Beispiele für die Nutzung des GNU-Werkzeugkastens
Einige der nachfolgend gezeigten Kommandos sind interne (eingebaute) Kommandos moderner Shells. Implizit wird immer die Nutzung der Bash unterstellt.
Hilfe:
# Manual-Seite des Kommandos chown aufschlagen man chown # Manual-Seite des Systemrufs chown aufschlagen # (Abschnitt 2 des Manuals) man 2 chown # GNU-Info-Seite des Kommandos chown aufschlagen info chown # Bash-Online-Hilfe für Kommando cd ausgeben help cd # Online-Hilfe der GNU-Tools (hier: Kommando rm) # durch Option --help aufrufen rm --help
eigene Identität / angemeldete Benutzer:
# eigene Identität ermitteln id # Informationen über lokal angemeldete Benutzer ermitteln w finger # Informationen über entfernt an host angemeldete Benutzer ermitteln; # funktioniert nur bei Zugriff auf den entfernten finger-Dämon finger @host
Ausgabe und Eingabe:
# drei Argumente unformatiert ausgeben
echo 1 2 3
# drei Argumente formatiert ausgeben
printf '%d: %d(%d)\n' 1 2 3
# Inhalt der Shell- und Umgebungs-Variablen PATH (Suchpfad) ausgeben
echo $PATH
# Ausgabe aller Dateinamen, die auf folgende Muster passen:
# - Namen unter /etc, die mit p oder s beginnen
# - Namen unter /etc, die mit Punkt und einem beliebigen Zeichen danach enden
# - Namen unter /, die nicht mit einem Buchstaben aus dem Intervall a bis f beginnen
# - Namen unter /usr/bin, die auf .sh enden
echo /etc/{[ps]*,*.?} /[^a-f]* /usr/bin/*.sh
# Datum ausgeben; Ausgabe des Kommandos date wird in das Argument
# von echo eingefügt
echo "Heute ist der $(date '+%d.%m.%Y')."
# Zahl auf Variable zahl einlesen
read -p 'Zahl: ' zahl
# Zahlen ins Feld array einlesen
read -p 'Feld: ' -a array
# Feld array geschlossen ausgeben
echo ${array[*]}
# Feld array zeilenweise ausgeben
for i in "${array[@]}"
do
echo "$i"
done
# erstes Element von Feld array ausgeben
echo ${array[0]}
echo $array
# drittes Element von Feld array ausgeben
echo ${array[2]}
Umgang mit Prozessen:
# alle root-Prozesse anzeigen
ps auxww | grep '^root\b'
# dito, nur in etwas anderem Format
ps -ef | grep '^root\b'
# Funktion psg definieren, die die Prozess-Liste nach einem
# egrep-Muster durchsucht
function psg()
{
ps auxww | egrep "$1" | fgrep -v "egrep $1" | fgrep -v "grep -E $1"
}
# Prozesse suchen, deren Einträge swap oder irq enthalten
psg 'swap|irq'
# Prozessbaum-Anzeige mit Prozess-ID und UID-Wechseln
pstree -up
# Prozess 324 mit Signal 9 (SIGKILL) hart beenden
kill -9 324
# Signal 15 (SIGTERM) an alle Prozesse senden, die das
# Kommando sleep ausführen
killall sleep
# Signal 2 (SIGINT) in der Shell abfangen
trap 'echo SIGINT' 2
# dito
trap 'echo SIGINT' SIGINT
# Laufzeit und Status des Systems (Anzahl Nutzer, Last) anzeigen
uptime
# Echtzeit-Anzeige der Prozess-Liste (in Auszügen) und des System-Status
top
Navigation im File-System:
pwd # absoluten Pfad des aktuellen Verzeichnisses anzeigen
# Das interne pwd der Bash kennt einen logischen und physischen Modus.
# Der physische Modus kann generell durch die set-Option -P oder spezifisch
# durch die Option -P von pwd aktiviert werden.
cd /tmp # Wechsel des aktuellen Verzeichnisses nach /tmp
cd # Wechsel ins Home-Verzeichnis des aktuellen Benutzers
cd ~max # Wechsel ins Home-Verzeichnis des Benutzers max
cd .. # Wechsel ins Eltern-Verzeichnis
cd - # Wechsel ins zuvor aktuelle Verzeichnis
pushd / # aktuelles Verzeichnis im Directory-Stack merken und Wechsel nach / (Wurzel)
pushd ~ # dito, aber Wechsel ins Home-Verzeichnis
dirs -l -v # Anzeige des Directory-Stacks
cd /etc # Wechsel nach /etc
popd # letztes Verzeichnis des Directory-Stacks löschen und zum Verzeichnis
# wechseln, das an der neuen Stack-Spitze steht
elementarer Umgang mit Dateien und Verzeichnissen:
ls # Inhalt des aktuellen Verzeichnisses im kurzen Format anzeigen
ls -l # Inhalt des aktuellen Verzeichnisses im langen Format anzeigen
ls -la # dito, aber zusätzlich die Punkt-Dateien anzeigen
ls -ld # den Eintrag für das aktuelle Verzeichnis anzeigen
ls -ld . # dito
ls -ld .. # den Eintrag für das Eltern-Verzeichnis anzeigen
alias l='ls -l' # Alias l als Abkürzung für ls -l definieren
l /tmp # entspricht ls -l /tmp
# Anzeige des Inhalts von /tmp im langen Format, umgekehrt nach der
# Modifikationszeit geordnet (zuletzt modifizierte Files stehen am Ende der
# Liste)
ls -ltr /tmp
# bei allen Files des aktuellen Verzeichnisses, deren Name auf .sh endet,
# wird für Gruppe und Welt das Ausführungsrecht gesetzt
chmod go+x *.sh
chown otto abc # File abc bekommt den Eigentümer otto
mkdir dir1 # Verzeichnis dir1 anlegen
rmdir dir1 # (leeres) Verzeichnis dir1 löschen
rm -rf dir1 # Verzeichnis dir1 rekursiv und ohne Rückfrage löschen
less /etc/passwd # /etc/passwd mit dem Pager less anzeigen
# die Ausgabe von find . (alle Verzeichniseinträge unterhalb des
# aktuellen Verzeichnisses) mit dem Pager less anzeigen
find . | less
# alle symbolischen Links unterhalb von /etc im langen Format ausgeben und
# in den Editor vim laden
find /etc -type l -ls | vim -
# die Namen aller Dateien unterhalb des aktuellen Verzeichnisses ermitteln
# und über xargs an das Kommando md5sum weitergeben (berechnet die
# MD5-Prüfsumme für alle Argumente); durch die korrespondierenden Optionen
# -print0 und -0 können auch Dateinamen, die Leerräume (Whitespace-Zeichen
# wie Leerzeichen und Newlines) enthalten und somit bei der Verarbeitung
# in der Shell Probleme verursachen, sauber behandelt werden;
# die Ausgabe von find (die Dateiliste) wird durch tee sowohl in der Datei
# /tmp/filelist abgespeichert als auch über eine Pipe an xargs weitergegeben;
# das Ergebnis von md5sum wird in der Datei /tmp/summen abgelegt
find . -type f -print0 | tee /tmp/filelist | xargs -0 md5sum > /tmp/summen
cp file kopie # kopiert Datei file nach kopie
# 1:1-Kopie von src nach dst (Dateien oder Dateibäume, Erhalt aller
# Attribute, kein automatisches Überschreiben existierender Dateien)
cp -ia src dst
mv file new # benennt file in new um
mv file /tmp # verschiebt file nach /tmp
mv file /tmp/new # verschiebt file nach /tmp/new
ln -s file symlink # symbolischen Link symlink als Verweis auf file erzeugen
rm file # löscht Datei oder Link file
# die oben gespeicherte Dateiliste wird per Eingabe-Umlenkung an xargs
# übergeben; dadurch wird rm -v für alle Dateien der Liste aufgerufen;
# somit werden alle Dateien der Liste gelöscht; durch die Option v wird
# die Löschung protokolliert
xargs -0 rm -v < /tmp/filelist
# Option dotglob aktivieren, so dass Dateinamens-Muster auch Dateinamen
# einschließen, die mit einem Punkt beginnen (außer . und ..)
shopt -s dotglob
# alle Dateien des aktuellen Verzeichnisses mit Ausnahme der Datei myfile
# löschen
echo * | fgrep -v myfile | xargs rm -f
# dito mit alternativer Realisierung unter Verwendung erweiterter Muster
# (Aktivierung über shopt -s extglob)
echo !(myfile) | xargs rm -f
# alle Dateien des aktuellen Verzeichnisses, deren Namen mit p beginnen
# und nicht auf 29 enden (wieder unter Verwendung erweiterter Muster)
echo p!(*29)
# Modifikationszeit von file auf die aktuelle Zeit setzen; leere Datei
# file anlegen, falls sie bisher nicht existiert
touch file
# Inhalt von /etc/hosts auf die Standardausgabe ausgeben
cat /etc/hosts
# /etc/passwd und /etc/hosts verketten und Zeilen von hinten nach vorn
# ausgeben
cat /etc/{passwd,hosts} | tac
# Name der Resultat-Datei /tmp/resultat.txt an die Shell-Variable
# result zuweisen
result=/tmp/resultat.txt
# evtl. existierende Resultat-Datei stillschweigend löschen
rm -f $result
for file in /etc/{hosts,printcap}
do
# die Variable file durchläuft die Liste der Dateinamen /etc/hosts
# und /etc/printcap
echo $file >> $result
# den aktuellen Dateinamen (Inhalt der Variable file) an die
# Resultat-Datei anhängen
cat $file >> $result
# den Inhalt der durch file benannten Datei an die Resultat-Datei
# anhängen
echo ======== >> $result
# Trennzeile an die Resultat-Datei anhängen
done
Montieren/Demontieren von Dateisystemen:
# Dateisystem nach /media/floppy montieren; Ort des Dateisystems muss in der # Datei /etc/fstab angegeben sein mount /media/floppy # Dateisystem unter /dev/fd0 (Diskette) nach /media/floppy montieren mount /dev/fd0 /media/floppy # Dateisystem unter /media/floppy demontieren umount /media/floppy
Mtools: Arbeit mit MSDOS-Dateisystemen ohne Montieren/Demontieren:
# alle Dateien des aktuellen Verzeichnisses, deren Namen auf .sh enden, ins
# aktuelle Verzeichnis (standardmäßig die Wurzel) von Laufwerk A: (Diskette) kopieren
mcopy *.sh a:
# alle Dateien und Unterverzeichnisse des Verzeichnisses DISKETTE unterhalb
# des Home-Verzeichnisses ins aktuelle Verzeichnis von Laufwerk A: kopieren
mcopy ~/DISKETTE/* a:
# Wenn man aktuell im Linux-Home-Verzeichnis steht, kann man kurz
# mcopy DISKETTE/* a:
# schreiben.
# alle Dateien des aktuellen Verzeichnisses der Diskette in Laufwerk A:
# ins aktuelle Verzeichnis kopieren
mcopy a:
mcopy a: . # die explizite Angabe des Ziel-Verzeichnisses . ist optional
mcopy -v a: # Option -v protokolliert die kopierten Dateien auf die
# Standard-Fehlerausgabe (vorzugsweise also auf den Bildschirm)
# eine analoge Kopie in ein benanntes Verzeichnis
mcopy a: ~/DISKETTE # kopiert ins Verzeichnis DISKETTE unterhalb des Home-Verzeichnisses
mcopy a: /tmp # kopiert ins Verzeichnis /tmp
# alle Dateien, deren Namen auf .sh enden, im aktuellen Verzeichnis von
# Laufwerk A: (Diskette) löschen
mdel a:\*.sh
# Inhalt des aktuellen Verzeichnisses von A: anzeigen
mdir
# aktuelles MTOOLS-Verzeichnis nach A:/DATEN wechseln
mcd a:/DATEN
# aktuelles MTOOLS-Verzeichnis anzeigen
mcd
# Diskette in Laufwerk A: logisch formatieren (leeres Dateisystem erzeugen);
# dies gestattet ein sehr schnelles Löschen des Disketteninhalts, da keine
# physische Formatierung der Spuren erfolgt
mformat a:
Textanalyse/-manipulation:
# Datei /etc/passwd mit dem interaktiven Editor Vim öffnen vim /etc/passwd # mit dem nicht-interaktiven Stream-Editor sed Kommentare und Leerzeilen # aus der Datei /etc/services löschen und Ergebnis auf die Standard-Ausgabe # ausgeben sed -e 's/#.*//' -e '/^$/d' /etc/services # die Datei /etc/passwd nach /tmp kopieren und dort mit dem Zeilen-Editor ed # bearbeiten; diesem wird mittels printf über die Standard-Eingabe die abzuarbeitende # Kommandofolge übergeben; er soll in den Zeilen 60 bis 100 jede am Zeilenende # vorkommende Zeichenfolge bash durch zsh ersetzen und das Ergebnis in das # Ausgangs-File zurückspeichern cp /etc/passwd /tmp && printf '60,100 s/bash$/zsh\nwq\n' | ed /tmp/passwd &> /dev/null
# sucht die Zeile(n) in /etc/passwd, die mit otto: beginnen grep '^otto:' /etc/passwd # sucht die Zeile(n) in /etc/passwd, die mit otto: oder not: beginnen egrep '^(otto|not):' /etc/passwd # ermittelt die Namen aller Dateien unterhalb des Verzeichnisses # dir1, in denen die Zeichenkette xyz vorkommt grep -rl xyz dir1 # ermittelt die Namen aller Dateien unterhalb des Verzeichnisses # dir1, in denen die Zeichenkette xyz nicht vorkommt grep -rL xyz dir1 # ermittelt die Namen derjenigen lesbaren Dateien im Verzeichnis /etc, die # irgendwo einen Punkt enthalten find /etc -type f -maxdepth 1 | xargs fgrep -l . 2>/dev/null # sortiert den Inhalt von /etc/passwd nach der UID (Feld 3) numerisch # fallend und speichert das Ergebnis in /tmp/passwd sort -t: -k3,3 -rn /etc/passwd > /tmp/passwd # dito, aber das Ergebnis erscheint zusätzlich auf der Standard-Ausgabe, wo # aber nur die ersten 20 Zeilen angezeigt werden sort -t: -k3,3 -rn /etc/passwd | tee /tmp/passwd | head -20
# zeigt die Differenz zwischen den beiden Dateien file.bak und file im # Format "unified context" an diff -u file.bak file # ermittelt rekursiv die Differenz zwischen den beiden Verzeichnissen # dir.old und dir.new; die Ausgabe erfolgt wieder im Format "unified # context" diff -ru dir.old dir.new
# findet alle Dateien ab dem aktuellen Verzeichnis, die höchstwahrscheinlich # mehrfach identisch vorkommen; mit find wird die Liste aller Dateien # erstellt; durch die korrespondierenden Optionen -print0 von # find und -0 von xargs werden auch File-Namen mit Leer- # und Sonderzeichen korrekt behandelt; für alle ermittelten Dateien wird die # 32 Zeichen lange externe Repräsentation der MD5-Summe errechnet; die Liste # wird nach dieser Summe sortiert; mittels uniq -D werden alle # Einträge der Liste ausgegeben, die mehrfach vorkommen; durch die Option # -w 32 betrachtet uniq nur die ersten 32 Zeichen jeder Zeile, # also die MD5-Summe und nicht den dahinter folgenden Dateinamen find . -type f -print0 | xargs -0 md5sum | sort | uniq -D -w 32
# ermittelt die Anzahl der Zeichen (Bytes) und Wörter der Datei # /etc/services wc -cw /etc/services # ermittelt die Anzahl der Verzeichnisse ab dem aktuellen Verzeichnis find . -type d | wc -l
# Ausgabe der ersten 5 Zeilen von /etc/passwd
head -5 /etc/passwd
# Ausgabe der letzten 10 Zeilen des Ring-Puffers des Linux-Kerns (enthält
# Log-Informationen)
dmesg | tail
# durch das Ampersand am Ende wird folgende Schleife im Hintergrund
# ausgeführt
for ((i=0; i < 10; i++))
do
# Zähl-Schleife, die 10 Mal durchlaufen wird;
# einen aktuellen Zeitstempel an die Datei /tmp/file anhängen und
# dann eine Sekunde schlafen
date >> /tmp/file ; sleep 1
done &
# dito mit alternativem Schleifenkopf (ab Bash 3)
for i in {1..10}
do
date >> /tmp/file ; sleep 1
done &
# kontinuierliche Anzeige des Datei-Endes von /tmp/file
# (man kann ein Wachstum der Datei sehen)
tail -f /tmp/file
# Feld 1 (Nutzerkennzeichen) der /etc/passwd ausgeben
cut -d: -f1 /etc/passwd
# Feld 1 (Nutzerkennzeichen) und Feld 3 (UID) der /etc/passwd durch
# getrennte cut-Kommandos ermitteln und über das Kommando paste unter
# Verwendung der Prozess-Substitution der Bash zeilenweise
# zusammensetzen
paste -d: <(cut -d: -f1 /etc/passwd) <(cut -d: -f3 /etc/passwd)
# Das konkrete Beispiel ließe sich einfacher so schreiben:
# cut -d: -f1,3 /etc/passwd
# alle Kleinbuchstaben durch die zugehörigen Großbuchstaben ersetzen echo abcde | tr a-z A-Z # dito echo abcde | tr [:lower:] [:upper:] # die Kleinbuchstaben a, b und c löschen echo abcdeabcde | tr -d a-c
# die Summe aller UIDs (Feld 3) der /etc/passwd bilden und ausgeben
awk -F: '
{ sum += $3 }
END { print sum }
' /etc/passwd
# der Variablen awk_file den Namen einer AWK-Datei zuweisen
awk_file=/tmp/passwd.awk
# ein AWK-Programm, das die einzelnen Felder der /etc/passwd
# besser lesbar anzeigt, in die AWK-Datei schreiben
echo '
# die Zeilen der /etc/passwd der Reihe nach ausgeben
BEGIN {
FS = ":"
}
{
print "Eintrag", FNR
print "name :", $1
print "password :", $2
print "uid :", $3
print "gid :", $4
print "real_name:", $5
print "home_dir :", $6
print "shell :", $7
print "======================"
}' > $awk_file
# AWK-Programm in der AWK-Datei ausführen; Resultat in die
# Datei /tmp/passwd.out umlenken
awk -f $awk_file /etc/passwd > /tmp/passwd.out
# Ausgabe-Datei mit dem Editor Vim öffnen;
# !$ entspricht dem letzten Wort der letzten Kommandozeile
vim !$
# passwd-Zeile für Nutzer otto suchen und per Pipe an das obige
# AWK-Programm übergeben
grep ^otto: /etc/passwd | awk -f $awk_file
Komprimieren und Archivieren:
# Datei file mittels gzip komprimieren, danach das Resultat file.gz
# wieder dekomprimieren und anschließend file mittels bzip2 nochmals
# komprimieren (Resultat ist file.bz2)
gzip file ; gunzip file.gz ; bzip2 file
# Kompressions-Kommando im Hintergrund ausführen
gzip file &
# Liste der Hintergrund-Jobs anzeigen
jobs
# aktuellen Job in den Vordergrund holen
fg
# Vordergrund-Prozess suspendieren
Ctrl-Z
# und in den Hintergrund schicken
bg
# Job 1 beenden
kill %1
# file.bz2 auf die Standard-Ausgabe dekomprimieren und Zeichen zählen
bunzip2 -c file.bz2 | wc -c
bzcat file.bz2 | wc -c
# das komplette Verzeichnis dir rekursiv ins ZIP-Archiv archiv.zip
# verpacken
zip -r archiv.zip dir
# Inhaltsverzeichnis des ZIP-Archivs archiv.zip ausgeben
unzip -v archiv.zip
# ZIP-Archiv archiv.zip entpacken
unzip archiv.zip
# der komplette Verzeichnisbaum, der bei dir beginnt, sowie die
# auf .sh endenden Datei-/Verzeichnisnamen des aktuellen Verzeichnisses
# werden in das gzip-komprimierte Tar-Archiv arch.tar.gz verpackt;
# durch die Option v (verbose) wird jede ins Archiv aufgenommene Datei
# protokolliert
tar cfvz arch.tar.gz dir *.sh
# dito, aber mit bzip2-Kompression statt gzip-Kompression
tar cfvj arch.tar.bz2 dir *.sh
# analoges unkomprimiertes Tar-Archiv erzeugen
tar cfv arch.tar dir *.sh
# Entpacken des bzip2-komprimierten Tar-Archivs arch.tar.bz2
# mit Protokollierung (Option v), Erhalt aller Zugriffsrechte
# (Option p), existierende Dateien nicht überschreiben (Option k)
tar xfvjkp arch.tar.bz2
# moderne tar-Implementierungen dekomprimieren komprimierte Archive
# automatisch, so dass man die Option z oder j weglassen kann:
tar xfvkp arch.tar.bz2
# dito für das gzip-komprimierte Tar-Archiv arch.tar.gz
tar xfvzkp arch.tar.gz
tar xfvkp arch.tar.gz
# Archiv-Inhalt im kurzen Format ausgeben
tar tf arch.tar
tar tf arch.tar.gz
tar tf arch.tar.bz2
# die Kompressions-Optionen z bzw. j kann man auch hier
# bei modernen tar-Implementierungen weglassen
# Archiv-Inhalt im langen Format (Option v) ausgeben
tar tfv arch.tar
tar tfv arch.tar.gz
tar tfv arch.tar.bz2
# alle HTML-Dateien (Endung .html) ab dem aktuellen
# Verzeichnis 1:1 ins Verzeichnis ~/backup (Verzeichnis backup
# unterhalb des Home-Verzeichnisses des aktuellen Benutzers) kopieren
tar cf - $(find . -name \*.html) | (cd ~/backup && tar xfvkp -)
# Das Kommando find ermittelt die gesuchte Dateinamens-Liste.
# Über die Kommando-Substitution wird diese Liste an das
# Kommando tar übergeben. Da als Archiv-Name das Minus-Zeichen
# verwendet wird, schreibt tar sein Archiv auf die Standard-Ausgabe.
# Über eine Pipe übergeben wir dieses Archiv an eine Sub-Shell, die
# zunächst ins Verzeichnis ~/backup wechselt und dann mittels
# tar das aus der Pipe gelesene Archiv entpackt. Das Minus-Zeichen
# als Archiv-Name symbolisiert hierbei die Standard-Eingabe.
# Das cd der Sub-Shell hat keine Rückwirkung auf das erste
# tar-Kommando in der Eltern-Shell.
# extrahiere diejenigen Einträge aus einem Archiv, deren Endung mit
# p beginnt (z.B. .py)
archiv=~/backup/archiv.tgz
tar xfvkp $archiv $(tar tf $archiv | grep '\.p[^.]*$')
# Mit tar tf wird der Inhalt des Archivs ausgegeben. Mittels grep
# suchen wir uns die Files/Einträge mit passendem Namen heraus. Die
# von grep erzeugte Liste wird via Kommando-Substitution als die
# Liste der zu extrahierenden Einträge an tar xfvkp übergeben.
Arbeit auf entfernten Rechnern:
# interaktives Secure-Shell-Login auf Rechner miller ssh miller # Kommando hostname via SSH auf dem entfernten Rechner miller # ausführen ssh miller hostname # Datei /etc/hosts ins Verzeichnis /tmp von Rechner miller kopieren scp /etc/hosts miller:/tmp
Drucken:
Allgemein stehen unter Linux typischerweise die Kommandos lp und lpr zum Ausdruck von Dateien zur Verfügung. Der konkrete Funktions-Umfang sowie die Optionen hängen davon ab, welches Druck-System (CUPS, LPRng) Verwendung findet. Die Details sind den Manuals zu entnehmem. Die folgenden einfachen Beispiele sollen die prinzipielle Handhabung zeigen:
# die Ausgabe von ls -l auf den Standard-Drucker ausgeben ls -l | lpr # die Ausgabe von ls -l auf den Drucker printer1 ausgeben ls -l | lpr -P printer1 # die Dateien file1 und file2 auf den Standard-Drucker ausgeben lpr file1 file2 # die Dateien file1 und file2 auf den Drucker printer1 ausgeben lpr -P printer1 file1 file2