Bash: Ordner und Dateien
Zu den grundlegenden Vorgängen wie anlegen, umbenennen, verschieben und löschen von Ordnern und Dateien siehe den Artikel Dateisystem-Operationen. Siehe auch den Artikel Unix-Dateirechte.
Mit Bash lassen sich vielfältige Operationen an Dateien und Ordnern vornehmen. Viele dieser Operationen sind aber nicht unter allen Umständen möglich. Daher sollte man zunächst die nötigen Eigenschaften mit dem Kommando test überprüfen. Im folgenden Beispiel kommen diese Optionen zum Einsatz:
Da es sich bei den Rückgabewerten von test um Wahrheitswerte handelt, können diese im Terminal nicht direkt angezeigt werden. In Zeile 4 wird demonstriert, wie sie für die Ausgabe in alphanumerische Werte „umgewandelt“ werden können.
echo $HOME # zeigt den Benutzerordner an
echo $PWD # zeigt das Arbeitsverzeichnis an
test -e .bashrc && echo "true" || echo "false" # gelesen: Wenn Datei .bashrc existiert, dann schreibe "true", ansonsten "false".
path="${HOME}/foobar.txt"
path2="${HOME}/foobar2.txt"
if test -e "$path"; then
echo "Objekt $path existiert.";
echo "Dateiname:" $(basename "$path")
echo "Ordner:" $(dirname "$path")
if test -d "$path"; then echo "$path ist ein Ordner."; else echo "$path ist kein Ordner."; fi
if test -f "$path"; then echo "$path ist eine Datei."; else echo "$path ist keine Datei."; fi
if test -L "$path"; then echo "$path ist ein Symlink."; else echo "$path ist kein Symlink."; fi
if test -b "$path"; then echo "$path ist ein Blockgerät."; else echo "$path ist kein Blockgerät."; fi
if test -S "$path"; then echo "$path ist ein Socket."; else echo "$path ist kein Socket."; fi
if test -s "$path"; then echo "$path ist nicht leer."; else echo "$path ist leer."; fi
if test -k "$path"; then echo "$path hat Sticky-Bit gesetzt."; else echo "$path hat Sticky-Bit nicht gesetzt."; fi
if test -r "$path"; then echo "Lesezugriff auf $path besteht."; else echo "Lesezugriff auf $path besteht nicht."; fi
if test -w "$path"; then echo "Schreibzugriff auf $path besteht."; else echo "Schreibzugriff auf $path besteht nicht."; fi
if test -x "$path"; then echo "$path ist ausführbar."; else echo "$path ist nicht ausführbar."; fi
if test -O "$path"; then echo "Der aktuelle Benutzer ist Besitzer von $path."; else echo "Der aktuelle Benutzer ist nicht Besitzer von $path."; fi
if test -G "$path"; then echo "Der aktuelle Benutzer ist in der Gruppe von $path."; else echo "Der aktuelle Benutzer ist nicht in der Gruppe von $path."; fi
if test -e "$path2"; then
if test "$path" -nt "$path2"; then echo "$path ist neuer als $path2."; else echo "$path ist nicht neuer als $path2."; fi
if test "$path" -ot "$path2"; then echo "$path ist älter als $path2."; else echo "$path ist nicht älter als $path2."; fi
fi
else
echo "Objekt $path existiert nicht.";
fi
Möchte man den Inhalt eines Ordners rekursiv (einschließlich der Unterordner) durchsuchen, kann man das auf folgende Weise tun. Dies ist auch ein Beispiel für eine rekursive Funktion, da sie sich in Zeile 5 selbst aufruft.
dirscan() {
echo "${2}$(tput setaf 3)$(tput bold)$(basename "${1}")$(tput sgr0)" # Ordnername
for o in "${1}"/*; do
if test -d "$o"; then
dirscan "$o" "${2} "
else
if [ "$(basename "$o")" != "*" ]; then echo "${2} $(basename "$o")"; fi # Dateiname
fi
done
}
dirscan "$HOME/Dokumente" ""
Objekteigenschaften auslesen
Mithilfe des Kommandos stat lässt sich eine Vielzahl von Eigenschaften eines Ordners bzw. einer Datei abfragen. Darunter so grundlegende wie die Dateigröße, der Besitzer- oder Gruppenname oder die Zugriffsrechte. Außerdem können die Zeitpunkte der letzten Statusänderung ctime, Inhaltsänderung mtime und des letzten Zugriffs atime im ISO-Format oder als Zeitstempel der Unixzeit ausgegeben werden. Für die Platzhalter %w bzw. %W wird ›Entstehungszeit der Datei‹ angegeben, was ich aber nicht bestätigen kann. Stattdessen geben diese Platzhalter mtime an. Möglicherweise bezieht sich diese Eigenschaft auf Objekte in einem Windows-Dateisystem.
file=./foobar.txt
echo $(stat -c '%s' "$file") # Dateigröße in Bytes
echo $(stat -c '%u' "$file") # Besitzer-ID
echo $(stat -c '%U' "$file") # Besitzer
echo $(stat -c '%g' "$file") # Gruppen-ID
echo $(stat -c '%G' "$file") # Gruppe
echo $(stat -c '%a' "$file") # Rechte oktal
echo $(stat -c '%A' "$file") # Rechte rwx
echo $(stat -c '%w' "$file") # Entstehung ISO-Format (mtime)
echo $(stat -c '%W' "$file") # Entstehung Unixzeit (mtime)
echo $(stat -c '%x' "$file") # atime-ISO-Format
echo $(stat -c '%X' "$file") # atime-Unixzeit
echo $(stat -c '%y' "$file") # mtime-ISO-Format
echo $(stat -c '%Y' "$file") # mtime-Unixzeit
echo $(stat -c '%z' "$file") # ctime-ISO-Format
echo $(stat -c '%Z' "$file") # ctime-Unixzeit
Mit dem Kommando gio info (s. auch GIO) können weitere Eigenschaften in der speziellen GIO-Hierarchie ausgelesen werden.
file=./Bilder
gio=$(gio info "$file")
echo "${gio}"
gio=$(gio info "$file" | grep time::) # filtert alle Eigenschaften des time-Zweiges
echo "${gio}"
Mit dem Kommando gio set können diese Eigenschaften auch geändert werden, sofern eine Änderung erlaubt ist. Man beachte den fehlenden Doppelpunkt nach dem Namen der Eigenschaft im Gegensatz zu der Ausgabe von gio info.
# Ausgabe von gio info:
# metadata::nemo-icon-view-zoom-level: 1
gio set "$file" metadata::nemo-icon-view-zoom-level 3
Textdateien schreiben und lesen
Mit den Operatoren > und < ist es möglich, in eine Textdatei zu schreiben bzw. aus ihr zu lesen.
echo "Dies ist die erste Zeile." > ./foobar.txt # erzeugt bzw. leert die Datei und schreibt den String hinein
echo "Dies ist noch eine Zeile." >> ./foobar.txt # fügt den String ans Ende der Datei an
contents=$(< ./foobar.txt) # liest die gesamte Datei ein
echo "$contents"
Mit mapfile kann eine Datei Zeile für Zeile in ein Array geschrieben werden.
mapfile -t < ./foobar.txt
contents=("${MAPFILE[@]}")
for ((i=0; i < ${#contents[@]}; i++)); do
echo "${contents[i]}"
done