Vorlesung "UNIX"

von Prof. Jürgen Plate

3. Einige Kommandos

In diesem Kapitel wird eine Reihe wichtiger UNIX-Kommandos besprochen. Wie so oft, liegt hier der Nutzen in der Beschränkung. Weitere Kommandos kann sich nach Kenntnis des "Grundwortschatzes" jeder selbst aneignen. Es gibt für fast jeden Zweck schon passende UNIX-Kommandos. Denken Sie daran, bevor Sie anfangen selbst etwas zu programmieren. Es werden hier auch nicht alle Kommandos aus der Vorlesung beschrieben. Zunächst aber ein etwas "seltsames" Kommando.

:(Doppelpunkt)
Der Doppelpunkt ist das leere Kommando der Unix-Shell. Es liefert immer "true" zurück und hat keine Wirkung. Es werden jedoch alle Shell-Ersetzungen der nach dem Doppelpunkt angegebenen Kommandos durchgeführt. Es eignet sich daher auch zum Testen von Shell-Skripts.

ps [Optionen] (Report Process Status)

Liefert Statusinformationen über die aktiven Prozesse. Ohne Angabe von Optionen wird Information zu den Prozessen ausgegeben, die vom jeweiligen Terminal aus gestartet wurden. Zu jedem Prozeß wird eine Zeile ausgegeben, die Prozeßnummer, Terminalname, verbrauchte Rechenzeit und das Kommando angibt. Mehr erfahren Sie dann in Kapitel 4.

3.1 Kommandos zur Steuerung der Zugriffsberechtigung

Die Zugriffsberechtigungen wurde in Kapitel 1 besprochen; hier nun die Kommandos zum Setzen und Rücksetzen der Schutzbits. Die Bits UID und GID nehmen übrigens eine Sonderstellung ein - sobald eine Datei an einen anderen Benutzer übertragen wird, werden sie zur Sicherheit automatisch gelöscht. Bei den folgenden Kommandos erfolgen die Eingaben oktal (d. h. zur Basis 8). Das ist deshalb sinnvoll, weil es jeweils 3 Schutzbits für jede Benutzerklasse (Eigentümer, Gruppe, Andere) gibt, die sich zu einer Oktalstelle zusammenfassen lassen.

chmod Modus Dateiliste

Kommando zum Einstellen der Zugriffsrechte einer Datei, wobei zwei Modi existieren, symbolisch oder direkt. Symbolischer Modus: = Bereich Operand Berechtigung

Bereich u   Eigentümer (user)
g   Gruppe (group)
o   Übrige Benutzer (others)
keine Angabe = ugo
Operand +   Recht hinzufügen
-   Recht wegnehmen
=   Recht absolut setzen
Berechtigung r   Read
w   Write
x   eXecute
s   UID/GID (je nachdem, ob u+s oder g+s)
t   Sticky Bit (ohne Angabe von ugo)

Beispiele:

chmod +x              Ausführungsrecht für alle hinzufügen
chmod go-w dat2       Schreibrecht nur noch für User
chmod g+rwx dat3      Volle Rechte für Gruppe
chmod ugo-rwx dat4    Allen alle Rechte entziehen
chmod +t verz1        Sticky-Bit von verz1 setzen
chmod u+s admintool   SUID-Bit setzen

Direktmodus: Modus = Oktalzahl (3 - 4 Stellen)
Für user, group und others wird jeweils eine Oktalzahl angegeben, welche die jeweiligen Rechte wiedergibt. Dabei gilt folgende Wertigkeit:

read4
write2
execute1

Falls die Zugriffsrechte SUID (4), SGID (2) und STICKY (1) vergeben werden sollen, kommt vorne noch eine vierte Stelle hinzu. Die Anwendung dieses Modus zeigen die folgenden Beispiele:

  
                      User   Group  Others
chmod 754 dat1        rwx    r-x    r--
chmod 740 dat2        rwx    r--    ---
chmod 440 wichtig     r--    r--    ---
chmod 000 geheim      ---    ---    ---
chmod 4711 systool    rws    --x    --x

umask Modus

Dieses Kommando vereinbart eine Standardeinstellung der Dateirechte für alle Dateien, die nach Aufruf von umask erzeugt werden - man braucht also nicht jedesmal des chmod-Kommando aufrufen, wenn einen Datei kreiert wurde. Auf bestehende Dateien hat das Kommando keinen Einfluß. Bedauerlicherweise ist der dreistellige Zahlenwert (für User, Group und Others) genau das Komplement der Angabe von chmod, d. h. hier wird festgelegt, welches Bit nicht gesetzt werden soll (für den Anfänger eine Pest!). Stellen Sie sich einfach vor, sie ziehen den Wert des umask-Modus vom Maximalwert 777 ab. Sie erhalten dann die Zugriffsrechte. Beispiele:
umask 022          7 7 7       rwx r-x r-x
                 - 0 2 2
                 = 7 5 5
  
 umask 027         7 7 7       rwx r-x ---
                 - 0 2 7
                 = 7 5 0
  
 umask 177         7 7 7       rwx --- ---
                 - 0 7 7
                 = 6 0 0

chown Username Dateiliste

Übertragen einer Datei an einen anderen Benutzer. Der Benutzer wird vollständiger Eigentümer der Datei. Der alte Eigentümer verliert sie. Beispiel:

chown markus dat1

Datei dat1 wird an markus übertragen

chgrp Gruppe Dateiliste

Ändern der Gruppenzugehörigkeit einer Datei. Es kann entweder die Gruppennummer oder der Gruppenname angegeben werden.

3.2 Dateidienste

cat[-usvte] datei [datei]

(concatenate) Lesen der angegebenen Dateien und Kopieren auf die Standardausgabe. Zusammenkopieren mehrerer Dateien oder Ansehen der Dateien. Optionen:

-e $-Zeichen am Ende der Zeile ausgeben
-s (silent) Keine Fehlermeldung bei nicht existierenden Dateien
-t Tabulatoren als "^I" ausgeben
-v Nicht druckbare Zeichen als "^Z" ausgeben, wobei Z der ASCII-Wert des Zeichens + 64 ist (SOH = ^A, usw.)
-u ungepufferte Ausgabe

Beispiele:

cat dat1gibt dat1 auf dem Bildschirm aus
cat dat1 dat2 > dat3 kopiert dat1+dat2 auf dat3

Das Kommando tac arbeitet genauso wie cat, gibt die Zeilen jedoch in umgekehrter Reihenfolge aus.

cd [directory]

(change directory) Wechsel des Arbietsverzeichnisses. cd ohne Parameter wechselt ins Home-Directory.

cp dat1 [dat2 ... datx] directory

(copy) Kopiert eine oder mehrere Dateien in das angegebene Directory. Existiert die Datei schon im Zieldirectory, wird sie überschrieben. Existiert sie noch nicht, wird sie neu angelegt. Dateien, die mit einem Punkt beginnen, müssen explizit angegeben werden ("cp * ziel" kopiert nur diejenigen Dateien, die nicht mit einem Punkt beginnen; "cp .* ziel" kopiert alle Dateien).

ln [-fs] dat.alt dat.neu

(link) Trägt für eine bereits existierende Datei "dat.alt" ein (Hard-)Link unter dem Namen "dat.neu" ein. Die Datei ist physikalisch nur einmal vorhanden, aber unter zwei Namen ansprechbar. Beim Dateinamen wind der Link-Count auf 2 gesetzt. Beide Directoryeinträge müssen auf dem gleichen Datenträger (= Dateisystem) liegen Dateien mit mehreren Links werden erst beim Löschen des letzten Links physikalisch gelöscht. Optionen:

-f verhindert eine Nachfrage des Kommandos, falls die Datei schreibgeschützt ist.
-s erzeugt ein "Symbolisches Link". Hier wird eine Datei angelegt, die einen Verweis auf ihr Link enthält (Dateityp 'l'). Solche Links werden hauptsächlich für Verzeichnisse verwendet, sie wirken auch über die Grenzen von Dateisystemen hinweg.

Beispiele:
ln /usr/bin/ls /home/meier/bin/dir
ln -s /home/local /usr/local

mkdir Dirname

