19.04.2023

Linux Shell-Scripte

Shells unter Unix / Linux
Shellsoptionen
Bash Konfiguration
Shell Sonderzeichen
Script ausführen und testen
Umleitung und Pipes
Datei Descriptoren
Dateinamen-Expansion
Builtins erstellen
Variablen
Rechnen mit der Shell
Zeichenketten
Arrays (Feldvariablen)
Bearbeiten von Variablen oder Texten mit awk, sed, cut, und tr
Bedingungen definieren
echo Ausgabe formatiern
if Verzweigung
case Verzweigung
for Schleifen
while Schleifen
until Schleifen
test Kommando
Dialog
Ausgabe Operationen
Eingabe Operationen
Kommandozeilen Parameter und Optionen
Fehler in Scripten erkennen und reagieren
Beispiele
sonstiges

Links:
Howto Shell-Globbing

Seitenanfang

Shells unter Unix / Linux

csh C-Shell
tcsh TENEX C Shell, Nachfolger der C-Shell
sh Bourne-Shell (unter Linux gibt es nur eine Bourne-Shell kompatible Bash)
ash NetBSD Bourne-Shell, wesentlich kleiner als die bash
ksh Korn-Shell, ( Nachfolger der sh ) bei Debian im Paket pdksh
bash Bourne Again Shell (mit "shopt -s Option" kann man Optionen in der Shell einstellen)
zsh Z-Shell
sash stand-alone shell
... u.s.w.
Seitenanfang

Shellsoptionen

set -o {name} auf on setzen
set +o {name} auf off setzen
set -o verbose Verbose Modus aktiv
set +o verbose Verbose Modus deaktiv
set -v Verbose Modus aktiv
set +v Verbose Modus deaktiv
echo $SHELLOPTS aktuell gesetzte Optionen anzeigen

set Optionen der Bash ( abefhkmnptuvxBCHP )

Option Name Funktion
-a allexport neu definierte oder veränderte Variablen werden automatisch exportiert
-b notify bewirkt, dass Meldungen von Hintergrundjobs sofort ausgegeben werden (voreingestellt wartet die Bash bis zur Ausgabe des nächsten Prompts)
-B braceexpand Klammerexpandierungen erlauben (entspricht der Voreinstellung)
-C noclubber Setzen dieser Option verhindert, dass bestehende Dateien durch Ausgabeumleitungen (Redirections) zerstört werden
-e errexit In diesem Modus beendet sich die Shell immer dann automatisch, wenn ein Befehl einen Fehlercode erzeugte
-f noglob Deaktiviert die Komplettierungsfunktion für Dateinamen
-h hashall Deaktiviert das Speichern der Pfade bereits einmal ausgeführter externer Befehle; ein Abschalten bewirkt längere Ausführungszeiten bei Skripten
-H histexpand Erlaubt erweiterte Ersetzungen aus dem Historybuffer (voreingestellt: on)
-k keyword Zuweisungen werden in das Environment des Befehls übernommen
-m monitor Aktiviert die Job-Kontrollfunktionen (Voreinstellung: on bei interaktiven Shells)
-n noexec Verhindert die Ausführung von Befehlen; die Syntax wird aber überprüft und gegebenenfalls Fehlermeldungen erzeugt (deaktiviert bei interaktiven Shells)
-o Option setzt die im Argument übergebene Option, siehe das Beispiel oben
-p privileged Aktiviert den privilegierten Modus
-P physical Unterdrückt die Darstellung von symbolischen Links, statt dessen wird das physikalische Verzeichnis verwendet
-t onecmd Die Shell terminiert nach dem Ausführen des ersten Befehls
-u nounset Bewirkt, dass ungesetzt Variablen Fehlermeldungen erzeugen; ohne diese Option wird ihnen ein leerer Inhalt zugewiesen
-v verbose Befehlszeilen werden angezeigt, bevor sie ausgeführt werden
-x xtrace Alle Befehlszeilen werden mit expandierten Argumenten angezeigt, bevor sie ausgeführt werden

Defaulteinstellungen der Shelloptionen

allexport		off
braceexpand		on
emacs			on
errexit			off
hashall			on
histexpand		on
history			on
ignoreeof		off
interactive-comments	on
keyword			off
monitor			on
noclobber		off
noexec			off
noglob			off
nolog			off
notify			off
nounset			off
onecmd			off
physical		off
posix			off
privileged		off
verbose			off
vi			off
xtrace			off
Seitenanfang

Bash Konfiguration

Befehl Beschreibung
shopt -s {arg} Syntax Shell Option aktivieren
shopt -u {arg} Syntax Shell Option deaktivieren
shopt alle Optionen und deren Status anzeigen
Beispiele
shopt extglob Status der Option Shell-Globbing anzeigen
shopt -s extglob Shell-Globbing aktivieren
shopt -u extglob Shell-Globbing deaktivieren
Option Funktion
cdable_vars bewirkt, dass die Bash Argumente des cd-Befehls als Variablen interpretiert, wenn es sich um keine Verzeichnisse handelt
cdspell einfache Schreibfehler (vertauschte oder fehlende Buchstaben) in Verzeichnisnamen werden durch diese Option automatisch korrigiert
checkhash die Bash sucht einen externen Befehl zunächst in der Hashtabelle, bevor er anhand des Suchpfades gefunden wird
checkwinsize wenn diese Option aktiviert ist, prüft die Bash nach jedem ausgeführten Befehl, ob sich die Terminal-Abmessungen geändert haben.
cmdhist zusammengehörige Befehlszeilen werden in der History in Form einer Zeile abgelegt, dadurch vereinfacht sich ihre Bearbeitung
dotglob durch das Setzen dieser Option werden auch die mit einem Punkt beginnenden Dateinamen beim automatischen Komplettieren berücksichtigt
execfail verhindert in Skripten, dass die Shell nach einem Fehler in einem exec-Befehl terminiert
histexpand bewirkt, dass Historydateien nicht mehr überschrieben, sondern an bestehende Dateien angehängt werden
lithist zusammen mit cmdhist bewirkt sie das Zusammenfassen mehrzeiliger Befehle
sourcepath der source-Befehl kann auf die PATH-Variable zugreifen, wenn diese Option gesetzt ist
expand_aliases erlaubt das Expandieren von Alias-Definitionen
nocaseglob bei der automatischen Dateinamenkomplettierung berücksichtigt die Bash Groß-/Kleinschreibung nicht, wenn diese Option aktiv ist
huponexit allen von einer interaktiven Shell ausgeführten Hintergrundjobs wird ein SIGHUP-Signal gesendet, wenn sie terminiert
restricted_shell die Bash wird im Restricted-Modus mit eingeschränkter Funktionalität betrieben

Defaulteinstellung der Bash Konfiguration (v.4.3.11)

autocd			off
cdable_vars		off
cdspell			off
checkhash		off
checkjobs		off
checkwinsize		on
cmdhist			on
compat31		off
compat32		off
compat40		off
compat41		off
compat42		off
complete_fullquote	on
direxpand		off
dirspell		off
dotglob			off
execfail		off
expand_aliases		on
extdebug		off
extglob			on
extquote		on
failglob		off
force_fignore		on
globstar		off
globasciiranges		off
gnu_errfmt		off
histappend		on
histreedit		off
histverify		off
hostcomplete		off
huponexit		off
interactive_comments	on
lastpipe		off
lithist			off
login_shell		on
mailwarn		off
no_empty_cmd_completion	off
nocaseglob		off
nocasematch		off
nullglob		off
progcomp		on
promptvars		on
restricted_shell	off
shift_verbose		off
sourcepath		on
xpg_echo		off
Seitenanfang

Shell Sonderzeichen

