Kommandozeilen verstehen und effizient nutzen

New Thinking Store
2. März 2006

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.

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.tgz > mkdir backup > mv !mv:$ !$ > mv !$ !$:s/b/B > cd !$

Hilfreiche Tastenkürzel rund um die History

In der History interaktiv suchen (Think Emacs)

Worte aus der History einfügen

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 bar.[fg]
  touch: No match.
  > set nonomatch
  > touch bla.[fg]
  > touch fnord.{f,g}
  > ls
  bla.[fg]   fnord.f   fnord.g   foo.a   foo.b   foo.b~  foo.c   foo.c~

Job Control

Welcher Job?

Job Control abgekürzt

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

Dateien bearbeiten mit sed

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

Lösung: Option Inline-Edit (auch mit Perl o. ssed, falls sed zu alt):

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

Ausgabe eines Befehles gleichzeitig mitloggen und ansehen

Problem: Man will einerseits direkt die Ausgabe eines Befehls sehen, aber auch in eine Datei mitloggen.

Lösung: Output durch tee dateiname (Mnemonic: T-Kreuzung) pipen: z.B. fgrep 127.0.0.1 /var/log/access.log | tee localhost.log

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.1): screen

Aufruf

Nützliche Tools für die Kommandozeile (2.2): screen

Tastaturkommandos

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

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

Links

Danke

Letzte Änderung an den Quellen: 2006-03-04 09:21:51
Letzte Generierung: 2006-03-04 09:27:29
Generiert von abe@bijou mit WML 2.0.8 (30-Oct-2001)
$Id: shell-efficiency-newthinking.wml 56 2006-03-04 08:21:50Z abe $