(make directory) Anlegen eines neuen Verzeichnisses, sofern der Schreibschutz des übergeordneten Verzeichnisses dies zuläßt. Voreinstellung für das Zugriffsrecht ist (umask) 755. Die Standardeinträge "." und ".." werden automatisch erzeugt. Die Zugriffsrechte lassen sich mit chmod ändern.

more

Wie cat eine weitere Möglichkeit zum Ansehen von Dateien. Jedoch stoppt hier die Ausgabe nach einer Bildschirmseite. Durch Tastendruck kann weitergeblättert oder abgebrochen werden. Außerdem kann auch im Text gesucht werden: Die Daten werden entwider über die Standardeingabe gelesen oder aus (einer) Datei(en), die als Parameter angegeben wird.

less

Wie more, jedoch erweiterter Befehlssatz und man kann auch bei Pipes zurückblättern. Siehe man-pages.

mv [-f] dat.alt dat.neu

(move) Umbenennen einer Datei unter Einbeziehung des gesamten Dateibaums. D. h. neben reiner Namensänderung auch ein Verschieben in ein anderes Verzeichnis möglich (Änderung der Verzeichniseinträge, kein Kopieren). Ist die Datei "dat.neu" bereits vorhanden, wird sie überschrieben. Liegt die Datei auf einen anderen Datenträger, wird sie physikalisch kopiert und an der alten Stelle gelöscht. Die Option -f unterdrückt eine Rückfrage bei Schreibschutz für dat.neu.

rm [-fri] Dateiliste

(remove) Löschen von Dateien und Verzeichnissen. Die angegebenen Dateien werden gelöscht. Optionen:
-i interaktiv: vor dem Löschen wird nachgefragt, ob die Datei gelöscht werden soll. Antwort "y" oder "n".
-f Löschen ohne Nachfrage bei schreibgeschützten Dateien
-r rekursives Löschen; es werden auch alle Dateien in daruterliegenden Verzeichnissen gelöscht (Diese Option ist gefährlich, wenn man nicht aufpasst!).

rmdir directory

Löschen eines leeren Verzeichnisses

stat [Optionen] Datei(en)

Status einer Datei oder eines Dateisystems anzeigen. Folgende Optionen sind möglich:

-L, --dereference Verknüpfungen folgen
-f, --file-system Dateisystemstatus anstelle eines Dateistatus anzeigen
-c --format=FORMAT für die Anzeige das angegebene Format (siehe unten) verwenden. Nach jedem Eintrag wird ein Newline ausgegeben.
--printf=FORMAT wie --format, aber es werden Sonderzeichen wie "\n" oder "\r" akzeptiert. Es wird KEIN Newline nach dem Eintrag ausgegeben (muss man im Format mittels "\n" selbst machen.
-t, --terse Ausgabe erfolgt einzeilig in kompakter Form (ideal für die Weiterverarbeitung)
--help Hilfe anzeigen
--version Versionsinformation anzeigen

Die gültigen Formatangaben für Dateien sind:

  %a   Zugriffsrechte im Oktalformat
  %A   Zugriffsrechte in menschenlesbarer Form
  %b   Anzahl der beanspruchten Blöcke (siehe %B)
  %B   die Größe in Bytes jedes mit -%b- gemeldeten Blocks
  %C   SELinux-Sicherheitskontext-Zeichenkette
  %d   Gerätenummer dezimal
  %D   Gerätenummer hexadezimal
  %f   "raw"-Modus  hexadezimal
  %F   Dateityp
  %g   Gruppen-ID des Eigners
  %G   Gruppenname des Eigners
  %i   Inode-Nummer
  %h   Anzahl der Hardlinks
  %n   Dateiname
  %N   "Quoted File Name" mit Dereferenzierung bei symbolischen Links
  %o   E/A-Blockgröße
  %s   Gesamtgröße in Bytes
  %t   Major-Gerätetyp hexadezimal
  %T   Minor-Gerätetyp hexadezimal
  %u   Nutzer-ID des Eigners
  %U   Nutzername des Eigners
  %x   Zeit des letzten Zugriffs
  %X   Zeit des letzten Zugriffs als Timestamp
  %y   Zeit der letzten Modifikation
  %Y   Zeit der letzten Modifikation als Timestamp
  %z   Zeit der letzten Änderung
  %Z   Zeit der letzten Änderung als Timestamp

Die gültigen Formatangaben für Dateisysteme sind:

  %a   Freie Blöcke, die Nicht-Superusern zur Verfügung stehen
  %b   Gesamt-Datenblöcke im Dateisystem
  %c   Gesamt-Inodes im Dateisystem
  %d   Freie Inodes im Dateisystem
  %f   Freie Blöcke im Dateisystem
  %C   SELinux-Sicherheitskontext-Zeichenkette
  %i   Dateisystem-ID in Hex
  %l   Maximale Länge von Dateinamen
  %n   Dateiname
  %s   Optimale Transfer-Blockgröße
  %S   grundlegende Blockgröße (für Blockzahlen)
  %t   Typ hexadezimal
  %T   Typ in lesbarer Form

Die verwendete Shell besitzt möglicherweise eine eigene Version von stat mit anderen Optionen. Gegebenenfalls müssen Sie die Dokumentation der Shell zu Rate ziehen.

Beispiel:

stat .bash_history
  File: ".bash_history"
  Size: 4097            Blocks: 16         IO Block: 4096   reguläre Datei
Device: 801h/2049d      Inode: 245776      Links: 1
Access: (0600/-rw-------)  Uid: ( 777/   plate)   Gid: ( 777/   plate)
Access: 2011-09-19 17:27:09.000000000 +0200
Modify: 2011-09-19 15:57:28.000000000 +0200
Change: 2011-09-19 15:57:28.000000000 +0200

tar Aktion [Optionen] Datei(en)

Um mehrere Dateien in einer einzigen zusammenzufassen verwendet man in der Regel das tar-Kommando (Tape ARchive), nur wird hier nicht auf das Band geschrieben, sondern alle Dateien und Verzeichnisse in eine einzige Datei geschrieben (Option "f"). Analog kann ein Archiv dann wieder "ausgepackt" werden. Das tar von GNU kann je nach Angabe der Optionen die zu archivierenden Dateien mit compress oder gzip auch komprimieren. Die typische Kennung für Archivdateien ist .tar. Wenn die Archivdatei komprimiert ist, lauten die Kennungen zumeist .tgz, .tar.gz oder .tar.bz2.

Die Steuerung von tar erfolgt in zwei Stufen: Zum einen muss eine Aktion angegeben werden, die tar ausführen soll, und zum anderen kann diese Aktion durch eine oder mehrere Optionen gesteuert werden. Auch wenn Aktionen und Optionen formal gleich aussehen, besteht ein wesentlicher Unterschied: Es muss genau eine Aktion (nicht mehr und nicht weniger) vor allen anderen Optionen angegeben werden. Es werden hier nur die wichtigsten Optionen aufgeführt (das "v" steht wieder mal für "verbose").

tar cvf datei(en) archiv Archiv erzeugen (c = create)
tar xvf archivArchiv auspacken (x = extract)
tar tvf archivArchiv ansehen

Um z. B. alle Dateien des Verzeichnisses 'bin' (und dessen Unterverzeichnisse) in einem Archiv zu sichern, geben das Kommando:

tar cvf bin binaeres.tar
Wi sie sehen, ist die Syntax von tar anders als bei vielen Unix-Kommandos: Es werden alle Kommandos und Optionen als ein Block ohne die üblichen Optionsstriche angegeben, etwa tar cvf name.tar pfad. Für das komprimieren kommt dann noch "z" (gzip) oder "j" (bzip2) hinzu.

Generell sollten Sie immer einen Pfad beim Erstellen von Archiven angeben. Das macht später das Entpacken einfacher (weil die Dateien automatisch in Unterverzeichnisse extrahiert werden und so ein Durcheinander im aktuellen Verzeichnis vermieden wird). tar entfernt beim Anlegen eines Archivs auch vorsichtshalber den "/", wenn er als allererstes Zeichen der Pfadangabe steht (sonst kann man das Archiv nicht auspacken, wenn man keine Root-Privilegien besitzt).

Sehen Sie sich Archive vor dem Entpacken immer zuerst mit tar tvf ... an, um herauszubekommen, ob im Archiv Pfadinformationen gespeichert sind und wohin die Dateien installiert werden. Sie können dann vor dem Extrahieren der Daten noch ein Verzeichnis anlegen und das Archiv in diesem Verzeichnis auspacken.

tar kann aber auch verwendet werden, um ganze Dateibäume auf der Platte zu verschieben oder zu kopieren:

(cd Quelldir ; tar cvf - ) | (cd Zieldir ; tar xvfp - )
Der Vorteil gegenüber einem normalen Kopier- oder Verschiebe-Kommando besteht darin, dass symbolische Links als solche kopiert werden (und nicht die Daten, auf die die Links verweisen).

3.3 Steuerung des Druckers

Die gesamte Unix-Druckphilosophie basiert auf PostScript-Druckern. Diese verwenden ein Vektorformat und funktionieren daher in beliebiger Auflösung. Dieselbe PostScript-Datei wird umso schärfer ausgedruckt, je besser (je höher auflösend) der Drucker ist. Deswegen spielt PostScript nicht nur unter Unix, sondern vor allem im Druckgewerbe eine dominierende Rolle. Fast alle Unix/Linux-Programme, die Druckfunktionen anbieten, können ausschließlich PostScript-Dateien erzeugen. Es stellt sich also die Frage, wie solche Dateien zum Drucker kommen.

Unter Unix/Linux wurde das gesamte Drucksystem gleich mit einem Spooling-System und netzwerkbasiert konzipiert:

Unter Linux war lange Zeit das BSD-LPD-System üblich (LPD: line printer daemon). Das Drucksystem LPRng (LPR next generation) ist dem BSD-LPD sehr ähnlich, aber deutlich sicherer und mit einigen Zusatzfunktionen ausgestattet. CUPS (Common Unix Printer System) ist das zurzeit modernste System und hat sich in den letzten Jahren als neuer De-facto-Standard durchgesetzt. CUPS kann sehr komfortabel über den Webbrowser bedient werden.

Auch wenn sich die drei erwähnten Spooling-Systeme hinter den Kulissen sehr stark voneinander unterscheiden, ist die Oberfläche einheitlich. Das Kommando zum Drucken einer Datei lautet daher bei allen lpr.

Damit das Drucken einer PostScript-Datei auch bei Nicht-PostScript-Druckern funktioniert, ist eine Umwandlung der PostScript-Daten in das jeweilige Druckerformat erforderlich. Dazu kommen Filterprogramme (u. a. GhostScript) zum Einsatz. Sie wandeln die PostScript-Daten seitenweise in Bitmaps um. Für viele Dateitypen versucht das Spooling-System, den Typ der zu druckenden Datei zu erkennen. Gelingt das, und handelt es sich nicht schon um eine PostScript-Datei, wird die Datei mit Hilfe der Filter in das PostScript-Format umgewandelt.

Dazu ein Beispiel: Sie haben am Rechner einen Tintenstrahldrucker (kein PostScript) angeschlossen und der Drucker wurde richtig konfiguriert und "HP750" genannt. Zum Drucken führen das folgende Kommando aus:

lpr -PHP750 schweinchen.jpg
Darauf hin laufen folgenden Aktionen ab: Das BSD-LPD-System (manchmal BSD-LPR oder auch nur LPD genannt) ist gleichsam der Urvater vieler Spooling-Systeme. Für die Verwaltung des Spoolers ist der Drucker-Dämon lpd verantwortlich, der während des Init-V-Prozesses gestartet wird. Gesteuert wird die gesamte Druckerei über die Datei /etc/printcap. Diese Datei enthält in einer leider ziemlich unübersichtlichen Syntax die Daten zur Konfiguration des/der Drucker(s). Eine Minimalkonfiguration eines PostScript-Druckers ohne Filter kann etwa so aussehen:
# /etc/printcap
# local
lp1:\
  :lp=/dev/lp0:\
  :sd=/usr/spool/lp0:\
  :mx#0:\
  :sh:
# remote
lp2:\
  :lp=:\
  :rm=remotehost:\
  :rp=remoteprinter:\
  :sd=/usr/spool/lp1:\
  :mx#0:\
  :sh:
Das CUPS-Projekt soll die Druckerverwaltung von Unix/Linux vollkommen neu organisieren. Zu den wesentlichsten Vorteilen von CUPS zählen: Zu CUPS gibt es eine umfassende Dokumentation, lokal unter http://localhost:631/ und im Internet unter http://www.cups.org/.

Beim BSD-LPD-System und bei LPRng erfolgt beinahe die gesamte Drucker-Konfiguration über die Datei /etc/printcap. Bei CUPS steht sie zwar aus Kompatibilitätsgründen noch immer zur Verfügung, enthält aber nur eine Liste aller bekannten Warteschlangen (ohne weitere Parameter). Die eigentliche CUPS-Konfiguration erfolgt durch die Dateien im Verzeichnis /etc/cups:

classes.conf:  Definition aller Klassen
cupsd.conf:    Zentrale CUPS-Konfigurationsdatei
lpoptions:     Veränderungen gegenüber der Default-Konfiguration
mime.convs:    Zu verwendende Filter für verschiedene Dateitypen
mime.types:    Dateitypen für die PostScript-Konvertierung
ppds.dat:      PPD-Datenbank
printers.conf: Definition aller Drucker
ppd/name.ppd:  Konfiguration für die Warteschlange name

lpr Dateiliste

Ohne weitere Optionen wird die Datei wieder zum Standarddrucker geschickt, z. B. : lpr text
. Die Ausgabe anderer Programme kann in lpr gepiped werden (z. B. ls -l | lpr). Möchte man explizit angeben, auf welchem Drucker der Ausdruck erfolgen soll, verwendet man die Option -P. Direkt hinter dem "-P" folgt ohne Leerzeichen der Druckername, z. B.: lpr -Plaserjet3 text. Mit -o options lassen sich diverse Zusatzparameter übergeben.

lpc

Dies Kommando gestattet eine feinere Kontrolle über den Druckvorgang. Nach dem Start dieses Kommandos befinden Sie sich in einer interaktiven Arbeitsumgebung, in der Sie Kommandos wie status oder help ausführen können. Mit topq können Sie einen Druckjob in der Warteliste nach oben befördern. Als Parameter müssen Sie den Druckernamen und die Jobnummer angeben. Ein Teil der Kommandos in lpc darf nur von root ausgeführt werden. exit, bye oder quit beenden lpc.

lpq

Druckerwarteschlange auflisten. Zum Beispiel: lpq -Plaserjet3. Die Ausgabe sieht dann etwa so aus:
laserjet3 is ready and printing
Rank     Owner     Job    Files                               Total Size
active   markus    3      bericht.ps                          41984 bytes
lst      plate     17     brief                               3213 bytes
Mit der Option -Plaserjet3 wird im Beispiel die Ausgabe von lpq auf den Laserdrucker eingeschränkt. Die Option -a zeigt alle Druckjobs an.

lprm

Druckaufträge wieder löschen. Es erwartet als Parameter die Kennummer des Druckauftrags, der gelöscht werden soll. Leider gibt lpr beim Aufruf nicht die Kennummer aus. Dazu muß man zunächst mit lpq nachschauen, welche Aufträge in der Warteschlange stehen. Auch bei lprm kann mittels -Pname die Warteschlange angegeben werden.

lpstat [Optionen] [Auftragsnummer]

(Line Printer Status) Gibt den Status der mit lp abgesetzten Druckaufträge aus. Fehlt die Auftragsnummer, wird der Status aller Druckaufträge des Benutzers ausgegeben. Bei den Optionen a, c, o, p, u und v kann anschließend an die Option eine Liste von Druckern oder Druckerklassen angehängt werden. Die Information erfolgt dann nur zu den angegebenen Geräten. Fehlt die Liste, wird die Statusinformation zu allen Druckern ausgegeben.

lpinfo [Optionen]

Das Kommando zeigt alle bekannten Druck-Devices (-v) bzw. alle bekannten Druckertreiber an (-m). Noch ausführlichere Informationen erhalten Sie mit der zusätzlichen Option -l.

lpadmin

Mit diesem Kommando können CUPS-Drucker und -Klassen eingerichtet und wieder gelöscht werden. Außerdem können die Zugriffsrechte auf den Drucker (speziell für den Netzwerkbetrieb) eingestellt werden. EInfacher geht es aber mit der Weboberfläche.

3.4 Informationsdienste

Einige Informationsdienste sind schon bekannt: who, ls, man, tty. Hier folgen einige weitere Kommandos, die den Benutzer mit Informationen versorgen:

date [mmddhhmm[yy]] [+format]

Beim Aufruf ohne Parameter werden Datum und Uhrzeit ausgegeben. Der Superuser kann mit diesem Kommando die Werte auch neu eingeben:

date mmddhhmmyy (Monat, Tag, Stunde, Minute, Jahr)
z. B.: date 10091245 (9.10., 12 Uhr 45)

Über den Parameter +format ("+"-Zeichen beachten!) kann die Ausgabe nach eigenen Wünschen gestaltet werden. Die Ausgabeformatierung erfolgt gemäß den Konventionen der Programmiersprache C (printf). Als Parameter werden verwendet:

  %%   a literal %
  %a   locale's abbreviated weekday name (Sun..Sat)
  %A   locale's full weekday name, variable length (Sunday..Saturday)
  %b   locale's abbreviated month name (Jan..Dec)
  %B   locale's full month name, variable length (January..December)
  %c   locale's date and time (Sat Nov 04 12:02:33 EST 1989)
  %d   day of month (01..31)
  %D   date (mm/dd/yy)
  %e   day of month, blank padded ( 1..31)
  %h   same as %b, locale's abbreviated month name (Jan..Dec)
  %H   hour :24 hour(00..23)
  %I   hour :12 hour(01..12)
  %j   day of year (001..366)
  %k   hour :24 hour(00..23)
  %l   hour :12 hour(01..12)
  %m   month (01..12)
  %M   minute (00..59)
  %n   a newline
  %p   locale's AM or PM
  %r   Time, 12-hour (hh:mm:ss [AP]M)
  %s   Seconds since 1970-01-01 00:00:00,  (a GNU extension)
       Note that this value is defined by the localtime system
       call.  It isn't changed by the '--date' option.
  %S   second (00..60)
  %t   a horizontal tab
  %T   Time, 24-hour (hh:mm:ss)
  %U   Week number of year with Sunday as first day of week (00..53)
  %V   Week number of year with Monday as first day of week (01..53)
       If the week containing January 1 has four or
       more days in the new year, then it is considered week 1;
       otherwise, it is week 53 of the previous year, and the next week
       is week 1. Similar to ISO 8601 (but not 100% compliant.)
  %w   day of week (0..6);  0 represents Sunday
  %W   week number of year with Monday as first day of week (00..53)
  %x   locale's date representation (mm/dd/yy)
  %X   locale's time representation (%H:%M:%S)
  %y   last two digits of year (00..99)
  %Y   year (1970...)
  %z   RFC-822 style numeric timezone (-0500) (a nonstandard extension)
       This value reflects the current time zone.
       Is not changed  by the --date option.
  %Z   Time offset from UTC (-07) This generally consists of Time Zone+DST
       Is not changed by the --date option.

Beispiel: Datum und Uhrzeit zweizeilig:

date '+Datum: %w, %d.%m.%y%nUhrzeit: %T'

Erstellungs- und Zugriffszeit/Datum von Dateien werden intern in Sekunden ab dem Offiziellen Geburtstag von UNIX, dem 1.1.1970, 0 Uhr UTC, gespeichert. Vor einiger Zeit habe ich mal das UNIX-Verfallsdatum ausgerechnet:
Auf 32-bit-Systemen wird time_t genau 2038-01-19 03:14:08 UTC ueberlaufen, d. h. dieses Datum hat die gleiche Darstellung wie 1970-01-01 00:00:00 UTC = (time_t) 0.

Die GNU-Variante von date kennt noch weitere Parameter, wobei hier der interessanteste --date= bzw. -d ist. Dem Parameter folgt ein String, der Datums-Arithmetik erlaubt. Voreinstellung beim date-Kommando ist -d now. Der String kann neben den Namen für die Wochentage auch Wortkombinationen wie "yesterday", 2tomorrow", "last-week", "next-week", "last-month", "next-month", "last-year" oder "next-year" enthalten (wobei der Bindestrich auch durch ein Leerzeichen ersetzt werden kann. Auch können Ausdrücke wie "last Monday" oder "2 weeks ago" gebildet werden. Auch Rechnen ist möglich, z. B. "10 days ago", "monday + 1 week" oder "1 year 2 month ago". Die Angaben reichen in die Vergangenheit oder Zukunft, beispielsweise:

date --date='tomorrow'
date --date='1 day'
date --date='1 day'
date --date='1 week'
date --date='1 month'
date --date='1 year'
 
date --date='yesterday'
date --date='1 day ago'
date --date='1 day ago'
date --date='1 week ago'
date --date='1 month ago'
date --date='1 year ago'
Statt des Wortes "ago" können auch '+' und '-' verwendet werden, etwa "tomorrow + 10 days", "'next tuesday + 1 day" oder " yesterday - 5 days". Weiterhin kann die Arithmetik relativ zu einem bestimmten Tag arbeiten, z. B. "2014-01-21 + 2 weeks 3 days". Es folgen weitere Beispiele:
$ date -d now
Sa 28. Jun 13:56:51 CEST 2014

$ date -d today
Sa 28. Jun 13:57:05 CEST 2014

$ date -d yesterday
Fr 27. Jun 13:57:19 CEST 2014

$ date -d tomorrow
So 29. Jun 13:57:40 CEST 2014

$ date -d sunday
So 29. Jun 00:00:00 CEST 2014

$ date -d last-sunday
So 22. Jun 00:00:00 CEST 2014

$ date -d "last sunday"
So 22. Jun 00:00:00 CEST 2014

$ date -d "last monday" +%Y-%m-%d
2014-06-23

$ date -d "monday - 14 days"
Mo 16. Jun 00:00:00 CEST 2014

$ date -d "12/2/2014"
Di 2. Dez 00:00:00 CET 2014

$ date -d "2 Feb 2014"
So 2. Feb 00:00:00 CET 2014

$ date -d "Feb 2 2014"
So 2. Feb 00:00:00 CET 2014

$ date -d "3 minutes ago"
Sa 28. Jun 14:00:27 CEST 2014

$ date -d "3 minute ago"
Sa 28. Jun 14:00:32 CEST 2014

$ date -d "1 year 2 month"
Fr 28. Aug 14:04:07 CEST 2015

$ date -d "1 year 2 month ago"
Di 28. Apr 14:04:33 CEST 2015

$ date -d "+2 months 17 days"
So 14. Sep 14:05:13 CEST 2014

$ date -d "+2months17days"
So 14. Sep 14:05:23 CEST 2014

$ date -d "tomorrow + 10 days"
Mi 9. Jul 14:05:52 CEST 2014

$ date -d "yesterday - 10 days + 5 hours"
Di 17. Jun 19:06:22 CEST 2014

touch [-em] [mmddhhmm[yy]] Dateiliste

Setzt Datum und Uhrzeit der Datei. Parameter -m setzt die "modification time" (Voreinstellung), -a die "access time". Wird keine Zeit angegeben, nimmt touch die aktuelle Zeit (mmddhhmmyy = Monat, Tag, Stunde, Minute, Jahr).

df [-tfk] [Dateisystem] (Disk Free)

Liefert die Anzahl freie Blöcke und freier i-nodes des angegebenen Datenträgers. Fehlt die Angabe des Datenträgers, wird der aktuelle Datenträger verwendet. Optionen:

-t Gesamtkapazität wird mit angegeben
-f Die Angabe über i-nodes entfällt
-k Angabe in KByte statt in Blöcken

df /dev/dsk/0s1Daten über einen bestimmte Platte
df -f /usrfreie Blöcke des Dateisystems, das unter /usr eingehängt ist.

du [-arsk] [Dateiname]

(Disk Usage) Liefert die Anzahl der belegten Blöcke von Dateien und Verzeichnissen (fehlt der Dateiname, wird das aktuelle Directory untersucht). Bei Verzeichnissen werden die Blöcke der darin enthaltenen Dateien aufsummiert. Bei Link-Dateien wird nur der i-node gezählt. Es werden auch die indirekten Blöcke gezählt. Optionen:

-a (Voreinstellung) Daten für jede Datei ausgeben
-r Dateien melden, für die kein Leserecht existiert
-s Nur die Summe der belegten Blöcke ausgeben
-k Angabe in KByte statt in Blöcken

du -a dat1 Größe der Datei dat1 ausgeben
du -s /bin Summe der belegten Blöcke im Verzeichnis /bin
du -s /usr/* ausprobieren

file [-c] [-f Dateiname] [-m Dateiname] [Dateinamen]

(Determine File Type) Überprüfung der angegebenen Dateien auf ihren Inhalt (C-Programm, ASCII-Datei, ausführbares Programm, etc.). Um den Inhalt der Datei zu analysieren, verwendet das file-Kommando die Datei /etc/magic, in der Angaben über die Dateieigenschaften stehen (welche Bytes zu analysieren sind). Optionen:

-f Dateiname Die zu durchsuchenden Dateinamen stehen nicht in der Kommandozeile, sondern in der angegebenen Datei.
-m Dateiname Die Unterscheidungskriterieen stehen nicht in /etc/magic, sondern in der angegebenen Datei.

strings [Optionen] [Dateinamen]

Das Kommando zeigt die Zeichenketten innerhalb einer Binärdatei (genauer: einer Nicht-Text-Datei) an. Das ist beispielsweise dann praktisch, wenn man einen Text (z. B. eine Fehlermeldung) in einer Programmdatei sucht. Ebenso findet man den ASCII-Anteil, also den reinen Text, in einer Word- oder PDF-Datei. Word-Dateien offenbaren hier oft auch mehr als vom Autor gewünscht (Meta-Info, Löschpuffer etc.).

find Pfadname(n) Bedingung(en) Aktion(en)

(Find Files) Durchsuchen der Platte nach bestimmten Dateien. Dieses Kommando ist sehr mächtig und besitzt zahlreichen Optionen, welche die Bedingungen für die Dateiauswahl (= Treffer) festlegen. Die angegebenen Pfade werden rekursiv durchsucht, d.h. auch Unterverzeichnisse und Unter-Unterverzeichnisse, usw. Aufrufschema:

find Pfadname(n) Bedingung(en) Aktion(en)

Bei den nachfolgenden Optionen (= Bedingungen) steht das N für eine Zahlenangabe (ganze Zahl). Das Vorzeichen dieser Zahl bestimmt die Bedingung:

Bedingungen

Aktionen

(auch hier nur die wichtigsten):

Beispiele:

xargs (ssiehe unten) in Verbindung mit find kann die Effizienz des Programms erhöhen, da nicht für jede Datei ein neuer Prozeß gestartet werden muß. Aber es kann auch Gefahren in sich bergen. Stellen Sie sich vor, ein Bösewicht führt folgende Kommandos aus:

mkdir "/tmp/boese "
mkdir "/tmp/boese /etc"
touch "/tmp/boese /etc/passwd"
Er legt also - was er auch durchaus darf - zwei Verzeichnisse und eine Datei im allgemeinen Temporär-Verzeichnis an. Die Gemeinheit liegt darin, daß das Verzeichnis "boese " mit einem Lehrzeichen endet. Bei xargs werden daraus möglicherweise auf der Kommandozeile zwei Verzeichnisse: /tmp/boese (ohne Leerzeichen am Schluß) und /etc/passwd. Führt nun der Superuser das Kommando
find /tmp -mtime +30 -print | xargs rm -f 
aus, um ältere Dateien zu löschen, schießt er sich die Passwortdatei weg. mit der Option -exec kann so etwas nicht passieren. Neuere Versionen der Programme verhindern diesen Fall.

3.5 Die Kommandos stty und tput

UNIX arbeitet terminalorientiert, d. h. der Benutzer sitzt an einen wie auch immer ausgestatteten Text-Terminal. Auch der PC-Bildschirm bei Linux ist ein solches Text-Terminal. Ebenso ist ein "xterm" auf dem Grafikbildschirm nichts anderes als ein emuliertes Text-Terminal. Sobald Kontakt zu einem Terminal hergestellt ist, greift die Terminalsteuerung auf zwei Dateien zurück: /etc/ttydefs oder /etc/gettydefs, in der hauptsächlich Steuerungswerte für die Datenübertragung gespeichert sind (z. B. Baudrate, Datenformat, Handshake, etc.). Das ist natürlich nur noch dann interessant, wenn das Terminal über eine serielle Schnittstelle oder per Modem angeschlossen ist. Bei den Pseudo-Terminals, die über das Netz mit dem UMIX-Rechner verbunden sind, spielen die Inhalte der Dateien nur noch eine untergeordnete Rolle (z. B. bei der Definition einiger Steuertasten wie Backspace).

Beim Programmieren keimt recht schnell der Wunsch auf, den Bildschirm anzusteuern, z. B. den Bildschirm zu löschen, den Cursor zu positionieren etc. Es existieren verschiedene Möglichkeiten, dies zu realisieren. In den frühen Jahre von UNIX gab es zahlreiche Anbiter von Bildschirmterminals und jedes dieser Terminals wurde mit anderen Kombinationen von ASCII-Zeichen angesteuert. Selbst unter MS-DOS wurde diese Tradition noch gepflegt - in Form des ANSI-Treibers.

Welche Möglichkeiten der Bildschirmansteuerung gibt es? Ein Terminal reagiert normalerweise auf Zeichenfolgen, die vom Programm aus geschickt werden. Normale Zeichen werden als Buchstaben dargestellt, bestimmte Sonder- zeichen oder Kombinationen bewirken aber bestimmte Funktionen. Da diese Kombinationen meist bestimmte Sonderzeichen enthalten (z.B. ESCAPE), um sie von Text zu unterscheiden, werden die Steuerfolgen auch Escape-Sequenzen genannt. Wenn man nun z. B. den Bildschirm löschen möchte, dann sucht man sich im Manual des Terminals die entsprechende Sequenz für "Bildschirm löschen" heraus und schickt sie vom Programm aus an das Terminal. Weil es auch nichtdruckbare Zeichen sein können, kann es sein, daß man ihre oktale oder sedezimale Verschlüsselung angeben muß. Dazu ein Beispiel:

Bei einem VT100-Terminal ist die Sequenz für "Bildschirm löschen" die Zeichenfolge

[;H[2J

Man schickt das beispielsweise aus einem C-Programm heraus mit printf("\033[;H\033[2J") ans Terminal. Dabei ist "\033" die oktale Schreibweise für das Escape-Zeichen.

Bei bildschirmorientierten Programmen wie z. B. einem Editor muß es möglich sein, den Cursor auf dem Bildschirm frei hin und her bewegen zu können. Das geht nicht ohne weiteres, weil die Terminals dafür spezielle Steuercodes, meist ESC gefolgt von einer bestimmten Zeichenkette, erwarten. Auch Fett- oder Kursivschrift lassen sich oft über solche Steuersequenzen ein- bzw. ausschalten. Andere Funktionen sind z. B. das Löschen des gesamten Bildschirms oder bis zum Ende der Zeile. Leider sind die Steuersequenzen für die einzelnen Funktionen nicht einheitlich. Auch haben die vielen verschieden Terminals unterschiedliche Möglichkeiten.

Deshalb gibt es eine Datenbank, in der, bei BSD-UNIX in der Datei etc/termcap im Textformat und bei System V in kompilierter Form in einer Reihe von Dateien unter dem Verzeichnis /usr/lib/terminfo, die Steuersequenzen zur Bildschirmansteuerung bei verschiedenen Terminaltypen gespeichert sind. Die Termcap und Terminfo-Datenbanken sind im wesentlichen äquivalent zueinander. Der Vorteil der Termcap-Variante ist die leichte Lesbarkeit und Änderbarkeit. Dafür kann auf die kompilierte Terminfo-Datenbank schneller zugegriffen werden.

Termcap

Je nachdem mit welchem Terminal man nun gerade arbeitet, sucht sich das UNIX-System die richtigen Steuersequenzen für dieses Terminal aus der Datenbank, wenn ein Anwendungsprogramm Funktionen wie "Bildschirm löschen" oder "Cursor nach oben" aufruft. Auf diese Art sind auch bildschirmorientierte Programme ohne Veränderung mit praktisch jedem Terminal einsatzfähig, vorausgesetzt natürlich, daß ein Termcap/Terminfo-Eintrag für das Terminal existiert. Im allgemeinen sollte das für alle gängigen Terminaltypen der Fall sein. Falls der Eintrag für ein verwendetes Terminal fehlt, können die Datenbanken auch um eigene Einträge ergänzt werden.

Der Termcap-Eintrag für das oft verwendete VT100-Terminal von DEC sieht z. B. folgendermaßen aus:

vtlO0|vt100-am|vt100am|dec vt100:\ 
     :do=^J:co#80:]i#24:c1=50\1[;H\E[2J:sf=5\ED:\ 
     :le=^H:bs:am:ce5\E[%i%d:%dH:nd=2\EEC:up=2\E[A:\          
     :ce=3\E[K:cd=50\E[J:so=2\E[7m:se=2\E[m:us=2\E[4m:ue=2\E[m:\ 
     :md=2\E[lm:mr=2\E[7m:mb=2\E[5m:me=2\E[m:is=\E[1;24r\E[24;IH:\  
     :rf=/usr/share/lib/tabset/vt100:\ 
     :rs=\E>\E[?31\E[?41\E[?51\E[?7h\E[?8h:ks=\E[?lh\E=:ke=\E[?11\E>:\ 
     :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\ 
     :ho=\E[H:kl=\EOP:k2=\EOO:k3=\EOR:k4=\EOS:pt:sr=5\EM:vt#3:xn:\ 
     :sc=\E7:rc=\E8:cs=\E[%i%d;%dr:

In der ersten Zeile stehen die Namen, unter denen dieser Termcap-Eintrag angesprochen werden kann. Danach folgen durch Doppelpunkte getrennt die zur Verfügung stehenden Funktionen und entsprechenden Steuersequenzen. Die Steuercodes, um den Cursor auf den Bildschirm bewegen, findet man beispielsweise in den ersten beiden Zeilen. do = ^J bedeutet, daß der Cursor mit CTRL-J eine Zeile nach unten, und up=2\E[A, daß er mit ESC-[A eine Zeile nach oben bewegt wird. Kombinationen mit der Control-Taste werden also in der Form ^x angegeben, wobei x ein beliebiger Buchstabe sein kann. \E ist die Umschreibung für das Escape-Zeichen. Die Zahl 2 hinter dem Gleichheitszeichen bei der Angabe der Steuersequenz für die Bewegung des Cursors nach oben hat eine besondere Bedeutung. Grundsätzlich kann bei jeder Funktion an dieser Stelle eine Wartezeit in Millisekunden angegeben werden, die nach dem Abschicken der Steuersequenz verstreichen muß, bis der UNIX-Rechner weitere Zeichen an das Terminal schicken darf. Das ist notwendig, weil die Terminals für die Verarbeitung eines Steuercodes eine bestimmte Zeit brauchen, in der alle ankommenden Zeichen im - meist sehr kleinen - internen Puffer zwischengespeichert werden müssen, bis die Verarbeitung der Steuersequenz beendet ist. Bei einer schnellen Leitung zwischen Terminal und Computer kann es so zum Verlust von Zeichen kommen, weil der interne Puffer schnell überlaufen würde, wenn das Terminal beispielsweise damit beschäftigt ist, den Bildschirminhalt zu löschen. Dieses Warten nach dem Abschicken einer Steuersequenz an das Terminal nennt man englisch Padding.

Andere Angaben in dem Termcap-Eintrag sind die Zeilen- und Spaltenzahl des Terminals in der zweiten Zeile mit den Kürzeln co#80 bzw. li#24. Sollte man tatsächlich einmal in die Verlegenheit kommen, einen Termcap-Eintrag verändern oder gar neu schreiben zu müssen, findet man weitere Informationen in den man-pages oder in weiterführender Literatur.

Auch in Programmen werden symbolische Bezeichnungen für die Terminalfunktionen verwendet, die in den entsprechenden Headerdateien der C-Bibliothek festgelegt sind. Zur Änderung der Werte in ttydefs/gettydefs dient das Kommando stty, zur Steuerung der Ausgabe kann das Kommando tput verwendet werden.

Terminfo

Mittlerweile gibt es einen Nachfolger für Termcap, die sogenannte Terminfo-Datenbank. Sie ist ziemlich ähnlich, nur daß die Datenbank hier nicht im ASCII-Format abgespeichert ist, sondern in einem Binärformat, weil das geht. Im Normalfall haben die meisten verwendeten Unix-Varianten noch beides, termcap und terminfo.

Curses

Mit termcap kann man flexible Programme schreiben, aber es könnte noch einfacher gehen. Deshalb gibt es eine weitere Bibliothek, die auf termcap aufbaut: "curses". Die curses-Bibliothek ermöglicht sämtliche Terminal-E/A-Funktionen. Zusätzliches Ziel von "curses" ist es, den Update des Bildschirms in optimaler Form durchzuführen, also möglichst schnell mit möglichst wenig Zeichen, die geschickt werden müssen.

Curses geht dabei folgendermaßen vor: es gibt einen virtuellen Bildschirm im Hauptspeicher. Ausgaben werden nun zuerst in diesem internen Speicherbereich aufgebaut. Und erst beim Aufruf der Funktion refresh() werden alle seit dem letzten refresh() angefallenen Aenderungen an den realen Bildschirm geschickt. Zusätzlich ist es möglich, den Bildschirm in Bereiche (Windows, hat aber nichts mit X Windows zu tun) einzuteilen und diese getrennt zu bearbeiten. Am Anfang gibt es für den gesamten zur Verfügung stehenden Bildschirm das vordefinierte Window stdscr.

Wie sieht ein curses-Programm aus? Hier ein Beispielprogramm, das in der Mitte des Bildschirms den String "Hello, world!" invers ausgibt.

#include 

int main(void)
  {
  char *text = "Hello, world!";

  initscr();                 /* Curses-Paket initialisieren */
  clear();			         /* Bildschirm löschen */
  move(LINES/2-1,(COLS-strlen(text))/2-1);
                             /* Cursor zur richtigen Position */
                             /* LINES und COLS sind vordefiniert */
  standout();                /* schalte auf Invers */
  printw("%s\n",text);       /* gib den Text aus */
  standend();                /* wieder auf normal */
  refresh();                 /* reale Ausgabe */
  endwin();	                 /* Ende Curses-Nutzung */
  return 0;
  }