Sonderzeichen Beschreibung
. aktuelles Verzeichnis
.. übergeordnetes Verzeichnis
~ Home-Verzeichnis des aktuellen Benutzers
/ trennt die Verzeichnisnamen in Pfadangaben
\ Escape-Zeichen, das folgende Zeichen verliert seine Sonderbedeutung;
am Zeilenende: der Befehl wird in der nächsten Zeile fortgesetzt
:"..." die meisten eingeschlossenen Sonderzeichen verlieren ihre Bedeutung
´...´ alle eingeschlossenen Sonderzeichen verlieren ihre Bedeutung
`...` wird durch das Ergebnis des eingeschlossenen Befehls ersetzt
? beliebigen Buchstaben in Dateinamen
* beliebige Buchstabenfolge in Dateinamen
[...] steht für einen der Buchstaben innerhalb der Klammern in Dateinamen
! aktiviert die history expansion
{} fasst Kommandos oder Dateinamen zu einer Gruppe zusammen
() fasst Kommandos zu einer Gruppe zusammen, die in einer Subshell ausgeführt werden
< > Eingabe- und Ausgabe-Umleitung
| verbindet Ein- und Ausgabe zweier Befehle (Pipe)
; trennt Befehle innerhalb einer Zeile <Befehl1> ; <Befehl2>
Prozessbedinungen
& Prozess in den Hintergrund <Befehl1> & <Befehl2> Befehl1 wird im Hintergrund ausgeführt, Befehl2 im Vordergrund
&& UND-Verknüpfung, zwischen zwei Befehlen, der zweite Befehl wird ausgeführt, wenn der erste erfolgreich war. <Befehl1> && <Befehl2>
|| ODER-Verknüpfung, zwischen zwei Befehlen, der zweite Befehl wird nur ausgeführt, wenn der erste Befehl fehl schlug. <Befehl1> || <Befehl2>

 

Seitenanfang

Script ausführen und testen

