USER="schiermi"
NAME="Andreas Schiermeier"
EMAIL="[email protected]"
TWITTER="@schiermi"
EMPLOYER="FactSet Digital Solutions GmbH"
_=("🐧@💻" "🚴" "https://ccc-ffm.de/")
-
lt.
man 1 bash
ein "command language interpreter"-
"Programmiersprache für Betriebssystemprozesse"
-
direkte Kommandoeingabe (interaktive Shell)
-
Kommandos nach einem "Drehbuch" (Shellskript).
-
Interaktiv kann der Bediener auf unvorhergesehene (Fehler) reagieren. Passiert im Script zuviel Unbedachtes muss öfters gedreht oder dass Drehbuch werden.
-
Anfang der 1970er Jahre: Unix-Shells
-
Ende der 1970er: Stephen R. Bourne Shell, sh, Basis aktueller UNIX-shells; sowie ksh, csh
-
Ende der 1980er: bash bourne again shell vereint und erweitert bekannte Features
-
Anfang der 1990er: zsh, weitere neue Ansätze, werden teilweise auch in bash übernommen
-
Aktuell: bash auf vielen Systemen verfügbar und die Standardshell; Geschichte "erlebbar"
-
Vorraussetzung & Einstiegshürde: Kommandos müssen bekannt sein
-
; (Semikolon): separiert mehrere Anweisungen in einer Eingabezeile
-
⏎ (Zeilenschaltung, newline): Bringt Anweisungen zur Ausführung
-
einige (wichtige) Tastenkombinationen mit ✲ (Strg, Steuerung, Ctrl, Control)
✲+C |
Eingabe oder Programmausführung abbrechen (genauer: sendet Signal 2, SIGINT) |
✲+D |
Sende EOF (beende die Eingabe) |
✲+R |
In der Befehlszeilenhistorie suchen |
✲+S |
Terminal Flusskontrolle Stopp |
✲+Q |
Terminal Flusskontrolle Fortsetzen |
✲+Z |
Vordergrundprogramm in interaktiver Shell mit Jobcontrol anhalten (sende Signal 19, SIGSTOP) |
✲+A |
Springe in der Befehlszeile an den Anfang (via readline) |
✲+E |
Springe in der Befehlszeile an das Ende (via readline) |
← → |
Innerhalb der Befehlszeile navigieren |
↑ ↓ |
Innerhalb der Befehlszeilenhistorie navigieren |
Note
|
Unter Umständen werden Tastenkombinationen vom Betriebssystem, der grafischen Benutzeroberfläche oder dem Terminalemulator abgefangen. Desweiteren können Terminal (tty) oder die readline Bibliothek abweichend arbeiten |
Programme sind per Dateisystempfad vom Betriebssystem auffindbar und werden diesem zur Ausführung überlassen.
-
/bin/ls
-
/bin/mv
Builtins sind aus Effizienzs- oder Machbarkeitsgründen von der Shell selbst abgearbeitete Befehle.
-
pwd
-
test
-
[
-
(
time
)
-
cd
-
read
-
return
-
exit
-
[[
-
builtin
-
command
-
man 1 bash
, SHELL BUILTIN COMMANDS -
help
-
help builinname
Funktionen fassen mehrere Kommandos als benannte Subroutine zusammen (vergleichbar zu Programmiersprachen).
function fname () {
echo "Mein Name ist ${FUNCNAME}."
return 0
}
declare -F
declare -f
Aliase dienen als Abkürzung für häufig genutzte Aufrufe.
# Eingabe von "la" führt "ls -la" aus
alias la='ls -la'
# Eingabe von "cd.." führt "cd .." aus
alias cd..='cd ..'
# Aliase auflisten
alias
# Alias löschen
unalias la
Suchreihenfolge: Alias, Funktion, Builtin, Programm (Suche anhand PATH)
-
man 1 bash
, "COMMAND EXECUTION"
|
Deklaration bei erster Zuweisung |
|
Deklaration ohne Zuweisung |
|
|
|
Ganzzahl, Zuweisung einer Zeichenkette ergibt 0! |
|
Ganzzahl, readonly |
|
Variable löschen |
|
Indiziertes Array (Startindex: 0) |
|
Textindiziertes Array |
|
ganzes Array löschen |
|
Wert an Index in Array löschen |
Note
|
Innerhalb von Funktionen zur Begrenzung des Gültigkeitsbereichs local statt declare verwenden.
|
-
Zugriff auf einfache Variablen:
$variable
-
…oder besser:
${variable}
-
-
Zugriff auf das zweite Element des Arrays (Index 1):
${indexarray[1]}
-
Alle Elemente:
${indexarray[@]}
-
Anzahl der Elemente:
${#indexarray[@]}
-
Zugriff auf Element des Index "key":
${keyarray["key"]}
-
Alle Keys:
${!keyarray[@]}
-
Alle Elemente:
${keyarray[@]}
echo "${HOME}"
echo "${indexarray[1]}"
echo "${keyarray["Frankfurt"]}"
|
Scriptname |
|
Anzahl der übergebenen Parameter |
|
dem Script übergebene Parameter |
|
dem Script übergebene Parameter (> 9) |
|
dem Script übergebene Parameter als String verbunden |
|
dem Script übergebene Parameter als Array |
|
Prozess-ID der Shell |
|
Fehlercode des zuletzt beendeten Programms |
|
Prozess-ID des Elternprozesses |
|
Hostname des das Script ausführenden Systems |
|
aktuelles Arbeitsverzeichnis |
|
Hauptverzeichnis des angemeldeten Benutzers; Ziel für "cd" und Wert von ~ |
|
Suchpfad für ohne vollen Pfad aufgerufene Programme |
PATH="/home/as/bin:/usr/local/bin:/usr/bin:/bin:/usr/lib/mit/sbin"
-
/home/as/bin/ls
-
/usr/local/bin/ls
-
/usr/bin/ls
-
/bin/ls
-
/usr/lib/mit/sbin/ls
-
Suchcache anzeigen: hash -l
-
Suchcache leeren: hash -r
-
man 1 bash
, PARAMETERS
Noch eine Variable mehr: IFS
-
${IFS}
: Internal Field Separator -
Trennzeichen für die "Generierung" von Parametern aus Variablen.
-
Standard: Leerzeichen, Tabulator, Zeilenumbruch
-
unset
IFS stellt den Standard wiederher (nicht: IFS="").
Note
|
Das erste Zeichen aus IFS wird bei "$*" als Verbindungszeichen der Elemente verwendet.
|
-
Demo:
demo/params.sh
Allgemein: Textersetzungen im eingegebenen oder eingelesenen Kommando.
-
Es wird etwas Anderes ausgeführt als eingegeben.
echo "${HOME}"
Wildcards (üblicherweise anhand von Dateinamen)
|
keines bis beliebig viele Zeichen |
|
exakt ein beliebiges Zeichen |
|
ein Zeichen aus dem angegebenen Bereich |
-
Wildcards sind kombinierbar
-
Nicht mit RegEx z.B. “grep” (regulären Ausdrücken verwechseln)!
ls -l [0-9]*.csv
i=2
echo $(( i + 2 ))
echo {2000..2018}{01..12}{a..f}.txt
echo "Externe IP: $(curl -s ifconfig.co)"
# veraltet, nicht verschachtelbar:
echo "Externe IP: `curl -s ifconfig.co`"
# ähnlich: Dateiinhalt als Parameter nutzen
echo "$(< /etc/passwd)"
~
# Wert von ${HOME}
echo ~
# HOME-Verzeichnis eines (anderen) Benutzers
echo ~root
cmd1 | cmd2 |
STDOUT von cmd1 mit STDIN von cmd2 verbinden |
cmd1 |& cmd2 |
STDOUT und STDERR von cmd1 mit STDIN von cmd2 verbinden |
cmd > datei |
STDOUT von cmd datei schreiben |
cmd >> datei |
STDOUT von cmd an datei anhängen |
cmd < datei |
STDIN für cmd aus datei einlesen |
cmd1 < <( cmd2 ) |
STDOUT der Subshell von cmd2 als STDIN für cmd1 |
-
Demo:
demo/stdouterr-echo.sh
-
Demo:
demo/stdouterr-ls.sh
Im Allgemeinen signalisiert der Hashbang (#!) dem Betriebssystem dass diese Datei nicht als Binärdatei ausgeführt werden kann, sondern ein Interpreter zu Hilfe genommen werden soll.
#!/bin/bash |
eindeutig, bash muss jedoch in /bin vorhanden sein |
#!/bin/sh |
sollte nicht verwendet werden, wenn bash-Features verwendet werden |
#!/usr/bin/env bash |
findet bash (oder generell den angegebenen Interpreter auch an ungewöhnlichen Pfaden; benötigt aber im Gegenzug einen Zwischenschritt |
|
Zugriff auf uninitialisierte Variablen erzeugt einen Fehler |
|
Nicht abgefangene Fehler (rc != 0) beenden das Script |
|
Fehler in Pipes-Ketten werden als Fehler des gesamten Konstrukts gewertet |
|
verhindert das Überschreiben bestehender Dateien mit |
|
verhindert, dass Leerzeichen als Worttrenner verwendet werden |
Untersucht Script auf potenzielle Fehlerquellen |
|
Styleguide für Shellskripte |
tmpfile="$(mktemp)"
function cleanup() {
rm -f "${tmpfile}"
}
trap "cleanup" exit
xdg-open "https://github.com/schiermi/bashmeetup/"
echo "[email protected] - @schiermi"
echo "Danke für das Interesse!"
~adt/guest
echo "$?"