Kommandozeilen verstehen und effizient nutzen

DaLUG-Vortrag
23. September 2005, TU Darmstadt

Axel Beckert
<abe@noone.org>
http://noone.org/abe/

ÜBERSICHT

Die Shell

Nützliche Tools für die Kommandozeile

Weitere Ressourcen

Was ist eine Shell?

»Shell« (engl. für Muschelschale, Gehäuse) ist der umgangssprachliche Begriff für einen Kommandozeileninterpreter (engl. command line interpreter — CLI), kann aber auch andere Progamme zum interaktiven Aufrufen von Befehlen meinen, z.B. den Windows Explorer, Konqueror, Nautilus, den Norton Commander oder den Midnight Commander.

Kommandozeilen-basierte Shells lesen eine (oder mehrere) Zeilen Text ein, interpretieren diese als Kommando und führen es aus. Im folgenden wird der Begriff Shell mit einem Kommandozeileninterpreter gleichgesetzt.

Auf Unix-Systemen hat jeder Benutzer seine sog. Login-Shell, die Shell, die automatisch aufgerufen wird, wenn sich der User einloggt — egal ob lokal an der Console oder von einem anderen Rechner per SSH. Die Login-Shell kann meist mit dem Befehl chsh geändert werden.

Unter MS-DOS befindet sich der Benutzer nach dem Booten direkt in einer Shell. Unter Windows bekommt man eine Shell meist über das Anwählen des Punktes im Startmenü Eingabeaufforderung.

Eine kleine Übersicht über gängige Shells

Unix

DOS / Windows

Typische Funktionen heutiger Shells

Warum braucht man Quoting und wie funktioniert es?

Bestimmte Tasten bzw. Zeichen haben am Terminal, auf der Kommandozeile oder für Anwendungen besondere Bedeutungen, werden manchmal aber auch ohne diese Sonderbedeutung gebraucht. Sie müssen dann "escaped" oder "gequotet" werden.

Die drei Ebenen des Quotens

  1. Terminal
  2. Shell
  3. Anwendung

Nehmen wir z.B. eine Datei, deren Name aus einem Minus (»-«), einem Pipe-Zeichen (»|«) und einem Ctrl-C (»^C«) besteht und die wir umbenennen wollen: mv -|^C foobar
 

  1. Parameter, die mit »-« beginnen, sieht mv als Optionen.
    Quoting mit vorangestelltem »./«: mv ./-|^C foobar
  2. Das Pipe-Zeichen »|« ist ein Sonderzeichen der Shell für die Umleitung von Ein- und Ausgabe.
    Quoting mit vorangestelltem Bckslash »/«: mv ./-\|^C foobar
  3. Ctrl-C wird vom Terminal abgefangen und sendet statt dem Zeichen selbst einen Interrupt an das laufende Programm, in diesem Fall die Shell.
    Quoting mit vorangestelltem Ctrl-V: mv ./-\|^V^C foobar

Terminal-Quoting

Shell-Quoting

Anwendungs-Quoting

Auswertungsreihenfolge am Beispiel der Bourne Shell

  1. Syntax des Kommandos analysieren (Parsen): Aufsplitten in Parameter, Quoting, Umleitung von Ein- und Ausgabe, Erkennen (aber nicht Auswerten) von Variablen
  2. Ersetzen von Variablen durch ihre Inhalte und Backquoting (»`...`«, neuere Shells auch »$(...)«) durch den entsprechenden Output
  3. Nochmals Aufsplitten an Leerzeichen, Zeilenumbrüchen, Tabs, etc.
  4. Globbing (Auswerten von Wildcards)
  5. Quoting (beim Parsen erkannte Single Quotes, Double Quotes und Backslashes) entfernen.

History Expansion und Completion

Übliche, aber oft ineffiziente Nutzung der History

History Expansion: Die richtige Zeile

  !!        Letzte Kommandozeile
  !3        Dritte Kommandozeile
  !-2       Vorletzte Kommandozeile
  !foobar   Letzte Kommandozeile, die mit »foobar« begann
  !#        Alles, was bisher in dieser Zeile getippt wurde.
  !?foobar  Letzte Kommandozeile, die »foobar« beinhaltete

History Expansion: Der richtige Parameter

  :*    Alle Parameter, z.B. !!:*
  :^    Erster Parameter, z.B. !less:^
  :$    Letzter Parameter, z.B. !3:$
  :2    Zweiter Parameter, z.B. !-2:2
  :2-4  Zweiter bis vierter Parameter, z.B. !#:-2

History Expansion: Modifizieren

  :h  entfernt letzte Pfadkomponente, z.B. /foo/bar → /foo
  :t  entfernt Pfad von einer Datei, z.B. /foo/bar → bar
  :r  entfernt letzte Dateiendung, z.B. foo.x.y → :r:r → foo
  :e  entfernt alles bis auf die Dateiendung, z.B. foo.bar → .bar
  :u  Großbuchstaben: tcsh erster, zsh alle
  :l  Kleinbuchstaben: tcsh erster, zsh alle
  :p  Ergebnis nur ausgeben, nicht ausführen
  :q  Ergebnis quoten, keine weiteren Ersetzungen
  :x  Ergebnis quoten, keine weiteren Ersetzungen, Parameter an Blanks
      aufsplitten

  :s/a/b/     »a« einmal durch »b« ersetzen
  :gs/a/b/    Alle »a« durch »b« ersetzen
  :as/xx/x/   Im ersten Wort solange wie möglich »xx« durch »x« ersetzen
              (nur tcsh und csh, Gefahr von Endlosschleifen!)
  :ags/xx/x/  Solange wie möglich »xx« durch »x« ersetzen (tcsh, csh)