./script.sh ausführen des Scriptes (beim Script muss das Attribut (x) gesetzt sein
sh script.sh ausführen des Scriptes
. script.sh öffnen einer Subshell verhindern
#!/bin/sh Ausführende Shell in der ersten Zeile des Scriptes festlegen (je nachdem welche Shell man für den Script nutzen möchte)
sh -n script.sh Script nur auf Syntax prüfen, nicht ausführen
sh -v script.sh Zeilen vor dem Ausführen unverändert anzeigen (Option -vx können zusammen genutzt werden)
sh -x script.sh Zeilen vor dem Ausführen, nach der Substitutionen anzeigen (wenn Variablen durch einen Befehl erstellt werden (z.B. datum=`date`) wird das Ergebnis des Befehls angezeigt.
echo -e >/dev/null backslash escapes aktivieren
echo "Text" \\n mit aktivierten backslash escapes einen Text mit anschließenden Zeilenvorschub ausgeben.
   
   

- Die Debugg-Optionen kann man auch mit "set -x" in einer Konsole setzen, dann werden alle weiteren Befehle im Debuggmodus dargestellt. Die Option -xv kann man auch zusammen verwenden
- Wenn man innerhalb eines Scriptes auf externe Kommandos zurückgreift, erhöht sich die Laufzeit des Scriptes.

Seitenanfang

Umleitung und Pipes

Befehl > datei stdout in eine Datei leiten
Befehl >> datei stdout am Ende einer Datei anhängen
Befehl 2> datei stderr in eine Datei leiten
Befehl 2>> datei stderr am Ende einer Datei anhängen
Befehl > datei 2>&1 stdout und stderr in die gleiche Datei leiten
Befehl < datei eine Datei an stdin leiten
echo text Ausgabe nach stdout
echo text >&2 Ausgabe nach stderr
read variable Einlesen auf stdin
{ ... } Befehl in aktueller Shell gruppieren
( ... ) Befehl in Subshell gruppieren
Befehl | tee datei Ausgabe auf stdout und in eine Datei leiten
exec <&- stdin schliessen (man erhält den gleichen Effect auch mit der Umleitung nach /dev/null)
exec >&- stdout schliessen (man erhält den gleichen Effect auch mit der Umleitung nach /dev/null)
exec 2>&- stderr schliessen (man erhält den gleichen Effect auch mit der Umleitung nach /dev/null)

die Umleitung mehrerer Befehle in eine Datei erreicht man mit der Gruppierung der Befehle

- Fehlerkanal (stderr) über eine Pipe leiteten, zur weiteren Bearbeitung mit dem nächsten Programm.

befehl 2>&1 1>/dev/null | ...

- Ausführung in der aktuellen Shell

{
	date
	df -m
	ps -ef
} > status.out

- Ausführung in einer Kopie der aktuellen Shell als Subshell

(
	date
	df -m
	ps -ef
) > status.out

bei Verwendung von {...} in Einzeilern, muss man dareuf achten, das hinter der geöffneten Klammer ein Leerzeichen steht und vor der schliessenden Klammer ein Simikolon steht
{ befehl1 ; Befehl2 ; } > datei

Ausgabe duplizieren

- Ausgabe am Bildschirm und in eine Datei
befehl | tee datei
oder mit (-a) Append um an eine bestehende Datei etwas anzuhängen
befehl | tee -a datei

Seitenanfang

Datei Descriptoren

Solange man eine Datei nach der anderen ausliest, bracht man keine Datei Descriptoren, erst wenn man gleichzeitig auf mehrere Dateien zugreifen möchte wird sie benötigt. Mit Datei Descriptoren kann man neben STDIN, STDOUT und STDERR weitere Dateien öffnen um Daten lesen oder schreiben zu können.

- einen Datei Descriptoren öffnen, n kann eine Zahl von 3 - 9 sein.
Syntax:

exec n< datei
exec n> datei
exec n>> datei

- in eine Datei lesen oder schreiben, wenn man was an eine Datei anhängen möchte, wird dieses gleich bei der Definition durch "exec n>> datei" festgelegt.

befehl <&n
befehl >&n

- eine Datei schliessen, egal ob sie mit > < >> geöffnet wurde.

exec n>&-

Beispiel:

Datei monat.dat
Januar
Februar
Maerz
April
Mai

exec 3< monat.dat
read mon1 <&3
read mon2 <&3
echo $mon1 $mon2

Ausgabe
Januar Februar
Seitenanfang

Dateinamen-Expansion

* beliebig viele Zeichen
? ein beliebiges Zeichen
[0-9] [a-zA-Z] ein Zeichen, aus einer Gruppe von bestimmten Zeichen (ASCII-Tabelle)
\ Backslash hebt Sonderbedeutung von Metazeichen aus
   

Duch setzen der Debugg-Option (-x) kann man die Befehlszeile nach der durchgeführten Dateinamen-Expansion sehen
# set -x
# ls *txt
+ ls --color=auto datei0.txt datei1.txt
datei0.txt datei1.txt
Bereich für genau dieses Zeichen
- alle Dateien eines Verzeichnisses die auf "txt" enden
# ls *txt
datei0.txt  datei2.txt  datei4.txt  datei6.txt  datei8.txt  datei.txt
datei1.txt  datei3.txt  datei5.txt  datei7.txt  datei9.txt
- alle Dateien eines Verzeichnisses die an der Stelle die Zahl 1 und 3 und 5 haben.
# ls datei[135].txt
datei1.txt  datei3.txt  datei5.txt
- alle Dateien eines Verzeichnisses die an dieser Stelle die Zahl 1 bis 5 haben.
# ls datei[3-5].txt
datei3.txt  datei4.txt  datei5.txt
- alle Dateien eines Verzeichnisses die an dieser Stelle nicht die Zahlen 2 bis 7 enthalten.
# ls datei[!2-7].txt
datei0.txt  datei1.txt  datei8.txt  datei9.txt
Muster-Alternativen (nur in Bash und Korn-shell)
- die Option "extglob" der Shell muss eingeschaltet sein, damit die Mustersuche funktioniert
# shopt -s extglob

- genau eines der Muster
# ls datei@([2-3]|[5-6]|[8-9]).txt
datei2.txt  datei3.txt  datei5.txt  datei6.txt  datei8.txt  datei9.txt
- mind. eines der Muster
# ls datei+([2-3]|[5-6]|[8-9]).txt
datei2.txt  datei3.txt  datei5.txt  datei6.txt  datei8.txt  datei9.txt
- keines, eines oder mehrere der Muster
# ls datei*([2-3]|[5-6]|[8-9]).txt
datei2.txt  datei3.txt  datei5.txt  datei6.txt  datei8.txt  datei9.txt  datei.txt
- keines, oder eines der Muster
# ls datei?([2-3]|[5-6]|[8-9]).txt
datei2.txt  datei3.txt  datei5.txt  datei6.txt  datei8.txt  datei9.txt  datei.txt
- keines der Muster
# ls datei!([2-3]|[5-6]|[8-9]).txt
datei0.txt  datei1.txt  datei4.txt  datei7.txt  datei.txt  datei*.txt
Sonderzeichen aufheben
- ein Backslash vor * ? [] oder !, verliert das Zeichen seine Sonderbedeutung
# ls datei\*.txt
datei*.txt
Seitenanfang

Builtins erstellen

(Builtins-Funktionen in der Shell, gelten nur in der Shell in der man sie erstellt, bis die Shell beendet wird.)

Hilfe zum Theme "man builtins"
die Funktion wird mit den Aufruf "Befehl ()" erstellt, es erscheint ein ">" als Prompt, dann mit "{" eröffnen und mit "}" enden.
z.B.
file ()
{
ls -l $1
/usr/bin/file $1
}

Seitenanfang

Variablen


!! Um das Gleichheitszeichen herum darf kein Leerraum stehen, da die Shell diese Zeile als Befehl mit Argument interpretiert.

zur Kontrolle ob eine Veriable gesetzt ist kann man die Shelloption (-u) nutzen "set -u", wenn man dann eine Variable aufruft die nicht gesetzt ist erscheint eine Fehlermeldung. Mit "set +u" kann man die Fehlermeldung wieder deaktivieren.
# set -u
# echo $var
bash: var: unbound variable
# set +u
Befehl Beschreibung
Variablen setzen
VAR=123 Variable aus Zahlen
VAR="Text" oder VAR="String1 String2" Variable aus Zeichenketten, Sonderzeichen wie $ behalten ihre Bedeutung
VAR="$var1 $var2" eine Variable aus anderen Variablen zusammenseten
VAR='Text' Variable aus Zeichenketten, alle Metazeichen verlieren ihre Spezialbedeutung
VAR=`Befehl` Variable mit einem Befehl erstellen (Kommando-Substitution)
$ ? 0-9 # * @ ! - Spezialvariablen
${VAR}string Variable innerhalb eines Strings abgrenzen
Variablen anzeigen
echo $var Variable anzeigen
printenv alle Variablen anzeigen
printenv <VARIABLE> angegebene Variable ausgeben
env alle Variablen anzeigen
Variablen löschen
export VAR=  
export -n VAR  
unset VAR  

- Variablen inerhalb eines Strings
# file=datei
# echo ${file}[4-6]*
datei4.txt datei5.txt datei6.txt
- Beispiel für die Bedeutung von ' (Single Quotes) und " (Double Quotes)
# Dollar=1000
# echo "das sind meine $Dollar"
das sind meine 1000
# echo "das sind meine $Dollar\$"
das sind meine 1000$
# echo 'das sind meine $Dollar'
das sind meine $Dollar

# var=12
# echo "Variable: \$var   Wert: $var"
Variable: $var   Wert: 12
- readonly Variablen können nicht gelöscht weden, nur duch beenden der Shell. Mit "readonly" kann man sich alle geschtzten Variablen anzeigen lassen.
# var=12
# readonly var
# var=13
bash: var: readonly variable
# unset var
bash: unset: var: cannot unset: readonly variable
- Variable aus einem Befehl erstellen
var=`befehl`
echo "Ausgabe: `Befehl`"
- wenn man zwei Befehle ineinander Schachteln möchte, muss man die Backtics durch \ schützen.
`befehl1 \`befehl2\``
HOME Homeverzeichnisses des Benutzers
PWD aktuelles Arbeitsverzeichnis
PS1 Kommandozeilenprompt
0 Name des laufenden Prozesses
$ ProzessID des laufenden Prozesses
1 2 3 ... 1. 2. 3. ... bergebener Parameter
# Anzahl der übergebenen Parameter
* oder @ alle übergebenen Parameter
? Exit Status des letzten Kommandos
! ProzessID des letzten Hintergrundprozesses
- gesetzte Shell Option

Variablen indirekt aufrufen mit eval
# wert1=12
# wert2="wert1"
# eval echo \$$wert2
12
Variablen exportieren
export VAR eine Variable Globalisieren
export alle exportierten Variablen anzeigen
env | sort alle exportierten Variablen anzeigen
typeset -x (nur KSH, Bash) alle exportierten Variablen anzeigen
. myscript öffnen einer Subshell vermeiden
in SH, KSH und BASH  
VAR=wert ; export VAR eine Variable Globalisieren
nur in KSH und BASH  
export VAR=wert Variable exportieren
typeset -x VAR VAR1 ... Variable exportieren
typeset -x VAR=wert VAR1=wert1 Variable exportieren
typeset +x VAR VAR1 ... Exportflag wieder entfernen, die Variablen bleiben trotzdem in der aktuellen Shell gesetz.

Umgebungsvariablen werden normalerweise in Grossbuchstaben geschrieben.

Seitenanfang

Rechnen mit der Shell

let var=x+y ; echo $var rechnen mit Integer-Variablen oder Zahlen
let var="10 + 15" bei der Nutzung mit Doppelten Anführungszeichen kann man zur besseren Lesbarkeit mit Leerzeichen arbeiten
let var=6*\(10+10\) bei Rechnung mit Klammern müssen diese mit Backslash geschützt werden, da sie sonst die Bash zur Öffnung einer Subshell veranlassen würden.
((var=x*15)) rechnen mit Integer-Variablen oder Zahlen
((var=10 * 15)) auch mit Leerzeichen möglich
((var=5*(10 + 10))) Rechnung mit Klammern
var=$((10/15)) rechnen mit Integer-Variablen oder Zahlen
var=$((x + y)) auch mit Leerzeichen möglich
var=`expr 1 \* 2` rechnen mit Integer-Zahlen (bei Multiplikation mit expr dem * mit Backslash schützen)
expr 3 + 7 Ergebnis wird direkt ausgegeben
typeset -i var Integer-Variablen deklarieren
var=`echo "1.2 + 1.7" | bc` rechnen mit Fliesskommazahlen
var=`echo "scale=2 ; 342 / 10" | bc` mit "scale" kann man die Genauigkeit der Berechnung angeben (im Beispiel auf die 2. Kommastelle)
echo $RANDOM Zufallszahlengenerator (von 0 - 32767) der Bash oder Korn-Shell abfragen
var=`ksh -c 'echo $RANDOM'` ; echo $var Zufallszahlengenerator der Korn-Shell
var=`perl -e 'print int(rand(100))'` ; echo $var Zufallszahlen mit perl
echo "ibase=16; FF" | bc umwandeln von Hexadezimal in Dezimal, ibase=16 teilt bc mit das es sich um eine Hexadezimalzahl handelt.
echo -e 'obase=16;255' | bc umwandeln von Dezimal in Hexadezimal
echo -e 'obase=2;255' | bc umwandeln von Dezimal in Binär
echo "ibase=2;11111111" | bc umwandeln von Binär in Dezimal
echo "obase=8;10" | bc umwandeln von Dezimal in Oktal
echo -e 'ibase=8;12' | bc umwandeln von Oktal in Dezimal
z.B.
# typeset -i x y z
# x=3 ; y=4
# z=$x+$y ; echo $z
7
# z=$x-$y ; echo $z
-1
# z=$x*$y ; echo $z
12
# z=x*y ; echo $z	# man kann das $ beim rechnen mit Interger-Variablen weglassen
12
# z=8/$y ; echo $z
2
# z=5%$y ; echo $z	# Rest von 5/4
1
# z=`expr $x*$y` ; echo $z
12

# x=3256 ; y=10
# var=`echo "scale=4 ; $x / $y" | bc` ; echo $var
325.6000
Seitenanfang

Zeichenketten


Strings zusammenführen
# var1=das ; var2=ist ; var3=ein ; var4=String
# string=${var1}${var2}${var3}${var4} ; echo $string
dasisteinString
Länge eines Strings ermitteln
- Länge von Parametern kann auf die gleiche Art ermittelt werden, ersten Parameter $1 ist ${#1}
# echo ${#string}
15

# echo $string | awk '{print length($0)}'
oder Ergebnis in eine Variable speicher
var=`echo $string | awk '{print length($0)}'`
Teile von Zeichenketten extrahieren, ersetzen oder löschen
!! nur gültig ab Bash 2.0
${variable:start:länge} oder nur ${variable:start}
- die Positionsangaben beginnen mit 0, wenn die Länge weggelassen wird, erhält man den Wert ab der Startposition bis zum Schluss
extrahieren
# string="abcdefghijk"
# var=${string:2:2} ; echo $var
cd
löschen
# var=${string:0:3}${string:8} ; echo $var
abcijk
ersetzen
# var=${string:0:3}DEFGH${string:8} ; echo $var
abcDEFGHijk
für die Korn-Shell
typeset -Ln variable		Länge n von Linksbündig
typeset -Rn variable		Länge n von Rechtsbündig
extrahieren
# string="abcdefghijk"
# typeset -L6 string ; echo $string
fghijk
# typeset -R3 string ; echo $string
ijk
ersetzen
# string="abcdefghijk"
# typeset -L3 teil1
# teil1=$string ; echo $teil1
abc
# typeset -R3 teil2
# teil2=$string ; echo $teil2
ijk
# stringnew=$teil1"DEFGH"$teil2 ; echo $stringnew
abcDEFGHijk
Muster aus einem String entfernen
nur für Bash und Korn-Shell
${variable%muster}	entfernt rechts kleinstes passendes Stück
${variable%%muster}	entfernt rechts grösstes passendes Stück
${variable#muster}	entfernt links kleinstes passendes Stück
${variable##muster}	entfernt links grösstes passendes Stück
# var="/etc/apache2/sites-enabled/default" ; echo ${var%/*}
/etc/apache2/sites-enabled

# var="/etc/apache2/sites-enabled/default" ; echo ${var##*/}
default

- schneidet rechts 4 Stellen ab
# var="/etc/apache2/sites-enabled/default" ; echo ${var%????}
/etc/apache2/sites-enabled/def

- schneidet links 4 Stellen ab
# var="/etc/apache2/sites-enabled/default" ; echo ${var#????}
/apache2/sites-enabled/default

Seitenanfang

Arrays (Feldvariablen)

nur in KSH und BASH

Der Unterschied zwischen Arrays und "normalen Variablen" ist der, das man die Arrays in Schleifen benutzen kann. Das Array mus nicht unbedingt bei 0 beginnen, es können auch "Löscher" enthalten sein.

Arrays definieren "array[n]=wert"
array[0]="wert1"
array[2]="wert2"
array[5]="wert3"
KSH
set -A array wert1 wert2 wert3

BASH
array=(wert1 wert2 ...)
array=([4]=wert1 wert2 wert3 ...)

Arrays anzeigen
echo ${arr[0]}		einen Wert des Arrays anzeigen
echo ${arr[3]}		einen Wert des Arrays anzeigen
echo ${arr[*]}		alle Werte des Arrays anzeigen
Arrays kopieren
KSH
set -A arr2 ${arr1[*]}

Bash
arr2=(${arr1[*]})

Arrays löschen
unset array
unset arr[n]

Länge eines Arrays anzeigen

echo ${#array[*]}

Werte des Arrays modifizieren durch Angabe von Startpunkt und Länge
# array=(wert1 wert2 wert3)
# echo ${array[*]:1:2}
wert2 wert3
Arrays deklarieren
Ein Array muss nicht unbedingt deklariert werden.
typeset -i arr1		Werte des Arrays sind Integer
typeset -r arr2		Werte der arrays sind Readonly
Seitenanfang

Bearbeiten von Variablen oder Texten mit awk, sed, cut, und tr


awk
- String in kleine Buchstaben
# string="abcdefghijk"
# echo  $string | awk '{print tolower($0)}'
- String in Grossbuchstaben
# echo  $string | awk '{print toupper($0)}'
- Länge eines Strings ermitteln
# echo  $string | awk '{print length($0)}'
weitere Funktionen von awk
index, sub, match, split

- Sting um ein Stück kurzen Länge "len", Startposition "start" (Startposition beginnt bei 1 negative Zahlen sind möglich)
Syntax
awk '{print substr($0,start,len)}'
# echo $string | awk '{print substr($0,4,3)}'
def
- String ab einer Startposition "start" ausgeben
Syntax
awk '{print substr($0,start)}'
# echo $string | awk '{print substr($0,4)}'
defghijk
- ein Teil einse Strings ersetzen Teilstück "old" wird durch "new" ersetzt
Syntax
awk '{print gsub(old, new, $0)}' oder
awk '{gsub("old","new");print}'
awk '{gsub(/old/,"new");print}'
# string="abcdefghijk"
# echo  $string | awk '{gsub("cde","CDE");print}'
abCDEfghijk
Syntax
awk '{print $n}
awk -F char '{print $n}'
# string="abc def ghi:jk-abc def:ghi"
# echo $string | awk '{print $2}'
def
# echo $string | awk '{print $4}'
def:ghi
cut
- mit "cut" einzelne Zeichen (-c), Felder (-f mit Trenner -d) extrahieren
# string="abcdefghijk"
# echo $string | cut -c 3-6
cdef

# echo $string | cut -c 2,4,6,8,10
bdfhj
- Wort und Textfelder extrahieren
-d gibt das gewünschte Trennzeichen an
-f (field) das wievielte Feld das das angegebene Trennzeichen trennt
# string="abc def ghi:jk-abc def:ghi"
# echo $string | cut -d " " -f3
ghi:jk-abc

# echo $string | cut -d ":" -f2
jk-abc def
tr
- mit "tr" einzelne Zeichen innerhalb eines Strings durch andere ersetzenoder löschen.
# string="abcdefghijk"
# echo $string | tr 'a-z' 'A-Z'
ABCDEFGHIJK

# echo $string | tr -d 'def'
abcghijk
sed
- Strings oder ganze Texte mit "sed" bearbeiten, ändern oder löschen
Syntax
sed 's/old/new/g'
s - substitution, ersetzen
g - global, wenn ein Teilstück im String mehrmals vorkommt, werden alle ersetzt
# echo $string | sed 's/cde/CDE/g'
abCDEfghijk
- ohne Angabe von "new" wird das Teilstück gelöscht. # echo $string | sed 's/cde//g' abfghijk
Seitenanfang

Bedingungen definieren

Zeichenketten
"s1" = "s2" wahr, wenn die Zeichenketten gleich sind
"s1" != "s2" wahr, wenn die Zeichenketten ungleich sind
-z "s1" wahr, wenn die Zeichenkette leer ist (Länge gleich Null)
-n "s1" wahr, wenn die Zeichenkette nicht leer ist (Länge größer als Null)
Ganze Zahlen
n1 -eq n2 wahr, wenn die Zahlen gleich sind
n1 -ne n2 wahr, wenn die Zahlen ungleich sind
n1 -gt n2 wahr, wenn die Zahl n1 größer ist als n2
n1 -ge n2 wahr, wenn die Zahl n1 größer oder gleich n2 ist
n1 -lt n2 wahr, wenn die Zahl n1 kleiner ist als n2
n1 -le n2 wahr, wenn die Zahl n1 kleiner oder gleich n2 ist
sonstiges
! Negation
-a logisches UND
-o logisches ODER (nichtexklusiv; -a hat eine höhere Priorität)
\( ... \) Runde Klammern dienen zur Gruppierung. Man beachte, daß sie durch einen vorangestellten Backslash, \, geschützt werden müssen.
-f filename wahr, wenn die Datei existiert. (Weitere Optionen findet man in der man page zu test)
Shell-Script Befehle
. Abkuerzung fuer den Befehl source (interner Shell Befehl)
: Programm ohne Funktion liefert immer 0 zurück (interner Shell Befehl)
[ ] Abkuerzung von test (interner Shell Befehl)
alias Definiert einen Alias (interner Shell Befehl)
awk Programmiersprache zur Datei-Bearbeitung
break Beendet eine Schleife (for, until, while) oder eine case Abfrage (interner Shell Befehl)
builtin Fuert ein Shell internes Kommando aus, auch wenn es durch ein Synonym verdeckt ist (interner Shell Befehl)
case Ueberprueft einen String und fuehrt davon abhaengig Befehle aus
command Fuehrt das angegebene (einfache) Kommando ohne die normale shellinterne Identifizierung aus (interner Shell Befehl)
continue beendet den aktuellen Durchlauf einer for, until oder while Schleife (interner Shell Befehl)
declare Weist einer Variable Werte und / oder Eigenschaften zu
dialog Erzeugt eine Dialog-Box
echo Ausgabe von Text (interner Shell Befehl)
enable Schaltet Shellfunktionen ab- und wieder an (interner Shell Befehl)
env Anzeigen und setzen von Umgebungsvariablen
eval Interpretiert den Inhalt einer Variable als Kommando und fuehrt es aus (interner Shell Befehl)
exec Startet das angegebene Kommando als Ersatz zur laufenden Shell (interner Shell Befehl)
exit [Status] Verlässt die Shell, Beendet das Script und gibt den Fehlerwert (engl. Exit-Status) 0 zurück. Es sind Werte von 0 bis 255 (1 Byte) zulässig. Alle Werte außer 0 signalisieren einen Fehler. Welchen Fehler Sie welchem Wert zuweisen ist Ihre Sache. echo $? zeigt den Exit-Status des letzten Kommandos an. (Das Kommando false setzt den Exit-Status auf 1, true auf 0.)gibt den Status
export [varlist] Ermöglicht auch einer aufgerufenen (sub-) Shell den Zugriff auf die angegebenen Shell-Variablen.
false Liefert den Exit-Wert 1
fc Editieren und Ausfuehren von Befehlen aus der Befehlshistory (interner Shell Befehl)
for Leitet eine Zaehlschleife ein
function Definiert eine Funktion
getopts Durchsuchen der Kommandozeile nach (konventionell) gueltigen Optionen und Argumenten (interner Shell Befehl)
help Zeigt eine Hilfe zu internen Bash Befehlen (z.B. cd) (interner Shell Befehl)
history Anzeigen oder aendern der Befehls-History (interner Shell Befehl)
if Handelt abhaengig einer Bedingung
let Berechnet einen arithmetischen Ausdruck und speichert das Ergebnis in einer Variable
local Erzeugt eine lokale Variable und weist ihr einen Wert zu (interner Shell Befehl)
locale Zeigt Informationen zur lokalen Umgebung an
logout Verlaesst eine Loginshell (interner Shell Befehl)
popd Wechselt in ein durch pushd gespeichertes Verzeichnis. Das Verzeichnis wird aus der Liste entfernt. (interner Shell Befehl)
printenv Zeigt die Umgebungsvariablen an
printf Formatiert Zeichenketten wie die C-Funktion printf()
pushd Speichert den Namen des aktuellen Verzeichnis und wechselt anschliessend in das angegebene Verzeichnis.Siehe popd dirs (interner Shell Befehl)
read [varlist] Liest die durch Leerzeichen getrennten Wörter von Standardeingabe sukzessive auf die angegebenen Shell-Variablen ein.
readonly [varlist] Verhindert ein Überschreiben der angegebenen Shell-Variablen
return Verlaesst eine Funktion mit dem angegebenen Rueckgabewert (interner Shell Befehl)
run-parts Fuehrt alle Skripte und Programme aus die sich in dem angegebenen Verzeichnis befinden
sed bearbeiten von Strings bis zu anzen Texten
shift verschiebt die ganze Kette der Kommandozeilenparameter um eines nach links. Das bedeutet, der Parameter 2 wird zum Parameter1, der Parameter3 zum Parameter2 usw. Der erste Parameter fällt weg. Man kann shift auch mit einer Zahl aufrufen z.B. shift 3 führt dazu, das der Parameter 4 zum Parameter 1 wird.
source Fuehrt bei der Laufzeit das angegebene Shellskript aus ohne eine neue Shell zu oeffnen. (interner Shell Befehl)
suspend Veranlasst die Shell, auf das Signal SIGCONT zu warten (interner Shell Befehl)
test Ueberpruefen von Bedingungen (interner Shell Befehl, in alten Unix Derivaten ein externer Befehl)
tr bearbeiten, ändern von Strings
true Liefert den Exit-Wert 0
typeset Deklariert eine Variable (interner Shell Befehl)
unalias Loescht einen Alias (interner Shell Befehl)
unset Loescht die angegebene Variable (interner Shell Befehl)
until Arbeitet eine Schleife ab bis eine Bedingung erfuellt ist
wait [pid] Wartet auf die im Hintergrund befindlichen Prozesse
while Arbeitet eine Schleife ab solange eine Bedinung erfuellt ist
whiptail Erzeugt eine Dialog-Box
. dateiname Führt die in der Datei spezifizierten Shell-Komandos innerhalb der gleichen Shell aus; ohne . würde eine neue Shell gestartet; execute-Recht für die Datei ist nicht erforderlich.


weitere Hilfe mit "man bash" und "man test"

z.B.
- wenn der Verzeichniswechsel erfolg hat, wir der Befehl "ls -l" ausgeführt, bei misserfolg wird der Befehl nicht ausgeführt.
cd tmp && ls -l

- wenn der Verzeichniswechsel ausgeführt wird, wird der Befehl "ls -l" nicht mehr ausgeführt.

cd tmp || ls -l
Seitenanfang

echo Ausgabe formatiern

echo -e \\n \\t "\033[0;34mApache2 $1\033[0m" \\n
Option Beschreibung
-e Escape Sequenz aktivieren
\\n Zeilenvorschub
\\t horizontaler Tabulator
\033 leitet die farbige Textdarstelleung ein, statt \033 kann auch \e genommen werden, wie im nachfolgenden Beispiel.
[Attribut;Farbem Attribut und gewählter Farbwert
\033[0m schliest Farbdarstellung ab und setzt diese auf Standard zurück
echo -e \\n \\t "\e[0;34mApache2 $1\e[0m" \\n
Attribut Beschreibung
0 Attribute auf Ursprung stellen
1 Fett
4 Unterstrichener Text
5 Blinkender Text
7 Hintergrundfarbe und Textfarbe sind vertauscht
8 Text wird unsichtbar
Textfarben Beschreibung
30 Schwarz
31 Rot
32 Grün
33 Gelb
34 Blau
35 Magenta
36 Cyan
37 Weiß
Hintergrundfarben Beschreibung
40 Schwarz
41 Rot
42 Grün
43 Gelb
44 Blau
45 Magenta
46 Cyan
47 Weiß

mit blauem blinkenden Text

echo -e \\n \\t "\e[51;34mApache2 $1\e[0m" \\n
echo -e \\n "\033[0;31mROT \033[0;32mGRÜN \033[0;33mGELB \033[0;34mBLAU \
 \033[0;35mMANGENTA \033[0;36mCYAN \033[0;37mWEIß \033[0m" \\n
Seitenanfang

if Verzweigung

Operatoren
Syntax der if-Verzweigung
Syntax der if-Verzweigung logische Operatoren
if-Verzweigung Datei-Test Operatoren
Short Circuit-Test

Seitenanfang

Operatoren

je nach der benutzten Shell

Operatoren zum vergleichen von Zahlen (Bourne-Shell)

ist gleich = [ "$var" -eq zahl ]
ungleich != [ "$var" -ne zahl ]
kleiner als < [ "$var" -lt zahl ]
grösser als > [ "$var" -gt zahl ]
kleiner gleich <= [ "$var" -le zahl ]
grösser gleich >= [ "$var" -ge zahl ]

Operatoren zum vergleichen von Zeichenketten (Bourne-Shell)

ist gleich = [ "$var" = "wort" ]
ungleich != [ "$var" != "wort" ]
kleiner als < [ "$var" < "wort" ]
grösser als > [ "$var" > "wort" ]
ist leer oder existiert nicht   [ -z "wort" ]
ist nicht leer   [ -n "wort" ]

Logische Operatoren der Shell

&& UND ist erfolgreich, wenn beide Befehle erfolgreich sind.
|| ODER ist erfolgreich, wenn wenigstens ein Befehl erfolgreich ist.
! NICHT ist erfolgreich, wenn der Befehl fehlgeschlagen ist. (nur in KSH und BASH)

Logische Operatoren des test Kommandos

-a UND ist erfolgreich, wenn beide Befehle erfolgreich sind.
-o ODER ist erfolgreich, wenn wenigstens ein Befehl erfolgreich ist.
! NICHT ist erfolgreich, wenn der Befehl fehlgeschlagen ist. (nur in KSH und BASH)

Bei der eckige Klammer des if Befehls handelt es sich eigentlich um den Befehl test.
if testbefehl
	then
	Befehl
fi

if test bedingung
!! zwischen der Bedingung und then, muss ein Zeilenvorschub oder ein Semikolon stehn und zwischen den letzten Befehl und fi muss ein Semikolon oder ein Zeilenvorschub stehen !!

SeitenanfangSyntax der if-Verzweigung
- wenn die Bedingung zutrifft, wird der Befehl ausgeführt. Es kann ein oder mehrere Befehle sein.
if [ Bedingung ]
	then
	befehl1
fi

if testbefehl then befehl1 befehl2 fi
if [ Bedingung ] ; then befehl1 ; ... ; fi if testbefehl ; then befehl1 ; ... ; fi
- wenn die erste Bedingung zutrifft, wird der Befehl ausgeführt, trifft die Bedingung nicht zu, wird die zweite Bedingung getestet, trifft sie zu, wird der zweite Befehl ausgeführt, trifft diese nicht zu, wird der dritte Befehl ausgeführt.
if [ Bedingung ]
	then
	befehl
	:
	elif [ Bedingung ]
		then
		Befehl3
	else
	Befehl3
fi
SeitenanfangSyntax der if-Verzweigung logische Operatoren
Zahlen
if [ $var -ge 10 -a $var -lt 20 ] ...
if [ $var -ge 10 ] && [ $var -lt 20 ] ...

if (( $var -ge 10 && $var -lt 20 )) ...
if (( $var -ge 10 )) && (( $var -lt 20 )) ...
Strings
if [[ "$var" == "wort1" || "$var" == "wort2" ]] ...
if [[ "$var" == "wort1" ]] || [[ "$var" == "wort2" ]] ...
Seitenanfangif-Verzweigung Datei-Test Operatoren

sh ksh und bash Bedeutung
-f -f ist eine reguläre Datei
-d -d ist ein Verzeichni
-L oder -h -L oder -h ist ein Symbolischer Link
-e -e existiert, egal ob Datei Link oder Verzeichnis
-s -s existiert und ist nicht leer
-r -r ist lesbar
-w -w ist schreibbar
-x -x ist ausführbar
-b -b ist ein block Device (Gerätedatei)
-c -c ist ein character Device (Gerätedatei)
-p -p ist eine named Pipe (Pseudodatei)
-t -t ist ein serielles Terminal
-u -u das setuid Bit ist gesetzt
-g -g das setgid Bit ist gesetzt
-k -k das sticky Bit ist gesetzt
  -S ist Socket (Gerätedatei, Netzwerk)
  -O Benutzer eines Scripts besitzt die Datei
  -G Benutzer des Scripts hat gleiche GID wie Datei
  -o option Option option gesetzt
  file1 -nt file2 file1 neuer als file2
  file1 -ot file2 file1 älter als file2
  file1 -ef file2 file1 und file2 sind Hardlinks


- testen ob die Datei my.conf existiert

if [ ! -f my.conf ]
        then
        echo "Konfigdatei my.conf existiert nicht."
        exit 1
fi
echo "alles in Ordnung."

- testet ob das Verzeichnis existiert, wenn nicht wird es angelegt

if [ ! -d ~/verzeichnis ]; then
        mkdir ~/verzeichnis
fi

 

SeitenanfangShort Circuit-Test
mit && oder || kann man Befehle logisch verknüpfen
Syntax:
- wenn der erste Befehl einen Fehler liefert, wird der zweite Befehl nicht ausgeführt
befehl1 && befehl2
Kurzform von if befehl1 ; then befehl2 ; fi
- wenn der erste Befehl einen Fehler liefert, wird der zweite ausgeführt, liefert der erste Befehl keinen Fehler, wird der zweite nicht ausgeführt
befehl1 || befehl2
Kurzform von if ! befehl1 ; then befehl2 ; fi

z.B.
- wenn die Datei vorhanden ist, wird eine Meldung angezeigt.
[ -f my.conf ] && echo "my.conf ist vorhanden"
- wenn die Datei nicht vorhanden ist, wird eine Meldung angezeigt.
[ ! -f my.conf ] && echo "Datei my.conf nicht vorhanden"
- wenn die Datei nicht vorhanden ist, wird eine Meldung angezeigt, wenn die Datei vorhanden ist, wird der EXIT Staus angezeigt.
[ ! -f my.conf ] && echo "my.conf ist vorhanden" || echo $?
Seitenanfang

case Verzweigung


wird eingesetzt, wenn man eine Variable auf verschiedenen Muster testen möchte. Die Muster werden dann von oben nach unten durchgetestet bis eines passt, dann wird der dazugehörige Befehl oder mehrere Befehle ausgeführt. Wird heufig in init Scripten verwendet.

!! jedes Muser muss mit doppelten Semikolon abgeschlossen werden.
Syntax:
case "$var" in
	muster1)	Befehl1
				Befehl2
	;;
	muster2|muster3)	Befehl3
	;;
	muster4)	Befehl4
	;;
esac
z.B.
init Script
case "$1" in
        start)  echo "Option $1 angegeben"
        ;;
        stop)   echo "Option $1 angegeben"
        ;;
        status) echo "Option $1 angegeben"
        ;;
        *)      echo "Option $1 nicht gültig, nur start|stop|status"
        ;;
esac
Systeminfo Script
case "$1" in
        info|i) echo "Datum:            `date +%d.%m.%Y`"
                echo "Rechner:  `hostname`"
        ;;
        fs|f)   echo "Festplattenbelegung: in MB"
                df -m
                echo
                echo "Speicherbelegung: in MB"
                free -m
        ;;
        *)      echo "Aufruf sysstat.sh [info|fs]"
        ;;
