Bash: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(10 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
 +
= Nützliche Tastenbefehle =
 +
* [[Bash Shortcuts]]
 +
 +
=Einfache Verzweigungen=
 +
In Abhängigkeit vom Returncode eines Befehls oder einer Pipe kann mit den Sonderzeichen ''&&'' und ''||''  eine
 +
Verzweigung durchgeführt werden.
 +
*echo ''das ist sux1.'' > sux1
 +
*rm sux1 && echo ''sux1 ist geloescht!''
 +
*rm sux1 || echo ''sux1 konnte nicht geloescht werden.''
 +
Der Befehl nach ''&&'' wird dabei nur ausgeführt, wenn der Returncode des vorherigen Befehls oder der vorherigen
 +
Pipe 0 war, also der Befehl vor der Pipe fehlerfrei ausgeführt wurde. Ist ein Befehl vor einer Pipe nicht erfolgreich
 +
(Returncode != 0), wird der Befehl nach ''||'' ausgeführt.
 +
* [[Boolsche Algebra]]
 +
 +
=Endestatus=
 +
N:ach der Ausführung eines  Befehls wird ein Returncode (Endestatus) zurückgeliefert. Mit Hilfe des Returncodes lässt
 +
sich feststellen, ob der letzte Befehl fehlerfrei ausgeführt wurde.
 +
Returncode = 0 Letzter Befehl wurde fehlerfrei ausgeführt.
 +
Returncode ≠ 0 Letzter Befehl wurde nicht fehlerfrei ausgeführt.
 +
Das Kommando ''true'' liefert den Returncode 0, ''false'' liefert den Returncode ≠ 0 .
 +
Bei einigen Befehlen wird die zurückgelieferte Fehlermeldung (Returncode ≠ 0) noch weiter differenziert (siehe man
 +
fsck). In der Systemvariablen $? ist der aktuelle Returncode abgelegt und kann vom Benutzer abgefragt werden.
 +
Bsp.:
 +
*fsck asasas
 +
*echo $?
 +
16
 +
oder
 +
*ping www.xinux.de -w 1 -c 1 > /dev/null 2>&1
 +
*ping 172.20.103.2  -w 1 -c 1 > /dev/null 2>&1
 +
*echo $?
 +
0
 +
Erkenntnis: Rechner ist erreichbar
 +
 +
*ping 172.20.103.99  -w 1 -c 1 > /dev/null 2>&1
 +
*echo $?
 +
1
 +
Erkenntnis: Rechner ist nicht erreichbar
 +
 +
*touch bohnen
 +
*rm bohnen 2> /dev/null
 +
*echo $?
 +
0
 +
Erkenntnis: Löschen war erfolgreich
 +
 +
*rm bohnen 2> /dev/null
 +
*echo $?
 +
1
 +
Erkenntnis: Löschen war nicht erfolgreich
  
 
= Bash-Steuerstrukturen =
 
= Bash-Steuerstrukturen =
Zeile 230: Zeile 278:
  
 
=Interpretator=
 
=Interpretator=
==Der Interpretor in der Windowswelt==
+
*[[Bash Interpretator]]
 
 
{| border=1 cellpadding="2"
 
|-
 
! Endung
 
! Interpretor
 
|-
 
| .pl
 
| Perl
 
|-
 
| .py
 
| Python
 
|-
 
| .bat
 
| command.com
 
|-
 
| .cmd
 
| cmd.exe
 
|}
 
==Der Interpretor in der Linuxwelt==
 
Unter  Unix/Linux entscheidet nicht die Suffix welchem Interpretor ein Skript übergeben wird, da ja in
 
der Regel keine Suffix vorhanden ist. Die Art wird durch die Datei bestimmt, und zwar durch die ersten
 
Bytes einer Datei. Wenn wir unser Skript mit
 
*file skript
 
skript: ASCII text
 
untersuchen sehen wir, dass es als normaler ASCII Text interpretiert wird. Bei einem Programmaufruf wird
 
es einfach der aktuellen Shell übergeben (es gibt ausser der bash noch andere Shells z.B. bourne-shell
 
(bsh), korn-shell (ksh), ash). Um sicherzugehen, dass es der richtigen Shell übergeben wird, fuegt man
 
an den Skriptanfang einfach ein #! an, in unserem Fall ein #!/bin/bash für die Bourne-Again Shell.
 
Das bedeutet ,dass das Programm welches hinter dem #! (Gobang Operator) steht der Interpretor ist,
 
dem das Skript übergeben wird.
 
#!/bin/bash
 
date
 
hostname
 
pwd
 
Selbst in der C shell ist somit sichergestellt ,dass das Skript der Bash übergeben wird
 
*file skript
 
skript: Bourne-Again shell script text executable
 
 
 
==Ablauf eines Shell-Skriptes==
 
*Starten einer Subshell
 
*Lesen der Skriptdatei von der Subshell (zeilenweise)
 
*Kommandos werden nacheinander abgearbeitet
 
 
 
Beenden der Subshell und Rückkehr zur aufrufenden Shell
 
 
 
==Möglichkeiten ein Shellskript aufzurufen==
 
===bash skript (r)===
 
* Starten einer Subshell
 
* Lesen der Skriptdatei von der Subshell
 
* Kommandos werden nacheinander abgearbeitet
 
* Beenden der Subshell und Rückkehr zur aufrufenden Shell
 
''(Die Shell, die das Skript abarbeitet, kennt den Namen des Shellskriptes)''
 
 
===bash < skript (r)===
 
* Starten einer Subshell
 
* Lesen der Skriptdatei von der Subshell
 
* Kommandos werden nacheinander abgearbeitet
 
* Beenden der Subshell und Rückkehr zur aufrufenden Shell
 
''(Die Shell, die das Skript abarbeitet, kennt den Namen des Shellskriptes nicht)''
 
  
===./skript (rx)===
 
* Starten einer Subshell
 
* Lesen der Skriptdatei von der Subshell
 
* Kommandos werden nacheinander abgearbeitet
 
* Beenden der Subshell und Rückkehr zur aufrufenden Shell
 
''(Die Shell, die das Skript abarbeitet, kennt den Namen des Shellskriptes, es muss zusätzlich das Ausführungsrecht gesetzt sein.)''
 
 
===exec ./skript (rx)===
 
* Die Subshell ersetzt die aktuelle Shell (überlädt die aktuelle Shell)
 
* Lesen der Skriptdatei von der Subshell
 
* Kommandos werden nacheinander abgearbeitet
 
* Beenden der Subshell; danach ist der Prozess der aufrufenden Shell beendet.
 
 
===source skript  oder . skript (r)===
 
* Lesen der Skriptdatei von der aktuellen Shell
 
* Der interaktive Modus der aktuellen Shell wird „unterbrochen“
 
* Kommandos werden nacheinander abgearbeitet
 
''(Es wird kein neuer Prozess gestartet; Variablen haben in dieser Shell Gültigkeit)''
 
 
 
= Besondere Dateien und Verzeichnisse =
 
= Besondere Dateien und Verzeichnisse =
 
* Links zu weiteren Informationen über besondere Dateien und Systemvariablen:
 
* Links zu weiteren Informationen über besondere Dateien und Systemvariablen:
Zeile 315: Zeile 285:
 
** [[Bash Wichtige Systemvariablen (Auswahl)]]
 
** [[Bash Wichtige Systemvariablen (Auswahl)]]
 
** [[Bash Stellungsparameter]]
 
** [[Bash Stellungsparameter]]
 
=Einfache Verzweigungen=
 
In Abhängigkeit vom Returncode eines Befehls oder einer Pipe kann mit den Sonderzeichen ''&&'' und ''||''  eine
 
Verzweigung durchgeführt werden.
 
*echo ''das ist sux1.'' > sux1
 
*rm sux1 && echo ''sux1 ist geloescht!''
 
*rm sux1 || echo ''sux1 konnte nicht geloescht werden.''
 
Der Befehl nach ''&&'' wird dabei nur ausgeführt, wenn der Returncode des vorherigen Befehls oder der vorherigen
 
Pipe 0 war, also der Befehl vor der Pipe fehlerfrei ausgeführt wurde. Ist ein Befehl vor einer Pipe nicht erfolgreich
 
(Returncode != 0), wird der Befehl nach ''||'' ausgeführt.
 
 
=Endestatus=
 
N:ach der Ausführung eines  Befehls wird ein Returncode (Endestatus) zurückgeliefert. Mit Hilfe des Returncodes lässt
 
sich feststellen, ob der letzte Befehl fehlerfrei ausgeführt wurde.
 
Returncode = 0 Letzter Befehl wurde fehlerfrei ausgeführt.
 
Returncode ≠ 0 Letzter Befehl wurde nicht fehlerfrei ausgeführt.
 
Das Kommando ''true'' liefert den Returncode 0, ''false'' liefert den Returncode ≠ 0 .
 
Bei einigen Befehlen wird die zurückgelieferte Fehlermeldung (Returncode ≠ 0) noch weiter differenziert (siehe man
 
fsck). In der Systemvariablen $? ist der aktuelle Returncode abgelegt und kann vom Benutzer abgefragt werden.
 
Bsp.:
 
*fsck asasas
 
*echo $?
 
16
 
oder
 
*ping www.xinux.de -w 1 -c 1 > /dev/null 2>&1
 
*ping 172.20.103.2  -w 1 -c 1 > /dev/null 2>&1
 
*echo $?
 
0
 
Erkenntnis: Rechner ist erreichbar
 
 
*ping 172.20.103.99  -w 1 -c 1 > /dev/null 2>&1
 
*echo $?
 
1
 
Erkenntnis: Rechner ist nicht erreichbar
 
 
*touch bohnen
 
*rm bohnen 2> /dev/null
 
*echo $?
 
0
 
Erkenntnis: Löschen war erfolgreich
 
 
*rm bohnen 2> /dev/null
 
*echo $?
 
1
 
Erkenntnis: Löschen war nicht erfolgreich
 
  
 
=Steuerung der Ablaufanweisungen=
 
=Steuerung der Ablaufanweisungen=
Zeile 368: Zeile 293:
 
Mit dem Befehl bash select können verschiedene Arten von Menüerstellungsaufgaben, das Erstellen einer menübasierten Listen, das Erstellen eines Menüs aus Dateiinhalten usw. ausgeführt werden.
 
Mit dem Befehl bash select können verschiedene Arten von Menüerstellungsaufgaben, das Erstellen einer menübasierten Listen, das Erstellen eines Menüs aus Dateiinhalten usw. ausgeführt werden.
  
 
+
<syntaxhighlight lang=bash>
<syntaxhighlight>
 
 
#!/bin/bash
 
#!/bin/bash
 
select auswahl in Punkt1 Punkt2 Punkt3 Punkt4
 
select auswahl in Punkt1 Punkt2 Punkt3 Punkt4
Zeile 377: Zeile 301:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
<syntaxhighlight>
+
<syntaxhighlight lang=bash>
 
#!/bin/bash
 
#!/bin/bash
 
PS3="Datei zum Editieren auswählen : "
 
PS3="Datei zum Editieren auswählen : "
Zeile 403: Zeile 327:
 
done
 
done
 
</syntaxhighlight>
 
</syntaxhighlight>
 
 
 
  
 
==break n==
 
==break n==
Zeile 415: Zeile 336:
 
Programme unleserlich und schwer kontrollierbar. Daher ist eine sparsame Verwendung empfehlenswert.
 
Programme unleserlich und schwer kontrollierbar. Daher ist eine sparsame Verwendung empfehlenswert.
  
<syntaxhighlight>
+
<syntaxhighlight lang=bash>
 
#!/bin/bash  
 
#!/bin/bash  
 
while true
 
while true
Zeile 477: Zeile 398:
 
=Filedeskriptoren=
 
=Filedeskriptoren=
 
*[[Bash Filedeskriptoren]]
 
*[[Bash Filedeskriptoren]]
 +
 +
= Aufgaben =
 +
* [[Bash Youtube Abo]]
  
 
=Links=
 
=Links=

Aktuelle Version vom 20. Juni 2024, 02:08 Uhr

Nützliche Tastenbefehle

Einfache Verzweigungen

In Abhängigkeit vom Returncode eines Befehls oder einer Pipe kann mit den Sonderzeichen && und || eine Verzweigung durchgeführt werden.

  • echo das ist sux1. > sux1
  • rm sux1 && echo sux1 ist geloescht!
  • rm sux1 || echo sux1 konnte nicht geloescht werden.

Der Befehl nach && wird dabei nur ausgeführt, wenn der Returncode des vorherigen Befehls oder der vorherigen Pipe 0 war, also der Befehl vor der Pipe fehlerfrei ausgeführt wurde. Ist ein Befehl vor einer Pipe nicht erfolgreich (Returncode != 0), wird der Befehl nach || ausgeführt.

Endestatus

N:ach der Ausführung eines Befehls wird ein Returncode (Endestatus) zurückgeliefert. Mit Hilfe des Returncodes lässt sich feststellen, ob der letzte Befehl fehlerfrei ausgeführt wurde.

Returncode = 0 Letzter Befehl wurde fehlerfrei ausgeführt.
Returncode ≠ 0 Letzter Befehl wurde nicht fehlerfrei ausgeführt.

Das Kommando true liefert den Returncode 0, false liefert den Returncode ≠ 0 . Bei einigen Befehlen wird die zurückgelieferte Fehlermeldung (Returncode ≠ 0) noch weiter differenziert (siehe man fsck). In der Systemvariablen $? ist der aktuelle Returncode abgelegt und kann vom Benutzer abgefragt werden. Bsp.:

  • fsck asasas
  • echo $?
16

oder

  • ping www.xinux.de -w 1 -c 1 > /dev/null 2>&1
  • ping 172.20.103.2 -w 1 -c 1 > /dev/null 2>&1
  • echo $?
0

Erkenntnis: Rechner ist erreichbar

  • ping 172.20.103.99 -w 1 -c 1 > /dev/null 2>&1
  • echo $?
1

Erkenntnis: Rechner ist nicht erreichbar

  • touch bohnen
  • rm bohnen 2> /dev/null
  • echo $?
0

Erkenntnis: Löschen war erfolgreich

  • rm bohnen 2> /dev/null
  • echo $?
1

Erkenntnis: Löschen war nicht erfolgreich

Bash-Steuerstrukturen

Bash-Skriptbefehle

Bash-Variablen und Datenverarbeitung

Bash-Anpassung und -Optionen

Bash Basics

Einfache Shellsonderzeichen

; Trenne Kommandos
# Kommentar
& Programm im Hintergrund starten
| STDOUT von links wird zu STDIN von rechts
* steht für beliebig viel Zeichen auch 0
? steht für genau ein Zeichen
[abc] steht für eins der Zeichen in [ ] hier a b oder c
~ das Homeverzeichnis
> und >> leite in Datei um > überschreibe >> hänge an
< lesen aus Datei
2>&1 leite STDERR auf STDOUT
<< ende Lesen aus Datei (Heredokument)
{ , , , } Zeichenketten zusammensetzen
"..." Entwertung der Sonderzeichen ausser $ ' \
'...' Entwertung sämtlicher Sonderzeichen ausser ' selbst
\ Entwertung des folgenden Sonderzeichens

Eingabe/Ausgabe

Standardeingabe (0): Laufende Programme erwarten von hier ihre Eingaben (normalerweise handelt es sich um die Tastatur).

Standardausgabe (1): Programme schreiben auf diese ihre Ausgaben (Bildschirm).

Standardfehlerausgabe (2) : Fehlerausgaben landen hier (Bildschirm, aber nur die aktive Konsole).

Std.jpg

Umleitungen

cat

Das Programm cat liest von STDIN und gibt es STDOUT wieder aus, solange bis das EOF Zeichen kommt.

  • cat
bla bla
bla bla

Einlesen der Datei dat

  • cat < dat
wichtig

Schreiben in die Datei dat, dies überschreibt den bisherigen Inhalt der Datei

  • cat > dat
sogar noch wichtiger 

Ausgeben der Datei text

  • cat dat
sogar noch wichtiger

Lesen aus der Datei dat und schreiben in die Datei neuedat

  • cat < dat > neuedat
  • cat < neuedat
sogar noch wichtiger

Anhängen der Ausgabe von date an die Datei neuedat

  • date >> neuedat
  • cat neuedat
sogar noch wichtiger
Do 18. Jun 14:08:58 CEST 2009

Umleiten des Standardfehlerkanals nach error

  • rm sux 2> error
  • more error
Entfernen von „sux“ nicht möglich: No such file or directory

Zusammenlegen von Standardausgabe und des Standardfehlerkanals

  • touch tux
  • rm -v sux tux > aus-err 2>&1
  • cat < aus-err
rm: Entfernen von „sux“ nicht möglich: No such file or directory
„tux“ entfernt

Nacheinander auszuführende Kommandos

  • pwd; date
/root
Do 18. Jun 14:13:05 CEST 2009

Verknüpfung von cat und wc

  • cat < aus-err | wc -l
2

Übergeben der Ausgabe von tail als Eingabe von grep mit Hilfe der Pipe "|"

  • tail /var/log/auth.log | grep xinux
Jun 18 13:52:33 zero nss_wins[11433]: pam_unix(login:session): session closed for user xinux

Übergeben der letzten 100 Zeilen von syslog als Eingabe von grep

  • tail /var/log/syslog -n 100 | grep error
Jun 18 09:30:54 zero kernel: [154384.692135] end_request: I/O error, dev fd0, sector 0
Jun 18 09:30:54 zero kernel: [154384.712137] end_request: I/O error, dev fd0, sector 0

Jokerzeichen in der Shell

  • mkdir test
  • cd test/
  • touch a ab abc abcd abcd b cd efg haij

Ein * steht für jedes Zeichen beliebig oft

  • ls *
a  ab  abc  abcd b  cd  efg  haij
  • ls ab*
ab  abc  abcd

Ein ? steht für ein Zeichen

  • ls ?
a b
  • ls ??
ab cd 
  • ls ???*
abc  abcd  efg	haij

Eine [] steht genau für ein Zeichen das in der Klammer ist

  • ls [ab]
a  b
  • ls [abc]?
ab  cd

Eine [!] steht genau für ein Zeichen das nicht in der Klammer ist

  • ls [!abc]*
efg  haij

Mit der {element1,element2} kann man Dateinamen generieren

  • mkdir -v dir{1,2,3,4,5,6}
mkdir: Verzeichnis „dir1“ angelegt
mkdir: Verzeichnis „dir2“ angelegt
mkdir: Verzeichnis „dir3“ angelegt
mkdir: Verzeichnis „dir4“ angelegt
mkdir: Verzeichnis „dir5“ angelegt
mkdir: Verzeichnis „dir6“ angelegt

Backup mit Dateinamengenerierung

cp -v xx{,.save}

Wenn kein Treffer erfolgt wird das Sonderzeichen eingesetzt

  • rm -r *
  • mkdir -v *
mkdir: Verzeichnis „*“ angelegt
  • cd *t/*$

Entwerten kann man ein Sonderzeichen mit einem \

  • rm -rvi \*
rm: Verzeichnis „*“ entfernen? n

Entwerten kann man mehrereSonderzeichen mit ""

  • rm -rvi "*"
rm: Verzeichnis „*“ entfernen? n

Entwerten kann man mehrereSonderzeichen mit

  • rm -rvi '*'
rm: Verzeichnis „*“ entfernen? n

Prinzip der Bash

Auf der Konsole werden die Befehle aneinander gereiht, indem zwischen den Befehlen ein ; eingefügt wird.

  • date ; hostname ; pwd
Mon Dec 15 08:59:13 CET 2003
dozent
/home/thomas

Neben dieser interaktiven Eingabe gibt es auch die Möglichkeit, dass die Shell die Kommandos aus einer Datei lesen kann.

Der Inhalt eines (z.B. mit dem vi erstellten) Shellskriptes:

  • cat skript
date
hostname
pwd

Die Ausgabe des Shellskriptes

  • ./skript
Mon Dec 15 09:07:22 CET 2003
dozent
/home/thomas/bin

Struktogramm nach Nassi-Shneiderman

Ausgabe Datum
Ausgabe Rechnername
Ausgabe Arbeitszverzeichnis

Interpretator

Besondere Dateien und Verzeichnisse

Steuerung der Ablaufanweisungen

Select

Mit dem Befehl bash select können verschiedene Arten von Menüerstellungsaufgaben, das Erstellen einer menübasierten Listen, das Erstellen eines Menüs aus Dateiinhalten usw. ausgeführt werden.

#!/bin/bash
select auswahl in Punkt1 Punkt2 Punkt3 Punkt4
do
   echo "Ihre Auswahl war : $auswahl"
done
#!/bin/bash
PS3="Datei zum Editieren auswählen : "
select AUSWAHL in *.sh exit
do
   case "$AUSWAHL" in
      exit)
           echo "exit" 
           break
          ;;
        "")
           echo "$REPLY: Ungültige Auswahl" 
           ;;
         *)
             if [ -d "$AUSWAHL" ]
              then
                echo "Verzeichnis kann nicht editiert werden"
                continue
              else
                $EDITOR $AUSWAHL
               fi
              break
            ;;
   esac
done

break n

Die aktuelle Schleife wird abgebrochen, danach wird mit der ersten Anweisung nach der Schleife weitergemacht. Bei Verschachtelungen wird auf der n-ten Schleifenebene aufgesetzt.

Anmerkung: Ein sinnvoller Einsatz dieser Konstrukte liegt in der Behandlung von Ausnahmen (Fehler). Intensiver Einsatz macht die Programme unleserlich und schwer kontrollierbar. Daher ist eine sparsame Verwendung empfehlenswert.

#!/bin/bash 
while true
 do
  test -f /tmp/sux && break  
  echo "unn weiter"
  sleep 3
 done
 echo  "und tschuess"

Funktionen

bash funktion

Signalbehandlung

Signale bei der Programmierung der bash

Es existieren verschiedene Möglichkeiten, auf welchem Wege Signale gesendet werden können:

  1. von aussen:
    1. Benutzer (< DEL >, < CTRL >|, etc.)
    2. Prozesse (kill, alarm)
  2. von innen:
    1. Programmfehler (Adressfehler, ungültiger Befehl, Division durch 0, etc.)

Signale dienen der Interprozesskommunikation. Diese Nachrichten beschränken sich allerdings auf die Übertragung eines einzigen Wertes.

Von den Befehlen trap und kill werden folgende Signale verwendet:

Signalnummer Bedeutung
0 Beenden von bash
SIGHUP 1 Logoff von einer Datensichtstation
SIGINT 2 Drücken der Taste < DEL >
SIGQUIT 3 Drücken der Taste < CTRL > + c
SIGKILL 9 kill: unbedingter Prozessabbruch
SIGTERM 15 Programmbeendigung

Reaktion eines Prozesses auf den Empfang eines Signals

  • Der Prozess beendet sich (meist Standardeinstellung).
  • Der Prozess ignoriert das Signal. (Ausnahme: SIGKILL)
  • Der Prozess fängt das Signal ab, d.h. er leitet eine selbst definierte Reaktion ein.

Weitere Möglichkeiten der Bash-Shell

Alias-Namen

Filedeskriptoren

Aufgaben

Links