History Expansion: Kurzformen

  !^, !$, !:2, !*  Erster, letzter, zweiter bzw. alle Parameter des
                   letzten Befehls. Entspricht !!:^, !!:$, !!:2, !!:*
  ^a^b             Ersetze einmal »a« durch »b« im letzten Befehl.
                   Entspricht !!:s/a/b

History Expansion: Beispiele

Ohne History Expansion

> tar cvf foobar-1.2.3woody4_i386.tar foobar > gzip -9v foobar-1.2.3woody4_i386.tar > mv foobar-1.2.3woody4_i386.tar.gz foobar-1.2.3woody4_i386.tgz > mkdir backup > mv foobar-1.2.3woody4_i386.tgz backup > mv backup Backup > cd Backup

Mit History Expansion

> tar cvf foobar-1.2.3woody4_i386.tar foobar > gzip -9v !:2 > mv !$.gz !$:r:r.tgz > mkdir backup > mv !mv:$ !$ > mv !$ !$:s/b/B > cd !$

Sonstige History Tricks

History ignoriert mit Leerzeichen beginnende Zeilen

Zeilen, die mit einem Leerzeichen beginnen, werden nicht in der History gespeichert. (Nur bash und zsh, optional.)

bash> HISTCONTROL=ignorespace zsh> setopt HIST_IGNORE_SPACE > echo foo foo > echo bar bar > !! echo foo foo

Kommandozeile in Editor editieren

Mit fc (für "Fix Command" — "Repariere Kommando") kann man bereits eingegebene Kommandozeilen editieren und erneut ausführen. (Nur bash, zsh und ksh.)

Häufiges Hin und Her zwischen Verzeichnissen

(Zurück in) Das letzte Verzeichnis

Der Directory Stack

Funktioniert unter bash, tcsh, zsh und z.T. auch in der cmd.exe.
 

Unbekanntere Wildcards und Ähnliches

> ls foo.a foo.b foo.b~ foo.c foo.c~ > ls foo.[ab] foo.a foo.b > ls *[^~] foo.a foo.b foo.c > unset nonomatch > touch foo.[fg] touch: No match. > set nonomatch > touch foo.[fg] > touch foo.{f,g} > ls foo.[fg] foo.a foo.b foo.b~ foo.c foo.c~ foo.f foo.g

Job Control

Welcher Job?

Job Control abgekürzt

Nützliche Shell Builtins

Globale Aliasse der zsh

> alias -g T='| tail' > fgrep bla /var/log/messages T

Nützliche Tools für die Kommandozeile (1)

find und xargs für Dateinamen mit Leerzeichen

Problem: Backquotes (`programm` oder $(programm)) versagen kläglich bei Leer- oder Sonderzeichen im Dateinamen.

Lösung: find mit NULL-terminierten Dateinamen und passendem xargs: find . -name '*.mp3' -print0 | xargs -0 mpg321

sed kann keine Dateien bearbeiten

Problem: sed -e 's/foo/bar/' datei > datei endet mit Datenverlust.

Lösung: Inline-Edit von Perl oder Super-Sed:

> perl -pe 's/foo/bar/' -i datei > ssed -e 's/foo/bar/' -i datei

Mitloggen von In- und Output von Shell-Kommandos

Problem: Man macht umfangreiche Installations- oder Upgrade-Arbeiten in der Shell und will das alles mitprotokollieren.

Lösung: Das Tool script (Paket "bsdutils" bei Debian) startet eine Subshell und protokolliert jeden In- und Output in eine Logdatei.

Nützliche Tools für die Kommandozeile (2)

Umbenennen vieler Dateien auf einmal

Problem: Da unter Unix die Shell die Wildcards auswertet, geht mv *.jpg *.jpeg im Gegensatz zu DOS nicht.

Lösung: Multiple Move (mmv) oder Perl-Skript Rename.

> mmv '*.jpg' '#1.jpeg' > mmv '*---*' '#1 - #2' Debian: > rename 's/jpg$/jpeg/' *.jpg > rename 's/_/ /g' *.mp3 SuSE: > rename jpg jpeg *.jpg

Sonstiges

  • screen
  • gpm
  • loco, colordiff, colormake, colorgcc
  • cut -c-80 (textutils), less -S, less -N, less +G, less +F, less +/xyz

Links

Danke

  • Den entsprechenden Entwicklern für bash, tcsh, zsh und screen.
  • Lou Montulli, Michael Grobe und Charles Rezac für Lynx
  • dem Debian-Projekt für Woody

Letzte Änderung an den Quellen: 2005-09-27 00:06:30
Letzte Generierung: 2005-10-28 00:51:49
Generiert von abe@bijou mit WML 2.0.8 (30-Oct-2001)