esac
Seitenanfang

for Schleifen

eine for Schleife wird so lange abgearbeitet, wie auch Parameter vorhanden sind. Die Parameter werden von links nach rechts abgearbeitet. Die komplette for Schleife gilt als ein einziges Kommando, Umleitungszeichen <> | & werden erst hinter done gesetzt.

Syntax:

for variable in parameter ; do befehl $variable ; done

for variable in parameter
	do
	befehl $variable
done

z.B.
- zeigt alle Dateien eines Verzeichnisses

for a in * ; do echo $a ; done

- zeigt die angegebenen Dateien nacheinander an

for a in datei1 datei3 datei5
	do
	echo $a ; done

- verschiedenen Varianten die eine Liste von der Zahlen 1 - 9 ausgeben.

for a in {1..9}; do echo $a; done
for a in $(seq 9); do echo $a; done
for a in `seq 9`; do echo $a; done
for a in {1,2,3,4,5,6,7,8,9}; do echo $a; done
for ((a=1; a<10; a++)) ; do echo $a; done

Buchstabenvarianten 2 stellig ausgeben, alle 2 Sekunden eine.

for a in {a..z}{a..z}; do sleep 2; echo $a; done

- verschiedenen Varianten mit Buchstabenlisten

for a in {a..z};do echo $a; done
for a in {a,b,t,z};do echo $a; done
(for a in {a..z}{a..z}; do echo "$a.test"; echo $a; sleep 1; done) \
| grep -i "[a-z][a-z]\.test" | tee -a datei.txt

 