Die Verwendung von Bibliotheken wie termcap oder curses hat natürlich Auswirkungen auf die Portabilität des Programms. Schon verschiedene Unix-Systeme haben verschiedene Curses-Bibliotheken.

stty [Optionen]

(set tty) Änderung der Standard-tty-Parameter. Die Einstellungen sind nur solange gültig, wie der Shellprozeß mit dem Terminal verbunden ist. Das Kommando kann alleine oder mit diversen Parametern verwendet werden. stty ohne Parameter gibt die wichtigsten Einstellungen aus; um alle Parameter zu sehen, verwendet man stty -a. Meist kann man die Wirkung der entsprechenden Option durch ein "-"-Zeichen davor umkehren (siehe Beispiel stty -echo). Weitere Info: man stty. Beispiele:

stty erase ^h
Setzen der Backspace-Funktion (in diesem Fall Control-H). Bei direkter Eingabe kann man die entsprechende Taste direkt betätigen (Steuertasten werden als zwei Zeichen "geechot", Backspace z. B. als "^h"). Bei Eingabe in Skripts mit dem vi kann man mit Ctrl-D erreichen, daß das folgende Zeichen unverändert übernommen wird. Manche Shells aktzeptieren auch die Kombination aus zwei Zeichen, "^" + Buchstabe.

