Name des Skriptes
testen, ob es schon ein Programm mit dem gewünschten Skriptnamen gibt
type mein_Skript.sh
Ausführbar machen und aufrufen
chmod +x /pfad/zu/mein_Skript.sh
starten
/pfad/zu/mein_Skript.sh
./mein_Skript.sh
bash mein_Skript.sh
Skript verfügbar machen
~/bin/
~/.profile
ls -l /usr/local/bin
sudo chown root /usr/local/bin/mein_Skript.sh
sudo chgrp root /usr/local/bin/mein_Skript.sh
sudo chmod 755 /usr/local/bin/mein_Skript.sh
Die Shebang
Shebang:
#!/bin/bash
/bin/sh in der Shebang.
/bin/sh hingegen ist laut POSIX-Standard ein Muss.
Die Bash ist eine komplexere Shell, die nicht auf allen unixoiden Systemen zur Verfügung steht.
Unter Ubuntu ist /bin/sh ein symbolischer Link auf die Dash.
1.) Kommentare einfügen
2.) Variablen – Teil 1
2.1.) Variablen belegen
2.2.) Variablen lesen
2.3.) Variablen löschen
2.4.) Variablen abgrenzen
2.5.) Quoting
3.) Befehle
4.) Variablen
5.) Maskierung mit Backslashes
6.) Variablen – Teil 2
7.) Abschneiden von Mustern
8.) Umgebungsvariablen
9.) Rechnen mit der Shell
10.) Arrays
10.1.) Arrays belegen
10.2.) Arrays auslesen
10.3.) Arrays löschen
10.4.) Assoziative Arrays
11.) Interaktion mit dem Benutzer
11.1.) Ausgabe von Text
11.2.) Einlesen von Eingaben
12.) Umleitungen
13.) Das Test-Kommando
14.) Programmführung
14.1.) If-Else-Anweisung
14.2.) Case-Anweisungen
14.3.) Schleifen
15.) Parameter an ein Skript übergeben
16.) Funktionen
#!/bin/bash
#Hallo Welt Skript
echo "Hallo Welt"
11.2.) Einlesen von Eingaben
1.) Kommentare einfügen
# Dies ist ein Kommentar
2.) Variablen – Teil 1
2.1.) Variablen belegen
Im Gegensatz zu vielen anderen Programmiersprachen darf man bei der Shell keine Leerzeichen vor und nach dem Zuweisungszeichen = verwenden!
message=hallo
message="hallo Welt"
2.2.) Variablen lesen
echo "$message"
2.3.) Variablen löschen
unset message
2.4.) Variablen abgrenzen
Gelegentlich kann es der Fall sein, dass man Variablen innerhalb einer Zeichenkette verwenden möchte.
echo "$message"
echo "$messagelolo"
echo "${message}lolo"
2.5.) Quoting
3.) Befehle
echo Hallo, Welt
echo "Hallo, Welt"
echo *
-> bin include lib local man sbin share src var
echo "*"
-> *
echo "Dies ist eine
> mehrzeilige Ausgabe.
> Man hält es nicht für möglich."
4.) Variablen
foo="Hallo, Welt"
echo "$foo"
echo $foo
-> Hallo, Welt
date +%A
Der Parameter %A zeigt den ausgeschriebene Wochentag an
Montag
Auf einem deutschen System ist diese Ausgabe wie erwartet auf Deutsch. Man kann nun die Variable $LC_ALL
LC_ALL=C date +%A
Monday
5.) Maskierung mit Backslashes¶
echo \$foo
$foo
6.) Ausgaben in eine Variable schreiben
Befehlssubstitution
#!/bin/bash
#Ausgaben in Variable schreiben
#Variablendefinition
suchwort=player
liste=$(apropos $suchwort)
echo " Player-Liste:"
echo "$liste"
#!/bin/bash
#Ausgaben in Variable schreiben
#Variablendefinition
suchwort=player
liste=$(apropos $suchwort)
echo " Player-Liste:"
echo "$liste"
7.) Abschneiden von Mustern¶
Eine gewöhnungsbedürftige, aber doch sehr nette Funktion ist das Herausschneiden bestimmter Muster aus der Zeichenkette einer Variablen.
Schnitt-Funktionen
Funktion Erklärung
${variable%muster} Entfernt rechts das kleinste passende Stück.
${variable%%muster} Entfernt rechts das größte passende Stück
${variable#muster} Entfernt links das kleinste passende Stück.
${variable##muster} Entfernt links das größte passende Stück
pfadname="/var/www/index.html"
echo $pfadname
/var/www/index.html
echo "Pfad: ${pfadname%/*}"
Pfad: /var/www
echo "Dateiname: ${pfadname##*/}"
Dateiname: index.html
8.) Umgebungsvariablen
HOME Enthält das Homeverzeichnis des Benutzers.
PATH Suchpfad für Kommandos.
PWD Enthält das Aktuelle Verzeichnis.
? Enthält den Exitstatus des letzten Kommandos
9.) Rechnen mit der Shell
pingu@ubuntu:~$ echo $((100 / 3))
33
pingu@ubuntu:~$ x="62"
pingu@ubuntu:~$ echo $(($x + 12))
74
pingu@ubuntu:~$ ((x++))
pingu@ubuntu:~$ echo "$x"
63
pingu@ubuntu:~$ a=$((3 + 4 * 2))
pingu@ubuntu:~$ echo "$a"
11
pingu@ubuntu:~$ b=$(((3 + 4) * 2))
pingu@ubuntu:~$ echo "$b"
14
10.) Arrays
10.1.) Arrays belegen
Um einen Wert in ein Array zu schreiben, ist es nötig, den Index mit anzugeben. Allgemein sieht das folgendermaßen aus:
Arrayname[i]=Wert
Soll ein neues Array mit mehreren Werten auf einmal belegt werden, dann bietet sich folgende Schreibweise an:
Arrayname=(Dies sind vier Werte)
Es können auch Elemente an das Ende eines Arrays angefügt werden. Das Ende ist dabei der höchste bereits existierende Index:
Arrayname+=(all diese sieben Elemente werden einzeln angefügt)
10.2.) Arrays auslesen
echo ${array[2]}
Wird als Index ein „@“ oder „*“ angegeben,
${array[*]} oder ${array[@]}: Alle Elemente mit Nachbearbeitung wie Globbing oder Word-Splitting.
"${array[*]}": Kein Globbing, Elemente getrennt durch erstes Zeichen aus $IFS, Endergebnis ist ein Argument.
"${array[@]}": Kein Globbing, jedes Element wird ein eigenes Argument.
echo ${array[*]}
Hallo, Welt! bin boot dev etc home lib lost+found media mnt opt proc root run sbin srv sys tmp usr var Noch ein paar Worte und Leerzeichen.
10.3.) Arrays löschen
unset array
10.4.) Assoziative Arrays
declare -A meinarray
meinarray=(
[zwei]="Zweiter Wert"
[drei]="Dritter Wert"
[vier]="Vierter Wert"
)
meinarray[eins]="Ein Wert"
echo ${meinarray[eins]}
11.) Interaktion mit dem Benutzer
11.1.) Ausgabe von Text
#!/bin/bash
#Hallo Welt Skript
echo "Hallo Welt"
11.2.) Einlesen von Eingaben
#!/bin/bash
#Begrüßung
read -p "Geben sie ihren Namen ein:" name
echo Hallo: $name
12.) Umleitungen
Operator Erklärung
> Dient der Umleitung der Standardausgabe in eine Datei.
>> Dient ebenfalls der Umleitung in eine Datei, hängt jedoch die Ausgabe an eine bereits bestehende Datei an anstatt diese zu überschreiben.
| Mit dem Pipeoperator lässt sich die Ausgabe eines Kommandos als Eingabe für ein anderes verwenden.
< Statt von der Standardeingabe (Tastatur) wird aus einer Datei gelesen
13.) Das Test-Kommando
-d Verzeichnis Ist wahr, wenn "Verzeichnis" existiert.
-e Datei Ist wahr, wenn Datei existiert.
-f Datei Ist wahr, wenn reguläre Datei existiert.
-w Datei Ist wahr, wenn die Datei existiert und Schreibzugriff erlaubt ist.
-x Datei Ist wahr, wenn Datei existiert und Ausführbar ist.
-n String Ist wahr, wenn String nicht leer ist. (Bsp. eine Variable)
-z String Ist wahr, wenn String leer ist. (Bsp. eine Variable)
String1 = String2 Ist wahr, wenn String1 gleich String2 ist.
Zahl1 -eq Zahl2 Ist wahr, wenn Zahl1 gleich Zahl2 ist. (-eq = equal)
Zahl1 -lt Zahl2 Ist wahr, wenn Zahl1 kleiner Zahl2 ist. (-lt = less than)
Zahl1 -gt Zahl2 Ist wahr, wenn Zahl1 größer Zahl2 ist. (-gt = greater than)
Zahl1 -le Zahl2 Ist wahr, wenn Zahl1 kleiner oder gleich Zahl2 ist. (-le = less or equal)
Zahl1 -ge Zahl2 Ist wahr, wenn Zahl1 größer oder gleich Zahl2 ist. (-ge = greater or equal)
Zahl1 -ne Zahl2 Ist wahr, wenn Zahl1 nicht gleich Zahl2 ist. (-ne = not equal)
! foo Ist wahr, wenn foo falsch ist, also eine Negation.
14.) Programmführung
14.1.) If-Else-Anweisung
if [ Test-Bedingung ]
then
Befehl...
fi
if [ Test-Bedingung ]
then
echo "Ok, alles in Ordnung."
else
echo "Ahrg...Fehler."
fi
if [ Test-Bedingung ]
then
Befehl...
elif [ Test-Bedingung ]
then
Befehl...
else
Befehl...
fi
#!/bin/bash
echo "Wie ist Ihr Name?"
read ANTWORT
if [ "$ANTWORT" == "root" ]
then
echo "Hallo, Administrator."
else
echo "Hallo, Anwender."
fi
Ein Beispiel zeigt, wie man auf die Existenz einer Datei hin prüft und entsprechend dem Ergebnisse eine Meldung dazu ausgibt.
#!/bin/bash
#Dateitest
if [ -f /home/Pingu/test.txt ]
then
echo "Die Datei test.txt in Pingus Home ist da."
else
echo "Die Datei test.txt in Pingus Home fehlt."
fi
Oder das ganze wird mit einer elif-Konstruktion erweitert.
#!/bin/bash
# Dateitest
if [ -f /home/Pingu/test.txt ]
then
echo "Die Datei test.txt in Pingus Home ist da."
elif [ -d /home/Pingu/test.txt ]
then
echo "test.txt ist ein Verzeichnis"
else
echo "Die Datei test.txt in Pingus Home fehlt"
fi
14.2.) Case-Anweisungen
#!/bin/bash
dat="$1"
# Schneide vor Dateiendung ab:
ext=${dat/*./}
case $ext in
pdf)
xpdf "$dat"
;;
sh)
shellcheck "$dat"
;;
png|jpg|gif)
eog "$dat"
;;
wav|mp3)
aplay "$dat"
;;
*)
echo Unbekanntes Dateiformat"!"
;;
esac
14.3.) Schleifen
for-Schleife
while-Schleife
until-Schleife
params="a b c"
for z in $params
do
echo $z
done
#!/bin/bash
# for-schleife
for wort in Hallo "du Welt" "da draußen"
do
echo "$wort"
done
#!/bin/bash
# Variablendefinition
inputdir="/home/foo/Bilder/ZuBearbeiten"
outputdir="/home/foo/Bilder/Bearbeitet"
# Abarbeiten der eingelesenen Bilder mit Hilfe einer For-Schleife
# und dem Programm ImageMagick.
for pic in "$inputdir"/*.png
do
picname=$(basename "$pic")
echo "Bearbeite Bild: $picname"
convert "$pic" -colorspace Gray "$outputdir/$picname"
done
for wert in "${array[@]}"
do
Befehl...
done
for ((Anfangswert;Bedingung;Operation))
do
Befehl1
Befehl2
# usw.
done
for ((z=2004;z<=2014;z++))
do
mkdir Archiv_"$z"
done
while [ Test-Bedingung ]
do
Befehl1
Befehl2
# usw.
done
#!/bin/bash
# Warten auf das richtige Ergebnis.
echo "F
rage: Was ergibt 2 + 2"
echo ""
while ((answer != 4))
do
read -p "Bitte ihre Eingabe:" answer
case "$answer" in
4) echo richtig
;;
*) echo falsch
;;
esac
done
Eine while-Schleife eignet sich auch besonders gut, um ohne Interaktion Datendateien abzuarbeiten. Hierzu ein weiteres Beispiel:
#!/bin/bash
# Liste aus einer .csv-Datei verarbeiten
while read stapel
do
readarray -td\; zeile <<<"$stapel"
echo "
Vorname: ${zeile[0]}
Name: ${zeile[1]}
Funktion: ${zeile[2]}"
done < liste.csv; echo
15.) Parameter an ein Skript übergeben
#!/bin/bash
# willkommen
if [ $1 == "Pingu" ]
then
echo "Hallo, kleiner Pingu!"
else
echo "Hallo, $1"
fi
Die Variable $# gibt die Anzahl der verwendeten Parameter aus. So kann man prüfen, ob das Skript sinnvoll verwendet wird:
#!/bin/bash
# Willkommen
if [ $# -ne 1 ]
then
echo; echo "Verwendung: $0 Name"; echo
elif [ $1 == "Pingu" ]
then
echo "Hallo, kleiner Pingu!"
else
echo "Hallo, $1"
fi
16.) Funktionen
funktionsname(){
Befehle...
}
#!/bin/bash
PFAD="/home/pingu/"
# Funktionsdefinitionen
wievieledateien() {
anzahl=0
for file in "$PFAD"/* ; do
(( anzahl++ ))
done
echo "Es befinden sich $anzahl Dateien und Ordner in $PFAD"
}
./zaehledateien
#!/bin/bash
wievieledateien() {
zaehlpfad="$1"
for file in "$zaehlpfad"/* ; do
(( anzahl++ ))
done
echo "Es befinden sich $anzahl Dateien und Ordner in $zaehlpfad"
}
wievieledateien /home/pingu
wievieledateien /home/edit