Seitenanfang

while Schleifen

Die Schleife führt einen Block von Befehlen immer wieder aus, wie die Bedingung wahr ist. Die komplette while Schleife gilt als ein einziges Kommando, Umleitungszeichen <> | & werden erst hinter done gesetzt.

Syntax:

while [ Bedinung ]
	do
	Befehl
	 ...
done

while testbefehl
	do
	Befehl
	 ...
done

while [ Bedingung ] ; do Befehl ; ... ; done
while testbefehl ; do Befehl ; ... ; done

Endlosschleifen:

while true ; do ...
while : ; do ...
while [ 1 ] ; do
while [ x = x ] ; do ...
!! Man kann einen Doppelponkt als Befehl verwenden, er gibt immer 0 zurück.

z.B.
#!/bin/bash
#	pingt alle Adressen von 1 - 120 nacheinander an und zeigt die Erreichbarkeit
base=192.168.2
start=1
stop=120
X=$start

while [ $X -lt $stop ]
        do
        ip=$base.$X
        ping -w1 -c1 $ip > /dev/null 2>&1 && \
		echo "$ip ist erreichbar" || \
		echo "$ip nicht erreichbar"
        ((X=$X + 1))
done
- eine Endlos-Schleife beenden, wenn der Benutzer "quit" eingibt.
#/bin/bash
while true ; do
	read eingabe
	[ $eingabe !="quit" ] || break
	...