stty eb
Einschalten der akustischen Fehleranzeige (error bell).

stty echo stty -echo
Echo auf dem Bildschirm ein- und ausschalten. Bei der folgenden Kommandosequenz wird die Eingabe des Paßworts auf dem Bildschirm nicht wiedergegeben.

echo "Paßwort eingeben: \c"
stty -echo
read PASS
stty echo

tput Parameter

(terminal put) Senden von Steuerbefehlen an das Terminal, wobei die "echte" Steuerinfo der terminfo-Datenbasis entnommen wird. Als Parameter dient der symbolische Name der entsprechenden Steuerfunktion. Je nach Terminaltyp sind sehr viele Steuerfunktionen möglich. Derzeit akzeptiert tput nur einen Parameter, mehrere Steuerbefehle müssen also nacheinander gegeben werden. Die in der Praxis am häufigsten gebrauchten Parameter sind:

belSignalton
blink Text auf Blinken schalten
bold Text heller darstellen (hohe intensität)
clear Bildschirm löschen,Cursor in die linke obere Ecke
crCarriage Return
cup Cursor positionieren. Hinter cup folgen Zeilennummer und Spaltennummer der Cursorposition, z. B. cup 10 40
edBildschirm von Cursorposition bis Ende löschen
elVon Cursorposition bis Zeilenende löschen
home Cursor in linke obere Ecke
ind Schirm nach oben rollen
rev Text auf Inversdarstellung schalten
ri Schirm nach unten rollen
rmso Wieder auf normale Zeichendarstellung schalten
setaf Schriftfarbe setzen; Parameter ist Farbnummer
sgr0 Attribute zurücksetzen

