![]() |
Vorlesung "UNIX"von Prof. Jürgen Plate |
:(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.
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:
read | 4 |
write | 2 |
execute | 1 |
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 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
-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 dat1 | gibt 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.
-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
-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!). |
-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
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 archiv | Archiv auspacken (x = extract) |
tar tvf archiv | Archiv ansehen |
Um z. B. alle Dateien des Verzeichnisses 'bin' (und dessen Unterverzeichnisse) in einem Archiv zu sichern, geben das Kommando:
tar cvf bin binaeres.tarWi 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).
Unter Unix/Linux wurde das gesamte Drucksystem gleich mit einem Spooling-System und netzwerkbasiert konzipiert:
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.jpgDarauf hin laufen folgenden Aktionen ab:
# /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:
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
laserjet3 is ready and printing Rank Owner Job Files Total Size active markus 3 bericht.ps 41984 bytes lst plate 17 brief 3213 bytesMit der Option -Plaserjet3 wird im Beispiel die Ausgabe von lpq auf den Laserdrucker eingeschränkt. Die Option -a zeigt alle Druckjobs an.
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
-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/0s1 | Daten über einen bestimmte Platte | |
df -f /usr | freie Blöcke des Dateisystems, das unter /usr eingehängt ist. |
-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 |
-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. |
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:
-name Dateiname
Suche nach bestimmten Dateien (bei Verwendung von Metazeichen
wie "*" oder "?" den Namen unbedingt in '..' einschließen).
-type T
Suche nach einem bestimmten Dateityp T:
f: normale Datei
d: Directory
b: Block Device
c: Character Device
p: Named Pipe
-perm onum
Suche nach Dateien mit den durch die Oktalzahl onum angegebenen Zugriffsrechten.
Steht ein "-"-Zeichen vor onum, werden nicht alle, sondern nur die spezifizierten
Rechte geprüft (z. B. Test SUID: -perm -4000).
-links N
Suche nach Dateien mit einer bestimmten Anzahl N von Links
-user Kennung
Suche nach Dateien eines bestimmten Users; es kann der
Login-Name oder die UID angegeben werden.
-group Kennung
Wie -user, jedoch für Gruppen
-size N
Suche nach Dateien mit N Blöcken
-mount
Suche nur auf dem aktuellen Datenträger (wichtig, falls weiter Platten über
NFS eingebunden sind).
-newer Dateiname
Suche nach Dateien, die jünger sind, als die angegebene.
-exec Kommando
Ausführen eines Kommandos. Wird innerhalb des Kommandos die leere geschweifte Klammer
{} aufgeführt, so wird anstelle der geschweiften Klammern der jeweils
gefunden absolute Pfad der Datei eingesetzt. Das per -exec aufgerufene Kommando wird
immer mit einem geschützten Strichpunt (\; oder ";" oder ';') abgeschlossen.
-ok Kommando
Wie -exec, jedoch mit Sicherheitsabfrage.
find -user markus -print
Suche alle Dateien von User markus.
find .-name dat1 -print
Suchen nach allen Vorkommen der Datei dat1 ab dem aktuellen Verzeichnis.
find .-print -name dat1
Gibt alle Dateinamen ab dem aktuellen Verzeichnis aus. Vorsicht Falle:
da die Bedingungen von links nach rechts ausgewertet werden und -print immer wahr
ist, hat der Teil -name dat1 keine Wirkung.
find . -name '*.bak' -exec rm {} \;
Suche alle .bak-Dateien ab dem aktuellen Verzeichnis und lösche sie.
find /usr -size +2000 -print
Gib alle Dateien der Benutzer mit mehr als 2000 Blöcken aus
(z. B. um die Platzverschwender zu mahnen).
find . -name '*.bak' -ok rm {} \;
Suche alle .bak-Dateien ab dem aktuellen Verzeichnis und lösche
sie nur, wenn die Nachfrage mit "y" beantwortet wurde.
find / -user markus -exec rm {} \;
Lösche alle Dateien von User markus, wo auch immer sie stehen.
find . -name 'buch.kap*' -exec lpr {} \;
Drucke alle Dateien eines Buch-Manuskripts. Verwendet man xargs,
sieht das Kommando so aus:
find . -name 'buch.kap*' -print | xargs lpr
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 -faus, 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.
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
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.
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.
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.
#includeint 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 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
bel | Signalton |
blink | Text auf Blinken schalten |
bold | Text heller darstellen (hohe intensität) |
clear | Bildschirm löschen,Cursor in die linke obere Ecke |
cr | Carriage Return |
cup | Cursor positionieren. Hinter cup folgen Zeilennummer und Spaltennummer der Cursorposition, z. B. cup 10 40 |
ed | Bildschirm von Cursorposition bis Ende löschen |
el | Von 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 rmsoOder 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}"
$ 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.
-l | Zähle Zeilen |
-w | Zähle Worte |
-c | Zähle Zeichen |
+n | Beginne bei Seite n der Dateien (Default: 1) |
-h Kopf | Definiere Seitenüberschrift (Default: Dateiname) |
-f | Verwende 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. |
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.
-l | Alle 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.
-cSpalten | Die 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) |
-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 |
-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 |
basename /home/plate/dings.c | dings.c |
basename /home/plate/dings | dings |
basename $0 | Programmname |
real | Insgesamt verbrauchte Zeit (elapsed time) |
user | Im User-Modus verbrauchte Zeit |
sys | Im System-Modus verbrauchte Zeit (Systemdienste) |
-Zahl | Anzahl der Zeilen, die ausgegeben werden sollen |
-f Datei | Liest aus der Datei statt aus /var/adm/wtmpx |
namen | Benutzer- oder Terminalnamen |
![]() |
![]() |