done
Seitenanfang

until Schleifen


Entspricht einer while not Schleife, test wird so lange wiederholt, bis er erfolgreich ist. Da man in der Orginal Bourne-Shell kein Befehl mit ! negiert werden kann, ist man hier immer auf until angewiesen, anders als in der ksh oder Bash wo dieses möglich ist.
while [ ! Bedingung ] ; do ...
while ! testbefehl ; do ...
!! Die komplette until Schleife gilt als ein einziges Kommando, Umleitungszeichen <> | & werden erst hinter done gesetzt.

Syntax:
until [ Bedingung ]
	do
	Befehl
	...
done

until testbefehl
	do
	Befehl
	...
done
until [ Bedingung ] ; do Befehl ; ... ; done
until testbefehl ; do Befehl ; ... ; done
Endlosschleifen:
until false ; do ...
until [ x = y ] ; do ...
- eine Endlos-Schleife beenden, wenn der Benutzer "quit" eingibt.
#/bin/sh
until false ; do
	read eingabe
	[ $eingabe ="quit" ] && break
	...
done
Seitenanfang

Das test Kommando


Das test Kommando prüft seine Argumente. Exit status 0 zeigt, dass die spezifizierten Bedingungen wahr sind.
Syntax:
#ksh und bash
if ! testbefehl ; then Befehl1 ; fi