Beispiel:

 
    tput bel
    tput bold 
    echo "\nAchtung! Alle Daten werden gelöscht!\n"
    tput rmso
Oder auch Farbenspiele:
fg_rot=`tput setaf 1`
fg_gruen=`tput setaf 2`
fg_gelb=`tput setaf 3`
fg_blau=`tput setaf 4`
fg_magenta=`tput setaf 5`
fg_cyan=`tput setaf 6`
fg_weiss=`tput setaf 7`
fett=`tput bold`
invers=`tput rev`
untersr=`tput smul`
attr_end=`tput sgr0`

echo ${fg_rot}rot${attr_end}"
echo ${fg_gruen}gruen${attr_end}"
echo ${fg_gelb}gelb${attr_end}"
echo ${fg_blau}blau${attr_end}"
echo ${fg_magenta}magenta${attr_end}"
echo ${fg_cyan}cyan${attr_end}"
echo ${fg_weiss}(fast)weiss${attr_end}"
echo ${fett}fett${attr_end}"
echo ${invers}reverse${attr_end}"

3.6 Weitere Kommandos

xargs Programm [Parameter]

Das xargs-Programm fällt etwas aus dem Rahmen der übrigen in diesem Kapitel behandelten Programme. xargs übergibt alle aus der Standardeingabe gelesenen Daten einem Programm als zusätzliche Argumente. Der Programmaufruf wird einfach als Parameter von xargs angegeben. Ein Beispiel soll die Funktionsweise klarmachen:

$ ls *.txt | xargs echo Textdateien:

Hier erzeugt ls eine Liste aller Dateien mit der Endung .txt im aktuellen Verzeichnis. Das Ergebnis wird über die Pipe an xargs weitergereicht. xargs ruft echo mit den Dateinamen von ls als zusätzliche Parameter auf. Der Output ist dann:

Textdateien: kap1.txt kap2.txt kap3.txt h.txt

Durch Optionen ist es möglich, die Art der Umwandlung der Eingabe in Argumente durch xargs zu beeinflussen. Mit der Option -n <Nummer> wird eingestellt, mit wievielen Parametern das angegebene Programm aufgerufen werden soll. Fehlt der Parameter, nimmt xargs die maximal mögliche Zahl von Parametern. Je nach Anzahl der Parameter ruft xargs das angegebene Programm einmal oder mehrmal auf. Dazu ein Beispiel. Vergleich einer Reihe von Dateien nacheinander mit einer vorgegebenen Datei:

ls *.dat | xargs -n1 cmp compare Muster

Die Vergleichsdatei "Muster" wird der Reihe nach mitels cmp mit allen Dateien verglichen, die auf ".dat" enden. Die Option -n1 veranlaßt xargs, je Aufruf immer nur einen Dateinamen als zusätzliches Argument bei cmp anzufügen.
Mit der Option - i <Zeichen> ist es möglich, an einer beliebigen Stelle im Programmaufruf, auch mehrmals, anzugeben, wo die eingelesenen Argumente einzusetzen sind. In diesem Modus liest xargs jeweils ein Argument aus der Standardeingabe, ersetzt im Programmaufruf jedes Vorkommen des hinter - i angegebenen Zeichens durch dieses Argument und startet das Programm. In dem folgenden Beispiel wird das benutzt, um alle Dateien mit der Endung ".txt" in ".bak" umzubenennen.

ls *.txt | cut -d. f1 | xargs -iP mv P.txt P.bak

Das Ganze funktioniert allerdings nur, wenn die Dateien nicht noch weitere Punkte im Dateinamen haben.

wc [-lwc] [Datei(en)]

Dieses Kommando zählt Zeilen, Worte oder Zeichen in einer Datei. Wird kein Dateiname angegeben, liest wc von der Standardeingabe. Optionen:

-l Zähle Zeilen
-wZähle Worte
-cZähle Zeichen

pr [+n] [-h Header] [-ftF] [-wü] [-oü] [-lü] [Datei(en)]

(print) Ausgeben und Formatieren von Dateien. Ist keine Datei angegeben, wird von der Standardeingabe gelesen. Optionen:

+nBeginne bei Seite n der Dateien (Default: 1)
-h Kopf Definiere Seitenüberschrift (Default: Dateiname)
-fVerwende beim Seitenwechsel das Formfeed-Zeichen anstelle von Leerzeichen
-t Kopf- und Fußzeilen unterdrücken
-F Zu lange Zeilen nicht abschneiden sondern umbrechen
-w#Zeilenbreite festlegen (Default: 72)
-o# ü führende Leerzeichen vor jede Zeile setzen
-l#Seitenlänge festlegen (Default: 66). Davon gehen ab 5 Zeilen für Header und 2 Zeilen für Seiten-Nummer am Ende der Seite.

sleep zeit

Legt einen Prozeß für zeit Sekunden schlafen. Erst nach Ablauf dieser Zeit wird er wieder als "bereit" in die Warteschlange eingereiht. Anwendung in der Regel in Kommandoprozeduren (Shellskripts).

tr Ersetzungsliste

tr ist ein typischer Filter (tr = translate). Es wird benutzt, um in einer Datei bestimmte Zeichen durch andere zu ersetzen. tr liest immer von der Standardeingabe und schreibt auf die Standardausgabe. Als Parameter gibt man bei tr an, welche Zeichen durch welche anderen zu ersetzen sind. Die einfachste Variante ist, ein bestimmtes Zeichen in ein anderes umgewandelt werden soll. Dazu gibt man zunächst das zu ersetzende Zeichen und danach - durch Leerzeichen getrennt - das neue Zeichen als Parameter an. Beispiel:

tr : . < foo Ersetzt ":" durch ".".
tr abc def < foo Ersetzt "a" durch "d", "b" durch "e" und "c" durch "f".
tr a-z A-Z < foo Ersetzt Kleinbuchstaben durch Großbuchstaben.

Leider unterscheiden sich die Versionen von tr auf System V und BSD-UNIX-Varianten etwas, was die Verarbeitung dieser Zeichenfolgen anbetrifft. Bei System V müssen die Bereichs- und Wiederholungsangaben in eckigen Klammern eingeschlossen sein. Bei BSD gibt es nur Bereichsangaben, allerdings ohne Klammern. Dafür wird das letzte Zeichen der zweiten Zeichenfolge bei der ESD-Variante automatisch so oft wiederholt, bis die zweite Zeichenfolge genauso lang ist wie die erste.

recode

Noch mächtiger als tr ist recode. Dieses Kommando kann mehrere Dateien in einem Rutsch umcodieren und ersetzt normalerweise die Originaldatei durch die umcodierten Daten. Wem das zu gefährlich ist, muss vorher eine Kopie anlegen. Quell- und Zielzeichensatz erwartet das Programm als ersten Parameter (Trennzeichen ist ".."): Beispielsweise codiert der Befehl recode Latin-1..UTF-8 Test.txt die angegebene Datei von ISO-8859-1 nach UTF-8. Lässt man den Dateinamen weg, arbeitet recode als Filter. Mit den Schlüsselwörtern "tex" und "html" kann man Umlaute und Sonderzeichen außerdem ins TeX-Format oder in HTML-Entities und zurück konvertieren. Die Optionen sind u. a.:

