Linux-Tutorial / Schreiben Sie Ihr erstes Bash-Skript mit Variablen, Bedingungen und Schleifen

Ein Shell-Skript speichert Befehle und Kontrollfluss in einem wiederverwendbaren Programm. In Bash sollten Sie Variablenexpansionen in Anführungszeichen setzen, Eingaben validieren und den Beendigungsstatus prüfen, während Sie ein kleines Skript erstellen und testen.

Diese Lektion erstellt ein erstes Programm, das in einer Datei gespeichert wird. Überprüfen Sie den Shell-Ausführungsfluss für Variablen und Operatoren sowie Bash-Fehler und sichere Dateioperationen für Fehler, Pfad- und Nebenläufigkeitsgrenzen.

Wählen Sie Bash explizit und bereiten Sie einen Arbeitsbereich vor

Diese Lektion richtet sich an Bash unter Ubuntu und Rocky Linux. Funktionen wie [[ ... ]] und Arrays sind nicht auf jedem sh portabel, daher sollten Sie kein Bash-Skript mit sh script.sh ausführen. Überprüfen Sie bash --version, arbeiten Sie in einem neuen Verzeichnis und speichern Sie Shell-Dateien mit LF-Zeilenenden.

lab=$(mktemp -d "$HOME/linux-script-lab.XXXXXX")
cd "$lab"
mkdir "sample files"
printf "one\n" > "sample files/alpha.txt"
printf "two\n" > "sample files/beta.txt"

Erstellen Sie das komplette ausführbare Skript

Der folgende Block erstellt list-files.sh im aktuellen Verzeichnis. Das Skript validiert ein Verzeichnisargument und gibt dessen reguläre Dateinamen aus. Es verändert die Dateien nicht, was es geeignet macht, um mit Variablen, Verzweigungen und Schleifen zu experimentieren.

cat > list-files.sh <<'EOF'
#!/usr/bin/env bash
if (( $# != 1 )); then
  printf "Usage: %s DIRECTORY\n" "$0" >&2
  exit 2
fi
directory=$1
if [[ ! -d "$directory" ]]; then
  printf "Not a directory: %s\n" "$directory" >&2
  exit 1
fi
count=0
for path in "$directory"/*; do
  [[ -f "$path" ]] || continue
  printf "%s\n" "${path##*/}"
  count=$((count + 1))
done
printf "files=%s\n" "$count"
EOF
bash -n list-files.sh
bash list-files.sh "sample files"

Erwarten Sie alpha.txt, beta.txt und files=2; die Reihenfolge der Namen kann von der Regionseinstellung abhängen. bash -n überprüft nur die Syntax, nicht die Laufzeitpfade oder Berechtigungen. Die anfängliche #!-Zeile ist ein Shebang, der einen Interpreter auswählt, kein Shell-Prompt.

Verstehen Sie Variablen und Anführungszeichen

Zuweisung verwendet keine Leerzeichen um das Gleichheitszeichen: directory=$1. Das Setzen von Anführungszeichen bei "$directory" übergibt einen Pfad mit Leerzeichen als ein Argument. Einfache Anführungszeichen unterdrücken in der Regel die Erweiterung; doppelte Anführungszeichen erlauben die Parametererweiterung, verhindern jedoch Wortaufteilung und Pfaderweiterung. Es ist nicht notwendig, Benutzereingaben mit eval neu zu interpretieren.

In "$directory"/* ist der Verzeichnisanteil geschützt, während das Sternchen die Pfaderweiterung ausführt. Unter den Standard-Bash-Einstellungen kann ein nicht übereinstimmendes Muster als Literal bestehen bleiben, sodass der -f Test es überspringt. Das Muster schließt Punktdateien aus und durchsucht nicht rekursiv. Ein symbolischer Link auf eine reguläre Datei kann -f erfüllen.

Argumente, Bedingungen, Schleifen und Status lesen

Syntax Bedeutung
$# / $1 Argumentanzahl / erstes Argument
[[ -d ... ]] Testen, ob das Ziel ein Verzeichnis ist
for ...; do ...; done Einen Block auf jedes erweiterte Element anwenden
${path##*/} Entferne das Präfix bis zum letzten Schrägstrich
exit 0 / 1 / 2 Erfolg / ungültiges Ziel / Benutzungsfehler in diesem Beispiel

Wenn das finale printf erfolgreich ist, beendet das Skript mit Status 0. Die Bedeutungen von 1 und 2 sind Konventionen, die von diesem Skript gewählt wurden, nicht eine universelle Klassifikation für jeden Befehl. $? enthält den unmittelbar vorhergehenden Status des Befehls, prüfen Sie ihn daher, bevor ein anderer Befehl ausgeführt wird.

bash list-files.sh
printf "exit=%s\n" "$?"
bash list-files.sh missing-directory
printf "exit=%s\n" "$?"
chmod u+x list-files.sh
./list-files.sh "sample files"

Jeweils nur eine Bedingung ändern

  1. Führen Sie das Skript gegen das ursprüngliche Verzeichnis aus und bestätigen Sie eine Anzahl von 2.
  2. Fügen Sie gamma.txt hinzu und bestätigen Sie, dass sich die Anzahl auf 3 ändert.
  3. Entfernen Sie nur die hinzugefügte Datei und bestätigen Sie, dass die Anzahl wieder auf 2 zurückgeht.
  4. Testen Sie ein leeres Verzeichnis auf files=0 und einen fehlenden Pfad auf einen Fehler und Status 1.

Wenn Fehler bash\r oder ^M nach der Bearbeitung in Windows erwähnen, überprüfen Sie die Zeilenenden. bash FILE liest das Skript direkt; ./FILE benötigt Ausführungsberechtigung und eine gültige Interpreter-Zeile. Überprüfen Sie Ihr aktuelles Verzeichnis, bevor Sie das Labor aufräumen.

Wenn ein Windows-Editor CRLF anzeigt, ändern Sie es zu LF und speichern Sie. In VS Code wählen Sie CRLF → LF in der Statusleiste. Mit GNU sed erstellt das Folgende auch ein Backup und konvertiert list-files.sh dieser Übung.

cp -i -- list-files.sh list-files.sh.crlf-backup
sed -i 's/\r$//' list-files.sh
bash -n list-files.sh
bash list-files.sh "sample files"

Eine Syntaxprüfung sollte mit 0 ohne Ausgabe beendet werden; mit nur den ursprünglichen zwei Beispieldateien erwarten Sie files=2. Um die Konvertierung rückgängig zu machen, überprüfen Sie das Backup und stellen es mit cp -i -- list-files.sh.crlf-backup list-files.sh wieder her.

Offizielle Referenzen