#sh
if testbefehl ; then Befehl1 ; else Befehl2 ; fi
z.B.
#!/bin/bash
host=$1
if ! grep $host /etc/hosts > /dev/null ; then
        echo "Rechner $host ist nicht in /etc/hosts vorhanden."
        exit 1
fi
echo "Rechner $host ist in /etc/hosts vorhanden."

#!/bin/sh
host=$1
if grep $host /etc/hosts > /dev/null ; then
        echo "Rechner $host ist in /etc/hosts vorhanden."
        else
          echo "Rechner $host ist nicht in /etc/hosts vorhanden."
fi

if test -r /var/log/syslog then less /var/log/syslog fi
Seitenanfang

Dialog

dialog Textbasierter Dialog
kdialog QT Dialog für KDE
zenity GTK Dialog für Gnome

Beispiel für die verschiedenen Programme

dialog --checklist "Gewünschtes Obst" 0 0 0 A Apfel off B Birne on C Pflaume off
kdialog --checklist "Gewünschtes Obst" A Apfel off B Birne on C Pflaume off
zenity --list --checklist --column "Auswahl" --column "Kürzel" --column "Sorte" --text
 "Gewünschte Obstsorte" FALSE A Apfel TRUE B Birne FALSE C Pflaume

Beispiel Ja-Nein Abfrage

#!/bin/bash
while true;do
 echo -n "Installation fortsetzen (J|N)"
 read YesNo
 case $YesNo in
  j|J)
   break
   ;;
  n|N)
  exit 1
  ;;
  *)
 echo "Bitte geben Sie J oder N ein."
 esac
done
dialog --yesno "Installation fortsetzen?" 0 0 || exit 1

ein EXIT Status von 0 bedeutet Ja und EXIT 1 ist Nein.

Beispiel für die Abfrage eines Wertes.

#!/bin/bash
echo -n "Ihre eMail-Adresse: "
read EMAIL
tmpfile=$(mktemp -t)
dialog --inputbox "Ihre eMail Adresse" 0 0 2>$tmpfile
read EMAIL <$tmpfile
echo $EMAIL
Dialogfunktion Programm
Dialog
Ja/Nein Abfrage --yesno Text Höhe Breite
Benachrichtigung --msgbox Text Höhe Breite
Textdatei ausgeben --textbox Dateiname Höhe Breite
Auswahlmenü --menu Text Höhe Breite Menühöhe
Texteingabe --menu Text Höhe Breite Menühöhe [Kürzel Menüpunkt]
Passworteingabe --passwordbox Text Höhe Breite
KDialog
Ja/Nein Abfrage --yesno Text
Benachrichtigung --msgbox Text
Textdatei ausgeben --textbox Dateiname [Höhe Breite]
Auswahlmenü --menu Text [Kürzel Menüpunkt]
Texteingabe --inputbox Text
Passworteingabe --password Text
Zenity
Ja/Nein Abfrage --question --text Text
Benachrichtigung --info --text Text
Textdatei ausgeben --text-info --filename=Dateiname
Auswahlmenü --list --text Text --column Spaltenkopf Kürzel --column Spaltenkopf Menüpunkt [Kürzel Menüpunkt]
Texteingabe --entry --text Text
Passworteingabe --entry --text Text --hide-text
Seitenanfang

Ausgabe Operationen

echo
Escape-Sequenzen von echo (in der Bash muss die Option -e angegeben werden).
\t	horizontaler Tabstop
\v	vertikaler Tabstop
\n	Newline
\c	Newline unterdrücken
z.B.
#ksh|sh
echo "te\tst"
#bash
echo -e "te\tst"
printf
Formatiert die Ausgabe
Syntax:
printf "format" arg1 arg2 arg3
Die Ausgabe erfolgt genau wie sie zwischen den Anführungszeichen angegeben ist, wenn man ein Leerzeichen zwischen den Platzhaltern setzt, ist die Ausgabe auch mit Leerzeichen.
Platzhalterformen:
%z nur Angabe des Variablentyps
%mz min. Feldbreite (rechtsbündig)
%#mz Oktal und Hex-Formatierung setzt eine 0 (bei Oktal) oder 0x (bei Hex) oder 0X (%#mX) vor die Zahl
%m.nz Präzision
%-m.nz Linksbündig
%+m.nz bei positiven Zahlen wird ein Plus-Zeichen ausgegeben
Platzhalter
%s String
%c ASCII
%d Dezimalzahl (wie %i)
%i Integer (wie %d)
%f Fliesskommazahl
%e Fliesskommazahl in e-Notation
%g automatische wahl von %f oder %e
%u Integer ohne Vorzeichen
%o Oktalzahl ohne Vorzeichen
%x Hexadezimalzahl ohne Vorzeichen
%X wie %x, die Buchstaben werden aber gross geschrieben

z.B.
- Ausgabe eines Strings, das erste Feld ist 10 Zeichen lang und der String ist rechtsbündig ausgerichtet, dann kommt ein Leerzeichen und das nächste Feld mit 15 Zeichen länge und linksbündiger Ausrichtung.
printf "%10s %-15s \n" $LOGNAME $HOSTNAME
- vom ersten String werden nur 3 Zeichen ausgegeben
printf "%10.3s %15s \n" $LOGNAME $HOSTNAME
- positive Zahl mit Pluszeichen
printf "%+5d \n" 113
- erste Zahl als Oktalzahl ausgeben, zweite Zahl als Hex ausgeben
printf "%5o %5x \n" 113 113

Seitenanfang

Eingabe Operationen


Syntax:
read var
read var1 var2 var3
#!/bin/bash
while true
do
        echo -e "Ab hier kann man schreiben (q|quit für Ende): \c"
        read eingabe
        [ "$eingabe" != "q" ] && [ "$eingabe" != "quit" ] || break
        echo $eingabe
done