-lAlle bekannten Zeichensätze ausgeben
-d Nur Akzente und Umlaute umkodieren; z. B. sehr praktisch bei HTML-Dokumenten.
-f Umkodierung forcieren, auch wenn diese nicht umkehrbar ist.

Beispiele:

Es muss aber nicht immer tr oder recode sein. Mit den Kommandos expand und unexpand lassen sich Leerzeichen in Tabulatoren umwandeln und umgekehrt.

cut -cSpalten [dateien]
cut -fFelder [-dZeichen] [-s] [dateien]

Extrahieren bestimmter Spalten aus einer Datei. Werden keine Dateien angegeben, liest cut von der Standardeingabe. Die Ausgabe erfolgt auf die Standardausgabe. Optionen:

-cSpaltenDie angegebenen Spalten werden herausgenommen, dabei sind mehrere Zahlenangaben, getrennt durch Kommata möglich, ebenso Bereiche, z.B. 5-9.
-c-10,15,20,30- 1. bis 10. Spalte, Spalte 15, Spalte 20 und alles ab Spalte 30
-fFelder Angaben von Feldern durch die Feldnummern analog -c. Als Feldtrenner ist das Tabzeichen vorgegeben.
-dZeichen Vorgabe des Feldtrenners. Das Zeichen wird als Feldtrenner verwendet. z. B. -d:
-s Zeilen, in denen der Feldtrenner vorkommt, nicht ausgeben (Voreinstellung: Zeile ausgeben)

paste [-dZeichen] [-s] [dateien]

Die Dateien werden als Text-Spalten betrachtet und, getrennt durch Tabulatoren, zu Zeilen vereint. Die Ausgabezeile Nummer x ergibt sich aus den aneinander gehängten Zeilen Nummer x der angegebenen Dateien. Ohne Dateiangabe oder wenn als Datei "-" angegeben wird, liest das Programm von der Standardeingabe. Optionen:

-dZeichen Vorgabe des Feldtrenners. Das Zeichen wird anstelle des Tabulators als Feldtrenner verwendet. z. B. -d' '
-s Bei der Dateiausgabe den Zeilenwechsel (Newline) durch den Feldtrenner ersetzen (S = serialize), z. B. aus foo.txt eine einzige Zeile machen: paste -d' ' -s foo.txt

nl [option] ... [dateien]

Zeilen von Dateien nummerieren. Jede der angegebenen Dateien wird mit Zeilennummern auf die Standardausgabe geschrieben. Unter anderem gibt es folgende Optionen (für alle Optionen: man nl)

-bSTYLE Stil der Nummerierung (s. u.)
-iZAHL Zeilennummer nach jeder Zeile um ZAHL erhöhen
-nFORMAT Format der Zeilennummer (s. u.)
-sSTRING STRING nach Zeilennummer hinzufügen
-wZAHL ZAHL Spalten für Zeilennummern benutzen

Stilangaben:
a Alle Zeilen nummerieren
t Nur nichtleere Zeilen nummerieren
n Keine Zeilen nummerieren
pREGEX Nur Zeilen nummerieren, die einen Treffer für den einfachen regulären Ausdruck REGEX enthalten

Für das Format sind folgende Optionen möglich:
ln Linksbündig, keine führenden Nullen
rn Rechtsbündig, keine führenden Nullen
rz Rechtsbündig, führende Nullen

cal [[monat] jahr]

Kalender zu einem Monat oder Jahr auf der Standardausgabe ausgeben.

calendar

Minimalversion eines Terminkalenders. Sucht im aktuellen Verzeichnis nach einer Textdatei namens "calendar" und gibt alle Zeilen aus, die irgendwo das aktuelle oder morgige Datum enthalten. Datumsangabe amerikanisch: Monat, Tag (z. B. Jan 24, 1/25, January 25). Je nach Installation auch Funktion von cal implementiert.

basename string [suffix]

Extrahieren des Dateinamens aus einer Pfadangabe, die als String übergeben wird. Wird ein Suffix angegeben, wird dieser am Ende des Dateinamens entfernt. Zum Beispiel:

basename /home/plate/dings.cdings.c
basename /home/plate/dingsdings
basename $0Programmname

dirname

Extrahieren des Pfadnamens aus einer Pfadangabe, die als String übergeben wird. Beispiel: dirname /home/plate/dings.c ergibt /home/plate und dirname dingsda ergibt .

logname

Gibt den Loginnamen auf der Standardausgabe aus. Im Gegensatz zum Kommando id, das immer den aktuellen Loginnamen ausgibt, wird hier der Name des Login geliefert, auch wenn mit su die Benutzeridentität gewechselt wurde.

time [kommando]

Berechnet die Zeit, die das angegebene Kommando zur Ausführung braucht. Es werden drei Zeiten ausgegeben:

real Insgesamt verbrauchte Zeit (elapsed time)
user Im User-Modus verbrauchte Zeit
sys Im System-Modus verbrauchte Zeit (Systemdienste)

bc [-lmath]

Einfacher Taschenrechner hoher Genauigkeit. Um mit Gleitpunktzahlen zu rechnen, muß der Parameter angegeben werden. Liest Formeln von der Standardeingabe und gibt das Ergebnis auf der Standardausgabe aus. End mit EOF = CTRL-D.

last [-Zahl] [-f datei] [namen]

Ausgabe der An- und Abmeldezeiten von Usern. Optionen:

-Zahl Anzahl der Zeilen, die ausgegeben werden sollen
-f Datei Liest aus der Datei statt aus /var/adm/wtmpx
namen Benutzer- oder Terminalnamen

script [-a] [datei]

script erlaubt es, eine Terminal-Sitzung (oder einen Teil davon) auf einer Datei aufzuzeichnen. Dabei wird alles, was in dieser Zeit auf der alphanumerischen Dialogstation (oder dem xterm-Fenster bei graphischen Oberflächen) erscheint, festgehalten - auch das Eingabeecho. Ist 'datei' im Aufruf angegeben, so wird die Sitzung in dieser Datei protokolliert. Fehlt die Angabe einer Ausgabedatei, so wird in die Datei typescript des aktuellen Katalogs geschrieben. Ctrl-C (Unterbrechung) beendet die Protokollierung. Die Option -a veranlaßt script, das Protokoll an die Datei datei (oder typescript) anzuhängen, anstatt eine neue Datei zu eröffnen. script ist immer dann hilfreich, wenn alle Aktivitäten einer längeren Sitzung dauerhaft protokolliert werden sollen: z. B. bei der Fehlersuche, bei einer längeren Netzwerk-Sitzung auf einem entfernten Rechner oder beim Ausprobieren eines chat-skripts für eine PPP-Verbindung. Man kann auch eine Kommandofolge interaktiv ausprobieren und dann die richtigen Kommandozeilen aus der Protokolldatei per Editor schnell in ein Shellskript umsetzen.

3.7 Exkurs über Parameterersetzung

Es wurden mehrere Möglichkeiten vorgestellt, Prameter für ein Kommando zu erzeugen. Am Kommando find sollen alle Möglichkeiten kritisch betrachtet werden. Es geht in allen Fällen darum, bestimmte Dateien (*.txt) in allen Verzeichnissen zu suchen und die gefundenen Dateien auszudrucken.
  1. lpr `find / -name '*.txt' -print` /home/texte
    Zuerst wird das find-Kommando ausgefürt ubnd dessen Output bildet die Parameterliste des lpr-Kommandos. Nachteil: Das geht nur solange gut, solange nicht die systemspezifische Länge der Kommandozeile überschritten wird.

  2. find / -name '*.txt' -exec lpr {} /home/texte \;
    Für jede gefundene Datei wird das lpr-Kommando aufgerufen. Vorteil: Klappt immer. Nachteil: lpr wird u. U. sehr oft aufgerufen.

  3. find / -name '*.txt' -print | xargs lpr
    Das Ergebnis von find wird unter Berücksichtigung der Systembegrenzungen an lpr übergeben. Effizienteste Lösung.

    Zum Inhaltsverzeichnis Zum nächsten Abschnitt
    Copyright © Hochschule München, FK 04, Prof. Jürgen Plate