Abschnitt 5 als pdf
Transcrição
Abschnitt 5 als pdf
UNIX System, Netz und Kommunikation 1 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php UNIX System, Netz und Kommunikation, version dated 2007-06-29 09:30:05 5. UNIX für Fortgeschrittene: Die (t)c-Shell Variablen, Aliases, und Scripts Die (t)c-Shell arbeitet als Vermittler zwischen dem Benützer und den eigentlichen UNIX-Befehlen bzw. den eigenen Kommand (jedes ausführbare Programm ist ein Kommando wie jedes andere Systemkommando!). Zunächst liefert sie das Bereitzei ("prompt"), numeriert die Eingaben und stellt eine Kommando-Historie zur Verfügung (siehe Der History-Mechanismus der C-Shell ). Darüberhinaus hat die Shell einen außerordentlich leistungsfähigen Ersetzungsmechanismus ("alias") sowie eine Makro-Sprache, die einer der Programmiersprache C ähnliche Syntax besitzt und vielfältige, komplexe Kommandoprozed ermöglicht. Hier sollen nur die wichtigsten Eigenschaften mit einigen Beispielen kurz diskutiert werden; Details findet man mit "man csh" und "man tcsh". 5.1 Alias Mechanismus 5.2 Variable 5.3 Kommandos der (t)c-Shell 5.4 Initialisierungsfiles 5.5 Kommandoprozeduren der C-Shell Druckversion: Abschnitt 5 als pdf-File (77 Kb) 5.1 Alias-Mechanismus Eine Namensersetzung von komplexen Kommandos ist mit folgender Syntax möglich: alias mycom 'command' Insbesondere wenn command aus mehreren Teilstrings besteht, empfiehlt sich die Zusammenfassung unter '-Zeichen. Kommt in einem Kommando "mycom" als Kommandoname vor, so wird von der C-Shell "command" eingesetzt und die Interpretation beginnt von vorne. Damit sind geschachtelte Ersetzungen möglich. Das Alias gilt nur für Kommandonamen! Beispiele: alias pur 'rm *.bak *.bck' alias lpb 'lp -dtp_b ' alias searchfor 'grep -n' Mit dem ersten Alias "pur" werden alle Files mit der Extension .bak oder .bck im aktuellen Directory gelöscht. Der zweite Alias erlaubt es, Files mit "lpb filename " auf den Drucker tp_b zu schicken. Mit dem dritten erreicht man, dass dem Kommando searchfor meier daten.* entspricht grep -n meier daten.* womit aus allen Files "daten.*" die Zeilen ausgeschrieben werden, die "meier" enthalten. Innerhalb von Alias-Definitionen kann auch der History Mechanismus verwendet werden . Allerdings muss dem Sonderzeichen ! ein \ vorangestellt werden, um eine unendliche Rekursion zu verhindern: alias for 'f77 -O2 \!* library.o' erreicht, dass (siehe Kap. 3.4) for main.f sub1.f 29.06.2007 10:14 UNIX System, Netz und Kommunikation 2 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php entspricht f77 -O2 main.f sub1.f library.o Wichtig ist die Verwendung von Anführungszeichen bei der alias-Definition. Damit lassen sich auch mehrere Kommandos in einziges Alias stecken: alias cd 'cd \!^;pwd;ls' bewirkt, dass nach einem Wechsel des Directory ("cd") immer gleich der volle Pfad-Name ("pwd") und Inhalt des neuen akt Directory ("ls") angegeben wird. Ein Alias, das einen vor sich selbst schützt, ist alias rm 'rm -i' Was macht das wohl? Eine Liste aller aktuell gesetzten alias-Definitionen erhält man mittels "alias" (ohne Parameter). Für die Ersetzung von Ausdrücken in beliebigen Shell-Kommandos gelten Regeln, die r ekursive Einsetzungen gezielt ermöglichen oder verhindern. Man muss Erfahrung damit sammeln (vgl. Strings ). \ Escapesymbol für das nachfolgende Zeichen. "text" Klammert eine Zeichenkette zu einer Einheit. Nur für Filenamen werden Ersetzungen unterdrückt. 'text' Klammert eine Zeichenkette zu einer Einheit, aber es werden keinerlei Substitutionen vorgenommen. `some commands` Klammert eine Zeichenkette, die als Kommando(folge) betrachtet und ausgeführt wird. Die Kommandoausgabe wird danach textuell eingesetzt. Beispiel: echo `ls` liefert als Ergebnis einen Textstring, der das Ergebnis von 'ls' ist, also eine Liste aller Files im aktuellen Directory. Falls mehrere Parameter des alias-Kommandos verwendet werden sollen, so wird der n-te Parameter mittels "\!:n" angespro Beispiel: alias mycp 'cp \!:1 special/folder/\!:2' bewirkt beim Aufruf mycp adam eva das vollständige Komando cp adam special/folder/eva Wie kann man nun aber entscheiden, ob ein Kommando ein alias ist? Das geht mit dem Befehl which command Es wird dann angegeben, welches UNIX-Kommand beim Befehl "command" tatsächlich ausgeführt wird. So ist bei mit der Befehl "ls" durch ein Alias ersetzt und eine Abfrage ergibt: 107 [asterix] %which ls ls: aliased to ls -FC wohingegen zum Beispiel "pwd" ein Originalbefehl ist und daher: 108 [asterix] %which pwd /sbin/pdw anzeigt, wo dieser Befehl steht. Wie kann man das Alias zeitweise "aufheben", also zum Beispiel den originalen " ls" Befehl ausführen? Das geht mit einem vorgagestellten "\" (Backslash). Der Befehl 29.06.2007 10:14 UNIX System, Netz und Kommunikation 3 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php \ls ist das originale ls und das erkennt man auch mittels which, nämlich: 109 [asterix] %which \ls /sbin/ls Der Befehl alias allein bewirkt, dass alle im Moment gültigen Aliases herausgeschrieben werden. Aufgabe 5.1.A.1 Aufgabe 5.1.A.2 Aufgabe 5.1.A.3 Und schließlich: Mit dem Kommando unalias kann man das gesetzte alias wieder aufheben. 5.2 Variablen Die C-Shell hat auch Variablen, die entweder beim Start als Parameter festgelegt werden, oder aber in der Shell definiert werden Das können numerische Variablen und Textvariablen oder Text-Listen sein. Es gibt lokale Variablen, die in der gerade aktiven C-Shell gültig sind und Environment Variablen, die man anderen, in de gestarteten, Prozessen vererben kann. Lokale Variablen Environment Variablen 5.2.1 Lokale Variablen Durch set name = "text" wird die Variable name, die dann als "$name" (d.h. stets mit vorangestellten $-Zeichen) in Kommandos und Kommandofile verwendet werden kann, deklariert und erhält als Wert die Zeichenkette "text". Mit set mywords = (this is some text) wird ein Variablenfeld "mywords" definiert, das als Elemente die vier Wörter "this", "is", "some" und "text enthält. Die Anzah Elemente der Liste ist als Variable $#mywords verfügbar, einzelne Elemente als $mywords[1], $mywords[2], usw. Die Zählung beginnt bei 1, also dem ersten String. Der Wert von $?mywords ist dann ungleich "0", falls diese Variable gesetzt wurde. Das Argument in den eckigen Klammern ist dabei auch als Bereichsangabe interpretierbar. So liefert etwa $mywords[2-4] das Ergebnis is some text. Man kann auch das Ergebnis der Ausführung eines Kommando in ein Variablenfeld einspeichern. Dazu wird das Kommand zwischen zwei "Backqoutes" gesetzt: set myfiles= ( `ls` ) liefert das Variablenfeld myfiles, welche nun die Liste der Files im aktuellen Folder enthält. Das kann für viele Skripts sehr nptzl sein, da man anschließend diese Liste schrittweise abarbeiten kann und jeden der Files entsprechend bearbeiten kann. Die Variablen kann man weiterverwenden, um mittels set newword = $mywords[3]"garbage" eine Variable $newword zu erhalten. Der Befehl echo $newword 29.06.2007 10:14 UNIX System, Netz und Kommunikation 4 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php liefert als Ergebnis "somegarbage". Mittels set newword = ( $mywords[3] garbage ) erhält man eine neue Liste. Numerische Werte werden mit @ k = 44 definiert, und mit @ kk = $k - 2 verändert. (Bitte nicht auf die Leerzeichen zweischen den einzelene Elementen vergessen, sonst gibt es eine Fehlermeldung werden später wieder auf diesen Gebrauch der Variablen zurückkommen, einstweilen interessieren uns nur Textvariablen. Mit der Eingabe von set (ohne Parameter) erhält man eine Liste aller momentan gesetzten C-Shell Variablen. Der Wert der Variablen gilt nur lokal , wird also nicht an in der C-Shell gestartet e Shells weitervererbt. Aufgabe 5.2.1.A.1 Aufgabe 5.2.1.A.2 Aufgabe 5.2.1.A.3 Aufgabe 5.2.1.A.4 5.2.2 Environment Variablen Während der Wert der Variablen nur lokal gilt, gibt es in der C-Shell auch vererbba re Variable, sogenannte Evironment- (oder Umgebungs) Variable. Sie werden mit dem Befehl setenv name text gesetzt und die Liste dieser (wichtigen) Variablen wird mit setenv (ohne Parameter) oder printenv abgefragt. Es gibt viele vordefinierte Systemvariablen, die meisten sind Environmentvariablen und werden meist mit Großbuchstaben definiert. Hier einige wichtige Beispiele: $DISPLAY gibt an, welcher Bildschirm für die Ausgabe verwendet werden soll (lokal ist der Wert auf ":0.0" gesetzt, interessant wird es erst, wenn man auf einem anderen Computer rechnet, aber den eigenen Bildschirm aus Ausgabe verwenden will, vgl. Telnet ); meist wird der Wert vom System automatisch richtig gesetzt. $HOME gibt das Heimatdirectory der aktuellen Benutzerin an (versuche einmal "echo $HOME") $HOST der Name des Computers, auf dem man gerade arbeitet $MANPATH die Reihenfolge, in der nach man-Pages gesucht werden soll $USER der Benutzername $TERM Setzt die aktuelle Terminalcharacteristik, z.B vt100. $PATH (auch $path) gibt an, welche Directories in welcher Reihenfolge nach einem Kommando durchsucht werden sollen. 29.06.2007 10:14 UNIX System, Netz und Kommunikation 5 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php $SHELL welcher Shelltype ist aktiv (z.B.: /bin/tcsh) $prompt Das Bereitzeichen; Standard für C-Shell ist % $history Wert legt fest, wieviele Kommandos (Vergangenheit) gespeichert werden. $noclobber Wenn diese Variable gesetzt ist ("set noclobber") Standard: ungesetzt), können existierende Files durch Ausgabeumleitung (> und <) nicht überschrieben werden Das Verständnis der Variablen $path ist so wichtig, dass sie näher erläutert werden soll. Sie teilt dem System mit, in welchen Reihenfolge Directories nach ausführbaren Kommandos durchsucht werden sollen. Möge sowohl das Directory "/bin" (das sich im vom System vorgegebenen Standard-Path $path befindet) als auch das Directory "$HOME/bin" (also Directory "bin" im Home des Benutzers) einen Befehl namens f77 enthalten, die aber Verschiedenes bewirken. Mit set path = ( $HOME/bin $path ) erreicht man, dass bei Verwendung des Befehls f77 künftig (in diesem Shellprozess) zuerst das Directory $HOME/bin nach Vorhandensein eines Programmes f77, und erst dann der übliche Pfad durchsucht wird. Hätte man statt dessen set path = ( $path $HOME/bin ) geschrieben, wäre der Suchvorgang in umgekehrter Reihenfolge abgelaufen. (Achtung: Wenn man im eigenen Kommando f7 wieder f77 verwendet, kommt es zu einer unendlichen Rekursion. Man muss daher dann den vollständigen Namen /usr/ verwenden.) Warnung: Der normale Benutzer hat in seiner $path-Variable meist auch ".", das auf das jeweils aktuelle Verzeichnis deute Zeichen. Dann wird eben auch das aktuelle Verzeichnis nich ausführbaren Befehlen durchsucht. Das ist natürlich sehr pra Allerdings stellt das für andere Benutzer eine Gefahr dar: Stell dir vor, du bist in einen Folder einer Kollegin und sie hat ausführbaren File namens "ls" angelegt, der zwar auch das übeliche "ls" ausführt, aber noch etwas mehr (zum Beispiel deine Daten kopiert). Um das zu vermeiden sollt zumindest der Benutzer root nie "." in seinem Suchpfad haben. Um dann dennoch ein Programm im aktuellen Folder ausführen zu können, muss man den "vollständigen" Namen, also etwa ./localprog angeben. Ähnlich funktioniert $MANPATH. Jeder Benutzer kann so eigene Manual-Seiten für den Hausgebrauch erstellen und entsprechenden Directory in den $MANPATH aufnehmen.Bei einem "man"-Kommando wird dann auch das eigene Directory nach Man-Pages durchsucht Hinweis zur Verwendung von Variablen in der bash: Zu Verwirrung führt oft der Unterschied der Environment Variablen Definition in der C-Shell csh oder in der Bash-Shell bash (die für die oder den SysAdmin unter Linux voreingestellte Shell). In der bash setzt man die Variablenwerte wie in folgendem Beispiel: DISPLAY=remotehost:0.0 und fragt die Environment-Variablen mit dem Kommando env ab. Wenn die Variable global vererbt werden soll (also auch in "Untershells" gelten soll, so muss sie mit export Variablenname "exportiert" werden, also zum Beispiel export DISPLAY Aufgabe 5.2.2.A.1 5.3 Kommandos der (t)c-Shell Neben dem Alias gibt es eine Reihe von weiteren nützlichen Eigenschaften und C-Shell Kommandos. Zwei der zusätzlichen vielen Eigenschaften der tc-Shell sind: Commandline Editing: Man kann vorhergegangene Kommandozeilen durch die Tasten Cursor-up und -down zurückholen und m Hilfe der Tasten Cursor-left und -right, sowie <backspace> und <del> editieren. 29.06.2007 10:14 UNIX System, Netz und Kommunikation 6 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php Filename-Completion: Man kann in Kommandos Filenamen unvollständig angeben und die Taste <tab> drücken. Die Shell versucht, automatisch den Filenamen (aufgrund der Directoryinformationen) fortzusetzen, solange das eindeutig möglich ist. Für Programmierer besonders interessant ist das Kommando time command Durch das vorangestellte "time" wird weitere Information über Ausführung des Kommandos "command" gegeben. Es wird der Reihe nach angegeben: die Zeit im Benützermodus(u); die Zeit im Systemmodus (s); die ganze Ausführungszeit mit Verweildauer; der während der Ausführung dem Prozess zugeteilte Prozentsatz an CPU-Zyklen (%); der mittlere RAM-Speicherverbrauch (k); Zahl der read/write -Operationen auf die Disk (io); Zahl der Seiten-Überschreitungen (page faults: pf). 5.4 Initialisierungsfiles Wenn sich der Benützer am System anmeldet (login), werden einige Kommandofiles abgearbeitet. Zuerst ist das der vom (oder von der) SysAdmin vorgegebene File /etc/cshrc. Danach werden 2 Kommandofiles in Homedirectory des Benutzers autom exekutiert, sofern sie existieren. Dies ist zuerst der File ".cshrc" und anschließend der File ".login". Letzterer wird nur in "login-Shells" abgearbeitet, wohingegen /etc/cshrc und ".cshrc"bei jeder Eröffnung einer neuen C-Shell wieder abgearbeitet werden. Wenn in $HOME ein File ".tcshrc" existiert, wird er im Fall der tc-Shell ebenfalls berücksichtigt. In C-Shell-Kommandofiles kann man Kommentarzeilen durch ein vorangestelltes # kenntlich machen. (Die einzige Ausnahmen ist die erste Zeile "#!/bin/csh" in einen ShellScript.) Nachfolgend findest du Beispiele für die Files .login und .cshrc: # # # # # # # # # This is the local version of the default standard .login provided to csh users. They are expected to edit it to meet their own needs. The commands in this file are executed when a csh user first logs in. This file is processed after .cshrc. $Revision: 1.8 $ # Set the interrupt character to ^c and do clean backspacing. if (-t 0) then stty intr '^C' echoe endif # Set the TERM environment variable eval `tset -s -Q` # Set the default X server. if ($?DISPLAY == 0) then if ($?REMOTEHOST) then setenv DISPLAY ${REMOTEHOST}:0 else setenv DISPLAY :0 endif endif trail_path $HOME/bin In diesem File wird dafür gesorgt, dass die Variablen $TERM und $DISPLAY richtig gesetzt werden, je nachdem, wie der Benutzer sich an der Maschine anmeldet (also direkt oder remote). Entsprechend werden auch weitere Environmentvariablen gesetzt, d später von verschiedenen Programmen abgefragt werden können und die Art des bevorzugten Editors angeben. # # # # # # # # # This is the local version of the default standard .cshrc provided to csh users. They are expected to edit it to meet their own needs. The commands in this file are executed each time a new csh shell is started. $Revision: 1.6 29.06.2007 10:14 UNIX System, Netz und Kommunikation 7 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php # list directories in columns alias ls 'ls -C' # Remember last 100 commands set history = 100 # For interactive shells, set the prompt to show the host name and event number. if ( $?prompt ) then if ( -o /bin/su ) then set prompt="`hostname -s` \!# " else # set prompt="`hostname -s` \!% " set prompt='\! ['`hostname -s`'] %' endif endif ###################################################################### # locally suggested entries (thph): # umask +++ +-+ --###################################################################### umask 027 ###################################################################### # The following shortcuts may be activated by removing the # leading # ###################################################################### #alias cd 'cd \!*;pwd;ls' #alias ls 'ls -FC' #set noclobber #set savehist = 100 #alias pur 'rm *.bak' ###################################################################### # useful shortcuts: ###################################################################### alias here 'set hereiam = `pwd`' alias back 'cd $hereiam' ###################################################################### In diesem Beispiel wird der History-Mechanismus festgelegt und einige nützliche Aliases eingeführt. Einige davon sind noch aktiviert, da durch Kommentarzeichen geschützt. Der Benutzer kann sie bei Bedarf aktivieren. Man beachte: Bei einer Modifikation der Initialisierungsfiles werden die Änderungen erst bei einem Neustart (bzw. beim Öffnen einer neuen Shell) aktiviert. Wenn man ein sofortiges Ausführen solcher Files (zum Beispiel für den File $HOME/.cshrc) in der aktuellen Shell erzwingen will, so kann man das mit dem Kommando source $HOME/.cshrc erreichen. (Ebenso gegebenenfalls source $HOME/.login). Allgemein bewirkt das Kommando source filename das Lesen und Ausführen des angegebenen Files in der aktuellen Shell. Im Unterschied dazu würde der Aufruf filename (unter der Annahme der File sei ein ausführbares Script) die entsprechenden Befehle in einer neuen Unter-Shell ausführen. Das kann vor allem dann von Bedeutung sein, wenn in dem Script Environment-Variablen gesetzt werden. (Vergleiche auch die Bemerkung zum Kommando rehash in Beispiele für (t)c-Shell Scripts .) Je nach vorhandener Software gibt es noch weitere nützliche Initialisierungsfiles, die meist am günstigsten im $HOME untergebracht werden. Da ihre Namen alle mit einem Punkt beginnen, werden sie beim üblichen "ls" nicht ausgeschrieben und stören so nicht die Übersichtlichkeit. Unter IRIX können das unter anderem folgende Files sein: .Xdefaults für X Window .auxchestrc für das Desktopmenü .cshrc siehe oben .desktop-machinename enthält Information über den Bildschirmaufbau (Desktop) .history enthält die letzten Kommandos auch über das Ende der aktuellen Sitzung hinweg für einen Neustart (falls $savehist gesetzt ist) .login siehe oben .mailrc für den Mailer .neditrc für den Screen-Editor (siehe "man nedit") .netrc Abkürzungen für ftp (Achtung: darf nur für den Benutzer lesbar sein, also "chmod 600 .netrc") .plan Info über den Benutzer (vgl. "man finger") 29.06.2007 10:14 UNIX System, Netz und Kommunikation 8 von 13 .rhosts http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php zusätzlich "äquivalente" Hosts (siehe TCP/IP und Internet ) Beim "Ausloggen" wird auch (falls vorhanden) ein File namens .logout ausgeführt. Wenn du also regelmäßige Aufgaben erledigenlassen willst (etwa Files aufräumen), kannst du das in diesem File tun, der bei Vorhandensein automatisch mittels "source" ausgeführt wird.. Welche Initilaisierungsfiles findest du unter Linux? Aufgabe 5.4.A.1 5.5 Kommandoprozeduren der C-Shell Die C-Shell kennt eine ganze Reihe von Anweisungen zur Ablaufsteuerung von Kommandoprozeduren. Eine Kommandoprozedur ist ein normaler File, der mit "chmod u+x filename " exekutierbar gemacht wird und Shell-Kommandos enthält. Die erste Zeile muss ein spezielles Format haben, welche di verwendeten Shell angibt: #!/bin/csh (oder tcsh oder sh) Wir können hier nur einige Aspekte der Shell-Scripts diskutieren. 5.5.1 Mehr über Variablen 5.5.2 Vordefinierte Variable: Argumentenliste 5.5.3 Ablaufsteuerung der (t)c-Shell 5.5.4 Beispiele für C-Shell Scripts 5.5.1 Mehr über Variablen Variable spielen eine wichtige Rolle in Scripts. Wir haben schon im Abschnitt 5.2 den Begriff der Textvariablen eingeführt, die Strings, Listen und (ganzahlige) Zahlenwerte enthalten kann. Vor allem die Verwendung von Zahlenwerten bedarf noch zusätzlicher Erklärung. Die Ausdrücke in set, @ und in anderen, noch zu besprechenden Anweisungen (wie etwa if, exit, while) dürfen wie in (der Sprache) C viele Operatoren verwendet werden, z.B. @ k ++ äquivalent zu @ k = $k + 1 @ k -- äquivalent zu @ k = $k - 1 +, -, *, / die Grundrechnungsarten &&, || logisches UND, ODER ! logische Negation == Prüfung auf textuelle Gleichheit !~ Prüfung auf textuelle Ungleichheit Folgendes Beispiel überprüft (recht umständlich), ob zwei Files die gleiche Zeilena nzahl haben; set ck = `wc -l file1` (wc liefert Zeilenzahl und Filename) @ len1 = $ck[1] set ck = `wc -l file2` @ len2 = $ck[1] if ( $len1 == $len2 ) echo 'file1 und file2 sind gleich lang' In folgenden Beispiel wird (auf gekünstelte Art) ein Teil einer Liste auf eine andere Liste kopiert: set set @ k set @ k obst = ( apfel birne kirsche traube ) obst_neu (erzeugt leere Liste) = 2 obst_neu = ( $obst_neu $obst[$k] ) -- 29.06.2007 10:14 UNIX System, Netz und Kommunikation 9 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php set obst_neu = ( $obst_neu $obst[$k] ) echo $obst_neu gibt: birne apfel Weitere (bei if-Abfragen) nützliche Operatoren betreffen die Existenz und Eigenscha ften von Files und Directories. -d name liefert wahr, wenn "name" ein Directory ist (Beachte: !(-d name) liefert "falsch" wenn "name" ein Directory ist) -e name liefert wahr, wenn der File (oder das Directory) "name" existiert -o name liefert wahr, wenn der File (oder das Directory) "name" dem aktuellen Benutzer gehört -x name liefert wahr, wenn "name" exekutierbar ist -z name liefert wahr, wenn "name" File der Länge 0 ist Oft will man nur Teile von File- oder Directory-Namen verwenden. Dazu gibt es eine Reihe von Modifikatoren, die Variablen (welche Namen enthalten) mit : nachgestellt werden. In den Beispielen nehmen wir an, dass $var den Wert "/home/jfk/mytest.f" hat. $var:h (head) liefert den Pfadanteil (den Directorynamen), Bsp: /home/jfk $var:t (tail) liefert den Filenamen ohne Pfadanteil, Bsp: mytest.f $var:r (root) liefert den Anteil ohne die Extension, Bsp: /home/jfk/mytest $var:e (extension) liefert nur die Extension Bsp: f Aufgabe 5.5.1.A.1 Aufgabe 5.5.1.A.2 5.5.2 Vordefinierte Variable: Argumentenliste Beim Aufruf eines Kommandos, also auch eines C-Shell Scripts, kann man Argumente (z.B. Optionen oder andere Parame angeben. Diese sind dann innerhalb dieses Prozesses weitere "vordefinierte" Shell-Variable mit Namen "$argv". Es gilt $argv[0] $argv[1] ist der Name des aufgerufenen Programms (Scripts), kann kurz auch mit $0 aufgerufen werden ist der 1. Parameter (also "this" wenn der Aufruf "check this one" lautete,), kurz auch $1 der n. Parameter, kurz auch $n $argv[n] Anzahl der Parameter $#argv 29.06.2007 10:14 UNIX System, Netz und Kommunikation 10 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php Hier ein kurzes Script (mit dem Namen tellme): #!/bin/csh # usage: tellme user echo Folgende Information gibt es über den Benutzer $1 \: finger $1 exit 0 Aufgabe 5.5.2.A.1 Aufgabe 5.5.2.A.2 5.5.3 Ablaufsteuerung der (t)c-Shell Folgende Anweisungen sind Beispiele für die Ablaufsteuerung einer Kommandoprozedur. Bitte halte die Syntax wie angegeben ein! if ( ausdruck) kommando wenn der Klammerausdruck wahr ist, dann.. if (ausdruck) then in dieser Form für eine Folge von Kommandos geeignet kommandofolge endif wenn der Klammerausdruck wahr ist, dann.. if ( ausdruck) then kommandofolge1 else kommandofolge2 endif wenn der Klammerausdruck wahr ist, dann.. if ( ausdruck) then kommandofolge1 else if (expr) then kommandofolge2 else kommandofolge 3 endif solange der Ausdruck wahr ist,... while (ausdruck) kommandofolge2 end foreach variable (liste ) die Variable nimmt hintereinander jedes Element aus der Liste(envariablen) an. In der Kommandofolge kann dann $variable entsprechend verwendet werden kommandofolge end 29.06.2007 10:14 UNIX System, Netz und Kommunikation 11 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php Abbruch der Schleife break Sprung ans Ende der Schleife continue Sprung nach "label" goto label Label, zu dem gesprungen werden kann label: "kommando" wird n-mal ausgeführt repeat n kommando Beispiel: switch ( text ) switch ( $1 ) case muster_1: case "yes": kommandofolge1 echo OK breaksw breaksw case muster_2: case "no": kommandofolge2 echo not OK breaksw breaksw default : ... default: kommandofolge echo Neither endsw endsw Aufgabe 5.5.3.A.1 Aufgabe 5.5.3.A.2 5.5.4 Beispiele für (t)c-Shell Scripts Statt einer schrittweisen Erklärung sollen hier nur einige Beispiele angegeben werden. Beispiel 1: Nehmen wir an, wir wollen eine Kommandoprozedur (Shell-Script) erstellen, welche alle Files mit der Erweiterung ftn (d.h. main.ftn, sub.ftn.,..) in Files mit der Erweiterung "f" umwandelt. Enthält das aktuelle Directory also einen File main.ftn, soll er in m umgewandelt werden. Das leistet folgende Prozedur, die "ch_ext" heißen soll, und die man aufruft als ch_ext ftn f um Files mit der Erweiterung ftn in UNIX-Fortran-Files mit der richtigen Erweiterung f umzuwandeln. #!/bin/csh -f # usage: ch_ext ext1 ext2 Das # bedeutet Kommentarzeile: es handelt sich um ein C-Shell Script 29.06.2007 10:14 UNIX System, Netz und Kommunikation 12 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php set mylist = ( `ls -d *.$1` ) setze die Variable mylist gleich der Liste der Files mit Extension $1 im aktuellen Directory; die Option "d" sorgt dafür, dass nicht bei Directories mit Namen *.$1 die Namen der darin enthaltenen Files gelistet werden. foreach i ($mylist) Schleife über alle diese Files. mv $i $i:r.$2 Benenne File um; File-Extension soll gleich dem 2. Argument sein. end beendet Schleife. exit 0 beendet Script mit Status OK (Wert 0) Beispiel 2: Nun wollen wir eine Kommandoprozedur schreiben, die einen Directory-Baum rekursiv durchsucht und den Inhalt listet (die Prozedur soll nur das Prinzip demonstrieren; das UNIX-Kommando "ls -R" erledigt diese Aufgabe bereits). Rekursive Aufrufe sind in UNIX sehr einfach dadurch realisierbar, dass man einen neuen Prozess generiert (jeder "Eltern-Prozess" kann "Kinder-Prozesse" durch Verzweigen ("fork") generieren und diese abschnüren - dies passiert beim Erzeugen Hintergrundprozessen mit "&" - oder auf ihre Beendigung warten. Das klingt kompliziert, ist aber sehr einfach, wie aus dem folgenden Beispiel ersichtlich. Die Routine möge "lstree" heißen und im Directory $HOME/bin liegen. Dann erfolgt der Aufruf durch lstree directory #!/bin/csh -f # usage: lstree [directory] # search and list rec. a # file tree; for each sub# folder a new process is # created: use with great # care! If no directory is # given, start search with . Allgemeine Information: für spätere Bearbeitung nützlich if ( $#argv != 0 ) then cd $1 endif Falls kein Argument angegeben wird, beginnt das Auflisten im aktuellen Directory, ansonsten im angegebenen directory = $1 set dir = (`pwd`) Definiere Variable "dir" mit dem Directory-Namen und liste alle Files in diesem Directory. echo "files in $dir" ls set cont = (`ls`) Definiere Variable "cont" als Liste aller FIles im Directory foreach i ($cont) if( -d $i ) then $HOME/bin/lstree $i endif end Schleife über die File-Liste des momentanen Directory: Falls ein Element ein Directory ist,...erzeuge einen neuen Prozess (..) und beginne von vorne exit 0 Ende mit Status "ok" 29.06.2007 10:14 UNIX System, Netz und Kommunikation 13 von 13 http://physik.kfunigraz.ac.at/~cbl/Unix/admin/mk_combined_file.php Beispiel 3: Das ist ein User-Script (also in $HOME/bin/my_f77), um den Fortran Compiler prinzipiell mit der Optimierungstufe -O2 aufzurufen, eine eigene Library dazuzuladen, und das ausführbare Element nicht a.out,sondern mi t dem jeweiligen Programmnamen und Extension .x zubenennen. Daneben sollen aber alle anderen Angaben vererbt werden. #!/bin/csh # # use e.g. as 'my_f77 test.f' # set mypars foreach i ($argv) if ( $i:e == 'f' ) then set mypars = "-o $i:r.x" endif end /usr/bin/f77 -O2 -mips2 $mypars $argv$HOME/mylib/mylib.a exit 0 Beachte bitte: Neu angelegte Scripts (zum Beispiel in $HOME/bin) werden nicht automatisch sofort gefunden. Beim Start der Shell legt sich das System eine Cache-Liste der über die Variable $path erreichbaren ausführbaren Files an. Neue Files können dort also nicht aufscheinen. Mit dem Befehl rehash wird diese interne Liste aktualisiert. (In neu gestarteten Shells stimmt die Liste automatisch.) Aufgabe 5.5.4.A.1 29.06.2007 10:14