- read kann die eingelesenen Zeilen auf mehrere Variablen aufteilen, in diesem Beispiel wird der Inhalt der Datei /etc/passwd auf sieben Variablen verteielt, wobei mit IFS=: das Trennzeichen definiert wird, es wird dann die erste Variable ausgegeben.

IFS=:
while read f1 f2 f3 f4 f5 f6 f7
        do
        echo $f1
done < /etc/passwd
Seitenanfang

Kommandozeilen Parameter und Optionen

$0 Name der Kommandoprozedur, die gerade ausgeführt wird (mit Path)
$1 $2 $3 ... erster, zweiter, dritter ... Parameter
${1} ${2} ${3} ... es ist besser die Parameter in geschweifte Klammern zu setzen, da die Bash bei mehrstelligen Parametern diese anders interpretiert. z.B. ${11}
$# Anzahl der Parameter
$* steht für alle Kommandozeilen-Parameter ($1 $2 $3 ...) , ohne Programmname als einzigen String
$@ steht für alle Kommandozeilen-Parameter ($1 $2 $3 ...), ohne Programmname als Liste von Strings, der Unterschied zwischen $* und $@ wird in einer for Schleife sichtbar
$$ Prozeßnummer der Shell (nützlich, um eindeutige Namen für temporäre Dateien zu vergeben)
$- steht für die aktuellen Shell-Optionen
$? gibt den Return-Code des zuletzt ausgeführten Kommandos an (0 bei erfolgreicher Ausführung) mit "exit [Status]" kann man ein Fehlercode setzen, mit "echo $?" kann man den Status anzeigen.
$! Prozeßnummer des zuletzt ausgeführten Hintergrund-Prozesses

z.B.

#script.sh a b c d e f g h i j k

#!/bin/sh
echo ${1} ${11}
echo $1 $11
#!/bin/sh
echo Programmname: $0
echo Argument 1: $1
echo Argument 2: $2
echo Argument 3: $3
echo Argument 4: $4
echo Anzahl Parameter: $#

for var in "$@"
 do echo gesammte Kommandozeile mit \@: $var
done

for var in "$*"
 do echo gesammte Kommandozeile mit \*: $var
done
 

Ausgabe von: # arg.sh arg1 "arg2 ein String" arg3

Programmname: /home/user/script/arg.sh
Argument 1: arg1
Argument 2: arg2 ein String
Argument 3: arg3
Argument 4:
Anzahl Parameter: 3
gesammte Kommandozeile mit @: arg1
gesammte Kommandozeile mit @: arg2 ein String
gesammte Kommandozeile mit @: arg3
gesammte Kommandozeile mit *: arg1 arg2 ein String arg3
Seitenanfang

Fehler in Scripten erkennen und reagieren

- Testet ob zwei Parameter übergeben wurden.

#!/bin/bash
usage="$0 Parameter Zahl"

if [ $# -ne 2 ] ; then
        echo "  Falsche Anzahl von Parametern"
        echo "  $usage"
        exit 1
fi

if echo $2 | grep '[^0-9]' >/dev/null 2>&1 ; then
        echo "  Parameter2 ist keine Zahl"
        echo "  $usage"
        exit 2
fi

echo "Alles OK"

das gleiche Script in Kurzform

#!/bin/bash
usage="$0 Parameter Zahl"
[ $# -ne 2 ] && echo "  $usage" && exit 1
echo $2 | grep '[^0-9]' >/dev/null 2>&1 && echo "  $usage" && exit 2
echo "Alles OK"

die Angabe Optionaler Parameter mit berücksichtigen, dabei muss -opt1 oder -opt2 beim Aufruf des Scripts nicht immer mit angegeben werden.

#!/bin/bash
usage="$0 [-opt1] [-opt2] Parameter Zahl"
if [ "$1" = "-opt1" ] ; then
        echo " [$1] wurde Angegeben und ausgewertet"
        shift
fi
if [ "$1" = "-opt2" ] ; then
        echo " [$1] wurde Angegeben und ausgewertet"
        shift
fi

[ $# -ne 2 ] && echo "  $usage" && exit 1

echo $2 | grep '[^0-9]' >/dev/null 2>&1 && echo "  $usage" && exit 2

echo "Alles OK"
Seitenanfang

Beispiele

#!/bin/sh

# Pruefen, ob Parameter stimmen ...

case "$1" in
stop)
echo "Dieses Script wurde mit dem Parameter stop aufgerufen"
;;
*)
echo "Unbekannte Funktion " $1 " es gilt nur stop ..."
;;
esac
#!/bin/sh 
# Eingabe einer Zahl und while-Schleife
echo "Gib eine Zahl ein!" 
read i 
echo -e "Du hast $i eingegeben!!" 
while [ $i != 0 ] 
do 
i=$[i-1] 
echo $i 
done

- Script fragt nach dem Namen und zeigt ihn dann an.

#!/bin/sh
echo -n "Wie ist der Username: "
read username
echo Du heißt "$username"

#!/bin/bash
#Solange die Anzahl der Parameter ($#) größer 0
while [ $# -gt 0 ];
do
#Ausgabe des ersten Parameters
echo $1
#Parameter verschieben $2->$1, $3->$2, $4->$3,...
shift
done

- Script prüft ob die angegebene Datei lesbar für den User ist oder nicht

#!/bin/sh
if [ -r "$1" ]; then
echo
echo "Datei ist lesbar"
echo
else
echo
echo "Datei ist nicht lesbar"
echo
fi

Exit-Status eines Prozesses ermitteln
- Ihr habt einen Prozess gestartet, der bei seiner Beendigung einen Exit-Status zurückliefert. Nun wollt ihr zB. ein Skript auf unterschiedliche Art arbeiten lassen, je nachdem, ob dieser Prozess terminiert ist oder noch nicht. Ein kleines Skript kann die Information liefern:

#!/bin/sh
./proc
if [ $? != 0 ]; then
echo "proc noch nicht beendet"
exit -1
else
echo "proc beendet"
fi

- $? wäre hier der Exit-Status des vorher ausgeführten Programmes. In diesem Beispiel gehen wir davon aus, dass eine Fortführung unseres Skriptes nur sinn macht, wenn 'proc' beendet ist. Allerdings setzen wir hier voraus, dass 'proc' der zuletzt gestartete Prozess war. Wir können diesen Prozess aber auch mit seinem Namen ansprechen und sind nun unabhängig:

#!/bin/sh
if proc
then echo "proc noch nicht beendet"
else
echo "proc beendet"
fi

- Automatischer eMail Versand aus Scripten

#!/bin/bash
#
# eMail Versand per CLI
#
MAIL=/usr/bin/sendEmail
ABS='user@online.de'
EMPF='other@online.de'
USER="user@online.de"
PASS="Passwort"
SMTP=smtp.online.de:587
SUBJECT="Benachrichtigung an $ABS"
MESSAGE="Der Reaktor brennt"
#
#
if [ ! $MAIL ]; then
        echo -e \\n \\t Paket sendmail wird installiert \\n
        sudo apt-get install sendemail
fi
#
$MAIL -f $ABS -t $EMPF -u $SUBJECT -m $MESSAGE \
 -s $SMTP -xu $USER -xp $PASS -v
echo -e \\n
echo -e \\n \\t \\t "\033[0;33meMail wurde versand\033[0m" \\n

 



Seitenanfang

sonstiges

ls -al /dev/isdn+([0-9]) bash Option "shopt -s extglob" muss gesetzt sein
prips 192.168.2.1 192.168.2.12 erstellt eine List von IP Adressen von 2.1 - 2.12 die man in Scripten nutzen kann
   
   
   
   
   

- Ausgabe in einer Textdatei aller Dateien und Ordner eines Verzeichnisses, welche zwischen zwei Zeitpunkten verändert oder erstellt wurden.

mkdir times && cd times

leeres Verzeichnis anlegen und in dieses wechseln.

touch -d "12:30 2017-01-01" startpunkt
touch -d "13:49 2017-01-06" ziel

Dateien mit den Zeitstempeln anlegen, zwischen denen die Veränderungen stattgefunden haben

find <Verzeichnis> -type f -newer ./startpunkt ! -newer ./ziel >list.txt

<Verzeichnis> durch den Ordner ersetzen, der auf Veränderungen geprüft werden soll.