Bash - Teil 1
„Es gibt Dinge, die wir lernen müssen, bevor wir sie tun können. Und wir lernen sie, indem wir sie tun." (Aristoteles)
Die in Betriebssysteme aus der Vogelperspektive angesprochenen Punkte werden im Folgenden in der Praxis an Hand des Betriebssystems Linux in Detail erläutert. Dabei steht der praktische Bezug im Vordergrund. Wir verwenden dazu die Bash-Shell für ein interaktives Arbeiten. Linux ist ein unixoides Betriebsystem, d.h. die wesentlichen Konzepte sind auch für andere Unix-Betriebsysteme gültig.
In Unix ist das Dateisystem als Baum organisiert:
/
) oben dargestellt. Typische Linux Dateisystem-Struktur:
Dabei dienen die Ordner (directories) folgendem Zweck:
/
: Wurzel-Verzeichnis (root-Verzeichnis)./bin
: für ausführbare (Standard-)Kommando-Programme (binaries), wie ls
oder cp
./boot
: Für Dateien, die beim Booten benötigt werden./dev
: beinhaltet die Schnittstellen zu devices (Geräte)/etc
: für systemweite Konfigurationsdateien und Systemdatenbanken./home
: Heimatverzeichnis für User, d.h. darunter werden die User-Verzeichnisse angelegt./lib
: für System-Bibliotheken (libraries) und kritische Dateien, wie Kernel-Module und Geräte-Treiber (device driver)/media
: Standard mount point für entfernbare Datenträger, wie USB-Sticks und Medien-Abspielgeräte./mnt
: Dieses Verzeichnis enthält die Dateisystem mount points. /proc
: Virtuelles Dateisystem, in dem Informationen über Prozesse als Dateien angezeigt werden./root
: Heimatverzeichnis des Systemadministrators (Superuser, root). /tmp
: Platz für temporäre Dateien, diese werden typischerweise beim Systemstart gelöscht./usr
: für ausführbare Dateien, Bibliotheken und geteilte Resourcen, die nicht systemkritisch sind. /usr/bin
: für binäre, ausführbare Programme, die nicht in /bin
oder /sbin
liegen, z.B. das Programm which
./usr/include
: Header-Dateien für die Entwicklung (insbesondere für #include
Direktiven zum Übersetzen von C/C++ Quellcode)/usr/lib
: Bibliotheken und Datendateien, die von Programmen im /usr
-Verzeichnis (und woanders) benötigt werden./var
steht für "variable". Ein Verzeichnis für Dateien, die sich schnell ändern, z.B. Emails oder Prozess-ID Lockdateien./var/log
für Systemlogdateien./var/spool
Spool-Verzeichnis, z.B. für print-Jobs/var/tmp
Temporäres Verzeichnis für Dateien, die zwischen Systemstarts erhalten bleiben.Beachten Sie, dass hier ausgehend vom Wurzelverzeichnis die (weiteren) Verzeichnisse durch einen Slash /
getrennt werden.
ls /
"Graphical user interfaces make easy task easy, while command line interfaces make difficult tasks possible."
aus dem Buch von W. Shotts "The Linux Command Line".
Öffnen Sie ein Terminal für die Übungen/Aufgaben. Wie dies in der Regel geht, finden Sie z.B. hier: https://wiki.ubuntuusers.de/Terminal/
Sie sehen dann einen Eigabe-Prompt, der z.B. so aussieht:
praktische_informatik:~$
~
(tilde) steht als Abkürzung für Ihr Home-Verzeichnis. $
(dollar) zeigt an, dass Sie nicht Superuser (Nutzer mit Administratorenrechte) sind. Falls Sie als Superuser eingeloggt sind, steht hier typischerweise ein #
(hash). Der Prompt lässt sich aber individualisieren (wird später behandelt).Wir arbeiten mit der bash
(bourne again shell), die auch eine Ausführungsumgebung für die bash-Programmiersprache ist. Später werden wir mit der Bash auch richtig programmieren.
Lesen Sie ggf. das Kapitel 1.2 Was ist eine Shell? aus dem Buch Shell-Programmierung von Jürgen Wolf oder 1.2 What is a shell? aus dem Bash Reference Manual.
Lesen Sie außerdem die ersten beiden Abschnitte des Paragraphen 1.2. Bash Reference Manual.
Hinweis: Sie sind immer mit einem Benutzer/innen-Namen angemeldet. Dieser identifiziert eine/n Nutzer/in eindeutig.
Beispiel für ein Kommando (siehe unten):
date
Probieren Sie es aus. Gegen Sie das Kommando date
in Ihrer Kommandozeilenumgebung ein und drücken Sie die Eingabe-Taste (enter).
Mittels bash --version
erhalten Sie die Versionnummer Ihrer Bash:
bash --version
Auf der Kommandozeile können Sie folgende Tastenkürzel verwenden:
Mit Hilfe der Tabulator-Taste können Sie Befehle, Dateipfade etc. vervollständigen. Das ist in der Praxis ein sehr wichtiges Feature (Funktion) insbesondere für (längere) Dateipfade. Eine genaue Beschreibung finden Sie in 2.3 von https://www.selflinux.org/selflinux/html/bash_basic02.html#d27e93
Beachten Sie, dass das Kopieren und Einfügen mit Strg + v und Strg + c nicht funktioniert. Strg + c dient dem Abbruch von im Vordergund laufenden Programmen. Mehr dazu später (unter Senden von Signalen an Prozesse).
Im Gnome-Terminal funktioniert dies aber in Kombination mit der Shift-Taste, z.B. Strg + Shift + c für Kopieren.
ls
¶Mit dem Kommando ls
kann man sich die Inhalte von Ordnern ansehen, z.B. ls /bin
.
ls
steht dabei für list directory content. Hier wird dabei der absolute Pfad zu dem Verzeichnis (directory) verwendet. Der absolute Pfad startet immer mit dem Wurzelverzechnis /
(Zeichen slash).
Sie werden feststellen, dass Sie als "normaler" User nicht alles sehen können (auf Grund des Rechtesystems - siehe unten),
z.B. führt ls /root
zur Fehlermeldung
`ls: cannot open directory '/root': Permission denied`.
ls /
Mit ls
und date
haben Sie schon zwei Kommandos kennengelernt.
Kommandos können neben den Dateiargumenten auch mit Optionen ausgeführt werden. Die typische Struktur eines Kommandos ist:
<commandname> -<option1> -<option2> ... --<longoption1> ... <file1> <file2>
-
, z.B. ls -a
(alle auch versteckte Dateien anzeigen - wird später erläutert)--
, z.B. ls --all
Geben Sie die Befehle beim Durcharbeiten dieser Einführung immer auch selbst ein. Variieren Sie dabei die Befehle/Kommandos und probieren so Varianten aus, Nur durch pratisches Anwenden, Probieren und Herumspielen lernen Sie den Umgang mit der Komandozeile wirklich. Klavierspielen lernt man auch nicht durch Zuhören.
Hilfe zu Befehlen kann man auf der Kommandozeile unter anderem
mit man
bzw. help
erhalten.
Welches von den beiden die Hilfe anzeigt, hängt vom Typen des Kommandos ab.
Dies können Sie über type
ermitteln.
type echo
Bei shell builtins und keywords gibt es eine Hilfe mit help
.
Sehen Sie sich die Hilfe zu echo
an, d.h. geben Sie help echo
auf der Kommandozeile ein.
Sonst dient in der Regel das Kommando man
(Manual) dazu die Manpage (Hilfeseite) anzuzeigen.
Sehen Sie sich die Hilfe zu cp
an, d.h. geben Sie man cp
auf der Kommandozeile ein.
Wenn die Manpage angezeigt wird, können Sie mit der Taste h (für help) sich die Tasten für die Navigation/Suche etc. anzeigen lassen. Mit ↑ bzw. ↓ können Sie nach oben bzw. unten Zeile für Zeile "blättern".
Probieren Sie es aus. Wie können Sie die Manpage wieder verlassen? Hinweis: mit der Taste h erhalten Sie diese Information.
Neben help
und man
gibt es auch noch info
.
Zum Unterschied zwischen help
, man
und info
(
aus https://unix.stackexchange.com/questions/19451/difference-between-help-info-and-man-command):
help
is a built-in command in the bash shell (and that shell only) that documents some of the builtin commands and keywords of that shell. That's an internal documentation system of that shell.man
is a system-wide documentation system that provides short reference manuals (pages) for individual commands, API functions, concepts, configuration file syntax, file formats organised in sections (1 for user commands, 2 for system calls...). That's the traditional Unix documentation system.info
is another documentation system originating in the GNU project. It's hypertext with links (predates the web). An info manual is like a digital book with a concept of table of contents and (searchable) index which helps locating the information.Oft haben die Kommandos auch eine Option für eine kurze Hilfe, z.B. ls --help
Weitere Information finden Sie z.B. in https://wiki.ubuntuusers.de/Bash/Hilfe/
--help
), z.B. ls --help
.apropos
lässt sich anzeigen, in welchen Manpages ein Begriff vorkommt:apropos hardware
Mittels whatis
bekommt man eine einzeilige Beschreibung samt Manpage Nummern, z.B.:
whatis passwd
# das geht auch :-)
whatis whatis
which
¶Kommandos sind oft auch Programme, die im Dateisystem liegen. In welchen Verzeichnissen solche Kommandos gesucht werden, wird in der Umgebungsvariable PATH
angegeben (wird später ausführlich behandelt). Mit which
kann man (viele) Kommandos lokalisieren (locate a command).
which ls
Das Programm ls
liegt im Verzeichnis /bin
.
Probieren Sie folgenden Befehle und sehen Sie sich die Manpages zur Erklärung an.
date
cal
ncal -e
?df
free
Erinnerung: Mit der Taste h erhalten Sie die Navigationstasten in der Manpage, wie z.B. q zum Beenden der Anzeige der Manpage:
Sehen Sie sich die Hilfe zu ls
und auch zu man
an und beantworten Sie die Fragen:
man ls
. Hinweis: Unter dem Punkt SYNOPSIS
wird angegeben, wie die Argumente angeordnet werden können. Die eckigen Klammern [ .. ]
geben dabei an, ob Argumente optional sind. Unter DESCRIPTION
werden hier auch die Schalterargumente erklärt.-l
?Sehen Sie auch die tldr-Beschreibung von ls
an: https://tldr.ostera.io/ls
man man
(auch man
hat eine Manpage)
5
in man 5 passwd
? Was passiert dagegen, wenn man nur man passwd
eingibt?whatis passwd
.In der man
-Page zu ls
erfährt man zum Beispiel auch, dass das Kommando ls
eine Option -l
(für long, d.h. ausführlich) hat:
ls -l /usr/ /b?n/c* # Das "?" und "*" und die lange Ausgabe werden später erklärt
Dabei haben wir uns zwei Verzeichnisse angesehen und sogenannte Wildcards verwendet.
Wildcards sind Platzhalter für andere Zeichen in den Dateinamen (Verzeichnissen):
*
(star oder asterix) steht für eine beliebige Folge von Zeichen?
steht für genau ein Zeichen[ ]
(square backets) kann man genau die Zeichen bestimmen, die an der Stelle vorkommen sollen, z.B. ls /bin/c[ph]*
!
(bang) oder einem ^
(caret) als erstes Zeichen in den eckigen Klammern
kann man genau die Zeichen bestimmen, die an der nicht Stelle vorkommen sollen,
z.B. ls /bin/c[!ph]*
bzw. ls /bin/c[^ph]*
.Mit geschweiften Klammern kann man Alternativen angeben.
ls *.{txt,sh}
entspricht ls *.txt *.sh
. Aber es lassen sich auch Bereiche (brace expansion) angeben (siehe weiter unten).
Beispiele:
echo /*in/c[ph]*
ls /b?n/c[!ph]*
ls /bin/c{at,ha}*
Beachten Sie: Wildcards werden von der Shell zu Dateinamen aufgelöst (expandiert), d.h. die Kommandos (Programme) sehen nicht direkt die Wildcards, sondern schon die Expandierung, die die Shell vorgenommen hat.
Dies kann man mit dem echo
Kommando verdeutlichen. Mit echo
kann man eine Zeile Text ausgegeben (display a line of text). Ohne eine weitere Angabe wird der dem Kommndo echo
folgende Text auf der sogenannten Standardausgabe (stdout) ausgegeben.
Zur besseren Lesbarkeit verwenden wir hier zudem Quoting mit doppelten Anführungszeichen "
(double quote). Das Quoting wird später genauer erläutert.
echo "Hallo Welt!"
whatis echo
Hier wird das Glob-Muster expandiert, bevor es zum echo
Befehl weitergeleitet wird:
echo /bin/c[ah]*
Das Gleiche passiert auch bei den anderen Befehlen, wie bei ls
.
Beachte: (Einfache und doppelte) Anführungszeichen verhindern das Expandieren durch das Globbing:
echo /bin/c[a,h]*
echo "/bin/c[a,h]*"
echo '/bin/c[a,h]*'
Mit geschweiften Klammern { }
(braces, curly backets) lassen sich Bereiche angeben, die zu einer Sequenz expandiert werden:
# So funktioniert die brace expansion:
echo {1..11}
echo {20..10..2} # Rückwärts mit Schrittweite 2
echo {z..a..3} # Rückwärts mit Schrittweite 3
echo {a{1,2},b{3..6}} # verschachtelt
# Beachte, falls zu einem (expandierten) Muster keine Dateien gefunden werden,
# wird das "*" an den Befehl (hier echo) weitergegeben.
echo /bin/c{a..k}*
Probieren Sie ls /bin/c{a..k}*
aus. Erklären Sie, warum es dabei Fehlermeldungen gibt?
[:alnum:]
: Trifft auf jedes alphanumerisches Zeichen zu.[:alpha:]
: Trifft auf jedes alphabetisches Zeichen zu.[:digit:]
: Trifft auf jede Zahl zu.[:upper:]
: Trifft auf jeden Großbuchstaben zu.[:lower:]
: Trifft auf jeden Kleinbuchstaben zu.Solche Character classes müssen innerhalb weiterer [ .. ]
(Bedeutung der eckigen Klammern siehe oben!) eingesetzt werden!
Beispiel: Alle Dateien mit Endung (.txt
), die mit einem Kleinbuchstaben beginnen:
echo [[:lower:]]*.txt
# Beachte: Wenn das zweite Klammerpaar fehlt, werden die Zeichen einfach direkt interpretiert, z.B:
# Dieses Glob-Muster trifft auf alle Dateien zu, die mit ":", "l", "o", "w", e" oder "r" beginnen
# und nicht auf ein beliebigen Kleinbuchstaben!
echo [:lower:]*.txt
Wir können einen Pfad (path) als Weg von einem Verzeichnis zu einem anderen definieren. So können wir zwei Arten von Pfaden unterscheiden
Der Zweck von Pfaden ist es also ein Verzeichnis/Datei (im Verzeichnisbaum) zu identifizieren.
Am ersten Zeichen des Pfads kann man erkennen, ob es ein absoluter oder eine relaiver Pfad ist:
/
. Aber die Dateiangabe ~/.emacs
ist z.B. auch ein absoluter Pfad, da ~
eine Abkürzung für /home/<username>/.emacs
ist. Absolute Pfade haben Sie schon kennengelernt, so können Sie sich den Inhalt des Verzeichnis /usr/bin
(absoluter Pfad!) mit ls /usr/bin
anzeigen.
Das ist das Verzeichnis, in dem Sie sich mit der Kommandozeile (oder einem Prozess (ausgeführtes Programm) - Prozesse werden später erklärt) im Dateisystem befinden. Das Arbeitsverzeichnis bekommen Sie mit dem Kommando pwd
(print name of current/working directory) angezeigt.
So könnte man z.B. über das Kommando pwd
folgendes erhalten:
> pwd
/home/christian/Lehre/praktischeInformatik/bash_basics
Will man aus diesem Arbeitsverzeichnis das Verzeichnis (/usr/bin
) mit einem relativen Pfad identifizieren, muss man im Dateibaum fünf Ebenen (Verzeichnisse) absteigen. Um eine Ebene abzusteigen verwendet man zwei Punkte ..
, d.h. mit ls ../../../../../usr/bin
kann man den Inhalt von /usr/bin
mittels eines relativen Pfades anzeigen.
Neben dem Doppelpunkt gibt es noch den einfache Punkt .
, der für das Arbeitsverzeichnis steht. So könnte man sich auch über ls .
oder (hier auch) überkompliziert mittels ls ./../bash_basics/.
den Inhalt des Arbeitsverzeichnis anzeigen.
Beachten Sie, dass das Kommando ls
als Standard-Pfad das Arbeitsverzeichnis verwendet. So kann man beispielsweise alle Dateien im aktuellen Arbeitsverzeichnis einfacher nur über ls
erhalten.
Relative Pfade sind kürzer als absolute Pfade, wenn man z.B. ein Unterverzeichnis adressieren will.
Beispielsweise kann man im Arbeitsverzeichnis /home/christian/Lehre/praktischeInformatik
den Inhalt des Unterverzeichnis bash_basics
mit ls ./bash_basics
oder einfacher mit nur ls bash_basics
anzeigen.
Das Heimatverzeichnis des Nutzers / der Nutzerin lässt sich mit ~
(Tilde-Zeichen) referenzieren. Ist dies (wie hier) /home/christian
, kann man mit ls ~/Lehre
z.B. /home/christian/Lehre
erreichen. Jede/r Nutzer/in hat dabei ein eigenes Heimatverzeichnis in der Regel unter /home/
.
Zusammengefasst:
.
(dot) steht für das aktuelle Arbeitsverzeichnis..
steigt eine Ebene im Dateisystem ab, d.h. hin zur Wurzel des Dateisystems.~
steht für das Heimatverzeichnis (home directory) des Benutzers / der Benutzerin.Hinweis: cp
ohne weitere Angabe ist identisch mit cp ~
.
cd
¶Mit Hilfe des Kommando cd
(change directory) kann man das Arbeitsverzeichnis wechseln. Hier kann man wieder absolute und relative Pfade angeben, z.B.
cd work
- Wechseln in das Unterverzeichnis work
(relativer Pfad!)
type cd
Bewegen Sie sich im Verzeichnisbaum mit cd
auf und abwärts (im Verzeichnisbaum). Lassen sich sich mit ls
den Inhalt (inkl. Unterverzeichnisse) anzeigen. Mit pwd
können Sie jeweils sehen, in welchem Verzeichnis Sie sich befinden.
Sind die Namen der Dateien (inkl. Verzeichnisse) case-sensitiv, d.h. senstiv auf Groß- und Kleinschreibung?
Nutzen Sie die man
page von ls
, um folgende Fragen zu beantworten?
.
beginnen. Diese werden standardmäßig nicht angezeigt..py
(typischer Name für Python-Quellcodedateien) in einem Verzeichnis sortiert nach der Größe anzeigen? Hinweis: Nutzen Sie den Schalter -l
(long listing format), um Ihre Lösung zu überprüfen.
Bisher haben wir (in der Terminologie) Verzeichnisse und Dateien unterschieden.
In Unix/Linux ist aber der Begriff file (Datei) weiter gefasst. So werden Verzeichnisse auch unter Dateien subsumiert, d.h. Datei ist der Oberbegriff und Verzeichnisse sind auch Dateien.
Es gibt aber auch noch weitere Dateien, Gerätedateien (device file) oder symbolische Links (später).
-
(dargestellt z.B. als erstes Symbol in der Langdarstellung von ls -l
)d
l
b
(z.B. Festplatten)c
(z.B. serielle Schnittstellen)p
s
Das Konzept Hardware (Gerätedateien device files) und Sockets auch über Dateien anzusteuern, entspricht dem Unix-Prinzip "Alles ist eine Datei" (everything is a file).
Probieren Sie z.B. folgende Kommandos und achten Sie bei der Ausgabe auf das erste Symbol in jeder Zeile.
ls -l /dev/
ls /run/systemd/journal/dev-log -l
Das Konzept lässt sich folgendermaßen zusammenfassen: "Alles" ist in einem Linux/Unix System eine Datei (file),
/etc/passwd
abgelegt./etc/group
Das Kommando ls
ist in einer Datei gleichen Namens im Ordner /bin
abgelegt.
Wir können uns die ausführliche Information (Option -l
für long) zu der Datei ls
(mit Hilfe des Kommandos ls
) anzeigen lassen:
ls /bin/ls -l
zum ersten Teil -rwxr-xr-x
:
-
zeigt an, dass es sich um eine nomale Datei handelt (siehe oben).r
ead, w
rite und ex
ecute r
, w
und x
stehen, wenn die Rechte für User, die Gruppe oder alle Anderen erfüllt sind. Ein -
steht, wenn das Lese-, Schreib-, oder Ausführungsrecht nicht gesetzt ist.ls
ist ein ausführbares Programm).Die folgende 1
steht für die Anzahl der Hard-Links, die auf die Datei zeigen (Erklärung später).
Das erste root
seht für den/die direkte/n Besitzer/in der Datei. Das zweite root
für den Gruppennamen, dem die Datei zugeordnet ist.
Die 133792
ist die Größe der Datei in Byte. Wird mit der Option -h
einfacher lesbar.
Dann folgt das Erstellungs/Modifikationsdatum der Datei.
Ganz am Ende steht der Name der Datei.
Für das Ändern der Rechte benutzt man das Kommando chmod
(change file mode bits).
Zuerst erstellen wir eine Text-Datei (im laufenden Arbeitsverzeichnis) mit dem Namen longlist
. Der Text in der Datei soll dabei "ls -l" sein. Dies können wir durch folgenden Befehl erreichen:
echo "ls -l" > longlist
Mit Hilfe des Pfeils >
haben wird die Standardausgabe in eine Text-Datei mit Namen "longlist" umgeleitet. Dabei wurde die Datei longlist
erstellt. Wenn sie vorhanden gewesen wäre, hätten wir sie überschrieben.
Die Standardausgabe und das "Umleiten" wird später noch genau erläutert.
Jetzt überprüfen wir, ob die Datei wirklich geschrieben wurde:
ls -l l* # das Globmuster "l*" trifft auf alle Dateien zu, die mit einem kleinen l beginnen.
# dump the file - see "man hexdump"
hexdump -b longlist
echo
hexdump -c longlist
Typischerweise wollen wir aber einfach den Textinhalt einer Textdatei ausgeben.
Mit Hilfe der Befehls more
können wir eine Text-Datei seitenweise ausgeben (falls Sie nicht auf eine Seite passt):
more longlist
Jetzt können wir die Rechte der Datei ändern. Da in der Datei ls -l
steht, können wir sie für uns als Owner (u
- user) ausführbar machen:
chmod u+x longlist
Jetzt können wir sie ausführen. Dabei liest der Interpreter der Shell den Inhalt und führt ihn wie bei einer Eingabe auf der Kommandozeile aus:
./longlist
Dabei haben wir den relativen Pfad unserer Datei longlist
explizit angegeben, da ausführbare Dateien nur in speziellen Ordnern gesucht werden (mehr hierzu später).
Durch die explizite Angabe des laufenden Verzeichnis (.
) wird diese aber immer gefunden.
Wir können uns das Recht auf "Ausführung" wieder entziehen:
chmod u-x longlist
Jetzt erhalten wir bei ./longlist
die Fehlermeldung:
bash: ./longlist: Permission denied
Da das Recht auf Ausführung nicht mehr vorhanden ist, erhalten wir jetzt eine Fehlermeldung.
chmod
steht für change file mode bits. Das bits im Namen drückt dabei aus, dass die Rechte auch
über Bits gesetzt werden können:
rwx r-- r--
entspricht z.B. der Bitfolge 111 100 100
. Ein -
(fehlendes Recht) entspricht einer 0
.
Die drei Bitgruppen (mit jeweils drei Bits)
können dabei auch über die korrespondierende Oktalzahl(en) (hier 7 4 4
) gesetzt werden.
chmod 744 longlist # Wir geben uns auch wieder Ausführungsrechte
ls -l longlist
cat longlist
# kann für die Nutzer:in ausgeführt werden
./longlist
Probieren Sie z.B. folgendes:
chmod ug+rwx longlist
chmod o-r longlist
Machen Sie sich die Bedeutung der Kommandos klar.
Welche Rechte erhalten User, Group und Others mit chmod 730
?
Wie könnten Sie eine Datei mit Name long list
erstellen? Wieso sind Dateinamen mit Leerzeichen unpraktisch?
Hinweis: Mittels Escape-Character oder Quoting. Quoting wird später ausführlich beandelt.
Neben den 9 Bits für die Rechte gibt es drei weitere Schutzbits (Sonderechte). Recherchieren Sie deren Bedeutung, z.B.
id
(optional)¶Mit dem Befehl id
erhalten Sie die (wirkliche und die effektive) User- und Group-ID.
Welche User-ID haben Sie im System?
umask
¶Mit chmod
werden die Permissions von bestehenden Dateien geändert.
Mit dem Befehl umask
kann man dagegen die Permissions von den Dateien bestimmen, die (in der Zukunft) angelegt werden. Dabei hat umask
keinen Einfluss auf die zusätzlichen Rechte (weiteren Schutzbits), diese sind standardmäßig immer nicht gesetzt.
help umask
# hier nur anzeigen
umask -S
Ohne den Schalter -S
werden bei der Ausgabe und dem Setzen dagegen die Bits gezeigt die maskiert sind, z.B.
umask # 0002 entspricht 000 000 000 010
000 111 111 111 # permissions ohne weitere Schutzrechte
000 000 010 010 # Maske (umask)
-------------------------------
000 111 101 101 # resultierenden Permissions
entspricht u=rwx, g=rx, o=rx
Der auf der Kommandozeile eigegebene Wert von umask
gilt nur für die laufende Sitzung. Will man dies dauerhaft bewirken, muss man entsprechende Konfigurationsdateien verändern (wird später behandelt).
Dateien können mit dem Kommando rm
(remove) gelöscht werden.
rm longlist
Erstellen Sie eine Datei, entziehen Sie sich das Schreibrecht. Was passiert nun, wenn Sie die Datei löschen wollen.
touch
.Was passiert, wenn man touch
auf eine bestehende Datei anwendet?
Erstellen Sie tausend Dateien nach folgendem Muster my000.txt
, my001.txt
, ... , my999.txt
.
Hinweis:
touch
mit Brace expansion.Mit Hilfe des Kommandos mkdir
(make directories) können Sie Verzeichnisse erstellen, z.B.
mkdir myDir
Erstellen Sie ein Verzeichnis und wechseln Sie in das Verzeichnis (Hinweis: Welcher Befehl dient zum Wechsel des Arbeitsverzeichnis?). Überprüfen Sie, ob Sie wirklich in dem Verzeichnis sind (Hinweis: Mit welchen Kommando bekommen Sie das laufende Verzeichnis angezeigt?). Wechseln Sie wieder in das übergeordnete Verzeichnis. Entziehen Sie allen (User, Gruppe, Andere) das Ausführungsrecht (Welcher Befehl ist dafür nötig?). Können Sie jetzt noch in das Verzeichnis wechseln? Beantworten Sie damit die Frage: "Was bedeutet das Ausführungsrecht bei Verzeichnissen".
Leere Verzeichnisse können Sie mittels rmdir
löschen, z.B.
rmdir neuesVerzeichnis
Erstellen Sie ein Verzeichnis und in diesem eine neue Datei.
rm
(mit Optionen) löschen?
Ist es so möglich ein Verzeichnis inkl. Dateien zu löschen?Hinweis: Seien Sie vorsichtig bei der Benutzung von rm
, insbesondere in Kombination mit Wildcards. Sonst kann es passieren, dass Sie unabsichtlich wichtige Dateien löschen. Die Dateien sind gelöscht und nicht erstmal in einen Papierkorb verschoben.
Wie können Sie ein Verzeichnis samt Inhalt (auch Unterverzeichnisse) löschen? Wie vermeidet man dabei Nachfragen?
Wenn ein Verzeichnis für alle (other) Schreibrechte hat, kann dann ein/e beliebige/r andere/r User eine Datei in dem Verzeichnis löschen?
Beispiel:
$ ls -lrth . mydir2/
.:
total 4,0K
drwxrwxrwx 2 chris chris 4,0K Feb 5 13:44 mydir2
mydir2/:
total 4,0K
-rw-r--r-- 1 chris chris 2 Feb 5 13:44 t.txt
Darf User clara die Datei t.txt
löschen? Falls ja, wie kann das verhindert werden? clara soll aber weiterin das Recht haben, neue Dateien in dem Verzeichnis mydir2 zu schreiben. Hinweis: Die weiteren Schutzbits.
Textdateien können durch folgende Befehle angesehen werden:
more
less
- wie bei den Manpages:Recherchieren Sie die genaue Bedeutung der Befehle. Wie unterscheidet sich die Anzeige? Benutzen Sie beim Ausprobieren eine längere Textdatei, die wir z.B. folgendermaßen erstellen können (wir leiten wieder die Standardausgabe in eine Datei um):
man ls > man_page_of_ls
Mit Hilfe des Befehls cat
kann man auch den Inhalt einer Datei ausgeben:
cat /path/to/datei
Hinweis: Die Option -A
zeigt dabei die Steuerzeichen und das Ende der Zeilen mit einem $
an, etc.
Hier erkennt man, dass es keine Leerzeichen nach den Ländernamen gibt:
cat -A countries.txt
head
und tail
¶Mit dem Kommando tail
kann man sich das Ende einer Datei (Standard: die letzten 10 Zeilen) ansehen.
head
dient dagegen dazu den Beginn (Standard: die ersten 10 Zeilen) anzusehen - mehr zu den Kommandos siehe Manpages.
# mit `-n` kann man die Zeilenzahl bestimmen.
head -n 3 countries.txt
# -2 als Abkürzung für -n 2
tail -2 countries.txt
Hinweis: Mit dem Schalter -f
bei tail
(also tail -f /path/to/file
) können neue Zeilen, die am Ende einer Datei hinzukommen, beobachtet werden. Das kann z.B. hilfreich beim Beobachten von Log-Dateien sein, um neue log-Meldungen zu sehen.
cp
kopieren.mv
verschieben.Wie lautet der Befehl, um alle Dateien mit Endung .txt
vom Verzeichnis myDirA
zum Verzeichnis myDirB
zu verschieben? Nehmen Sie dabei an, dass die beiden Verzeichnisse sich im Unterverzeichnis des laufenden Arbeitsverzeichnis befinden. Erzeugung z.B. mit
mkdir myDirA
mkdir myDirB
touch myDirA/text1.txt myDirA/text2.txt
# Wie lautet der Befehl zum Verschieben?
#clean up
rm -r myDirA
rm -r myDirB
Wie läßt sich ein Verzeichnis zusammen mit den darin befindlichen Dateien verschieben?
(optional)
In einer Inode (ausgesprochen "eye-node") werden alle Informationen über eine Datei bis auf den Namen und die eigentlichen Daten gespeichert. In der Inode stehen also die Meta-Daten über die Dateien. Außerdem werden direkt und indirekt Zeiger (Adressen) auf die Bereiche der eigentlichen Daten gespeichert:
(Bild-)Quelle: http://e2fsprogs.sourceforge.net/ext2intro.html unter dem Punkt "Basic File System Concepts"
Der Abschnitt
Infos
der Inode dient zur Speicherung der Meta-Daten der Datei. Die darunterliegenden Abschnitte beinhalten die direkten und indirekten Zeiger, auf die Blocks mit den eigentlichen Daten der Datei.
In einer Partion werden Inodes eindeutig durch eine ID identifiziert. Partitionen sind zusammenhängende Bereiche auf einem Volume (Blockdatenträger).
Recherchieren Sie die genaue Bedeutung der oben kurz erläuterten Begriffe, wie Volume, Datenblock, Partitionen. Grundlagen zu Festplatten finden Sie z.B. am Anfang von https://access.redhat.com/documentation/de-de/red_hat_enterprise_linux/6/html/installation_guide/ch-partitions-x86
Die ID der Inodes lassen sich zu einer Datei für den Befehl ls
mit der Option -i
(bzw. --inode
Langversion des Schalters) anzeigen:
ls --inode
Ein Verzeichnis besteht aus solchen Paaren von Namen und Inodes. Mit der eindeutigen Inode-ID können dann die Metadaten zu der Datei gefunden werden (z.B. für die Anzeige bei ls -l
). Die Inode-Table ist dabei auch auf dem Block-Device (in einem extra Bereich) gespeichert.
(optional)
In mehreren Inode-Dateinamen Paaren kann die gleiche Inode-ID gesetzt sein. Dann kann auf die Meta-Daten und die Daten der Datei über mehrere Pfade (inkl. Namen der Datei) zugegriffen werden. Der Verweis vom Inode-Dateinamen Paar auf die Inode Table wird als Hard-Link bezeichnet.
Mit ln
kann man solche Links erstellen:
rm countries_second_hard_link.txt
ln countries.txt countries_second_hard_link.txt
ls --inode countries{.t,_s}*
In der Inode (Table) wird als Meta-Information auch die Anzahl der Hard-Links, die auf die Inode zeigen, festgehalten. Dies ist nötig, da beim Löschen einer Datei (d.h. des InodeID-Dateinamen Paares) oft kein Paar mehr auf die Inode zeigt. Dann sollte die Inode in der Inode-Table auch gelöscht werden, um entsprechenden Blockspeicher dort freizugeben.
Die Anzahl der Links auf eine Datei kann man auch mit der Option ls -l
sehen (siehe oben).
Mit stat
erhalten wir noch mehr Info:
stat countries.txt
rm man_page_of_ls
Hinweis: zu jeder Datei gibt es drei verschiedene Zeitangaben( aus https://dextutor.com/difference-between-access-modification-and-change-time-in-linux/)
Access Time: is the time when the file was last accessed or read. For example, using the cat, head or an editor. But remember you did not modify the contents.
Modification Time: is the time when the contents of the file was last modified. For example, you used an editor to add new content or delete some existing content.
Change Time: is the time when the file’s inode has been changed. For example, by changing permissions, ownership, file name, number of hard links.
Wieso hat ein Verzeichnis mehrere Hardlinks (mindestens zwei)?
Machen Sie sich außerdem mit dem Befehl ln
vertraut und erklären Sie auch was ein Softlink ist.
Lesen Sie hierzu z.B. https://wiki.ubuntuusers.de/ln/
Ist es möglich, dass Soft- bzw. Hardlinks auf gleiche Inodes zeigen, die auf unterschiedlichen Partitionen bzw. Festplatten liegen?
whatis ln
Es gibt drei Standarddateien:
Jeder dieser Standarddateien ist ein file descriptor zugeordnet. Ein file descriptor ist eine Zahl, die Unix/Linux einer geöffneten Datei zuordnet, um die Datei zu verwalten. Die file descriptoren sind fest für die Standarddateien:
0
für stdin1
für stdout und2
für stderr.Mit Hilfe von >
wird die Ausgabe umgeleitet.
Diese Weiterleitung (redirection) haben Sie schon kennengelernt:
echo "ls -l" > longlist
Hier können Sie explizit den file descriptor angeben:
# dasselbe Resultat, wie ohne die explizite 1
echo "ls -l" 1> longlist
Hier wird stdout in die Datei longlist
umgeleitet.
Im Allgemeinen gilt:
M>N
# "M" is a file descriptor, which defaults to 1, if not explicitly set.
# "N" is a filename.
# File descriptor "M" is redirect to file "N."
M>&N
# "M" is a file descriptor, which defaults to 1, if not set.
# "N" is another file descriptor.
(aus https://tldp.org/LDP/abs/html/io-redirection.html)
Man kann beispielsweise stderr zu stdout umleiten. Was ist für M>&N
hier M
und N
?
Mit >>
wird die Eingabe an die Datei angehängt, z.B.
echo "Hallo Welt" > greetings
echo -n "Hallo Welt sind Grüße" >> greetings
echo " an die Welt" >> greetings
Mit dem Schalter -n
wird bei echo
verhindert, dass ein newline (\n
) am Ende hinzugefügt wird.
# mit Hilfe von cat lässt sich auch der Inhalt einer Datei auf stdout ausgeben
cat greetings
Hinweis: So kann man den Inhalt einer Datei löschen:
> greetings
Was ist der Unterschied von >
und >>
?
Beispiel:
echo "Das ist eine" > text.txt
echo "Text Datei" > text.txt
vs.
echo "Das ist eine" >> text.txt
echo "Text Datei" >> text.txt
Sie wollen den Standardfehlerkanal zusammen mit der Standardausgabe in die gleiche Datei weiterleiten. Wie geht dies?
<
¶Mit <
kann die Standardeingabe umgeleitet werden:
< countries.txt cat
# die Reichenfolge spielt hier keine Rolle, d.h. folgendes ist äquivalent:
cat < countries.txt
# Anwendung: Unterdrücken des Dateinamens beim Zeilen zählen mit wc
wc -l countries.txt
# ohne Anzeige des Dateinamens:
wc -l < countries.txt
Wie kann man den Inhalt der Datei "greetings.txt" an den Inhalt der Datei gruesse.txt anfügen?
Ändern Sie ls /* > mylog.txt
, sodass die provozierte Fehlermeldungen
ls: cannot open directory '/root': Permission denied
ls: cannot open directory '/lost+found': Permission denied
in der Datei mylog.txt
landen und nicht auf der Standardausgabe:
ls /* > mylog.txt
Gibt es einen Unterschied zwischen diesen beiden Umleitungen, d.h. spielt die Reihenfolge eine Rolle:
ls -yz >> command.log 2>&1
ls -yz 2>&1 >> command.log
Eine genaue Erklärung finden Sie hier: https://catonmat.net/bash-one-liners-explained-part-three
Was ist /dev/null
und wie kann es eingesetzt werden?
Mit Hilfe von Pipes kann man Ein- und Ausgaben von Prozessen verknüpfen.
Prozesse sind "laufende" Programme (mehr dazu später). In diesem Sinne ist z.B. ls
ein Programm, das
gleichzeit mehrfach (quasi parallel) ausgeführt werden kann.
Pipes werden zum Verketten (chaining) von Kommandos, Scripten, Dateien und Programmen verwendet.
Hier wird mittels einer Pipe die Ausgabe (stdout) von ls -l
(erste Befehl) als Eingabe (stdin)
für den zweiten Befehl (wc -l
) übergeben:
# Was wird hier berechnet?
# das -1 bei ls ist eine Eins kein l
ls -1 | wc -l
# dies ist (fast) analog (aber effizienter!)
ls -1 > /tmp/tmp.txt
wc -l < /tmp/tmp.txt
rm /tmp/tmp.txt
Einfache Anwendung:
Wenn beispielsweise eine Ausgabe (zu stdout) zu lang ist, sodass sie nicht in das (Pseudo-)terminal passt, kann man sie zum Kommando less
umleiten und betrachten, wie z.B.
help read | less
Hier als Motivation ein etwas komplexeres Beispiel:
cat greetings | tr -s " " "\n" | sort | uniq | wc -l
Mit cat greetings
wird der Inhalt der Datei "greetings"
ausgelesen und über die Pipe weitergeleitet an tr
.
Mit tr
(translate or delete characters) kann man Zeichen ersetzen. Hier ersetzen wir das Leerzeichen " "
durch ein new line "\n"
.
cat greetings | tr -s " " "\n"
ist äquivalent zu
tr -s " " "\n" < greetings
Dieser Output wird weitergeleitet an sort
(siehe man sort
) zum sortieren.
cat greetings | tr -s " " "\n" | sort
uniq
beseitigt mehrfach vorkommende Zeilen (siehe man uniq
):
cat greetings | tr -s " " "\n" | sort | uniq
wc
(word count) zählt mit der Option -l
(lines) die Zeilen (siehe man wc
).
Somit zählen wir durch die Befehlskette alle unterschiedlichen Wörter der Textdatei greetings
.
cat greetings | tr -s " " "\n" | sort | uniq | wc -l
Die Befehle, die als Kommandozeilen-Werkzeuge für Unix/Linux entwickelt werden, werden typischerweise nach der Unix-Philosophie designt.
"Douglas McIlroy, der Erfinder der Unixpipes, fasste die Philosophie folgendermaßen zusammen:
Gewöhnlich wird das verkürzt zu: „Mache nur eine Sache und mache sie gut.“ "
aus dem Wikipedia-Artikel zur Unix-Philsophie
sudo
vor einem Kommando? Welche uid hat der Superuser?/sys
-Verzeichnis (sys
file system)? (Hinweise u.a. ab 37:00 in den Video in https://missing.csail.mit.edu/2020/course-shell/)/sys/class/backlight
zu setzen, wie in https://missing.csail.mit.edu/2020/course-shell/
beschieben. xargs
¶xargs
erlaubt es den Standard-Input als Argument für einen anderen Befehls einzusetzen.
Beispiel:
which ping | xargs ls -l
Das Kommando which ping
schreibt in stdout "/bin/ping". Die Pipe
sorgt dafür, dass es in der Standardeingabe (stdin) von xargs
landet. xargs
führt den Befehl
ls -la
mit dem weiteren Argument /bin/ping
aus, also effektiv
ls -la /bin/ping
. Dies kann man auch mit dem echo
-Kommando demonstrieren:
which ping | xargs echo ls -la
Manchmal spielt die Reihenfolge der Argumente eine Rolle (z.B. bei cp
).
Diese kann man mit xargs
folgendermaßen ändern:
which ping | xargs -I {} echo ls {} -la
{}
ist ein Platzhalter. Dieser wird mit dem Schalter -I
angegeben.
Der Platzhalter lässt sich der stdin auch mehrfach verwenden. Hier mit x
als Platzhalter.
ls *.txt | xargs -I x echo cp x x.bak
Ein sinnvolles Beispiel für xargs
wäre das Finden aller Dateien mit Endung *.py
(Python-Dateien) in allen Unterverzeichnissen. Dann soll in diesen Dateien die Zeichenkette TODO
gefunden werden, um beispielsweise festzustellen, wo man noch nicht fertig ist. (Das Beispiel wird später verwendet, nachdem das Suchen und Finden von Dateien erläutert wurde.)
find ../../ -name "*.py" | xargs grep TODO
Wird später im Kurs erläutert.
Mehr zu xargs
wieder in der Manpage oder auf https://tldr.ostera.io/xargs.
history
kann man alle zuletzt verwendeten Befehle erhalten.
Wie sie dies gezielt nutzen können, lernen Sie später.Tipp: Wollen Sie, dass Befehle nicht in der Historie landen, so können Sie diesen ein Leerzeichen voranstellen. Dies kann bei "gefährlichen" Befehlen hilfreich sein, da man diese so nicht durch eine schnelle Tastenkombination aus Versehen ausführt.
Eine Datei lässt sich mit dem Programm gzip
komprimieren. Dabei wird der Platzbedarf (in Bytes) der Datei reduziert.
Mit gzip <dateiname>
kann die Datei komprimiert werden. Sie bekommt die Endung .gz
.
mit gunzip <dateiname>.gz
wird die Datei wieder entkomprimiert.
Will man ganze Verzeichnisse (inkl. Unterverzeichnissen) mit den darin befindlichen Dateien archivieren, kann man das Programm tar
verwenden. Dabei wird ein sogenannter Schnappschuss (snapshot) des Verzeichnis / der Verzeichnisse in eine Datei (unkomprimiert) gepackt.
tar cvf archiv.tar <datei1> <datei2> ..
(Dateien können hier auch Verzeichnisse sein, siehe oben)
In der Datei archiv.tar
ist die Archivdatei. Die typische Endung für solche Archive ist .tar
.
c
steht für create, d.h. erzeugen eines Archivs.v
steht für verbose, d.h. es werden auf stdout Meldungen geschrieben, wie z.B. welche Dateien hineingepackt werden. Kann natürlich weggelassen werden.f
steht für file, d.h. danach muss der Name der Archivdatei folgen. Will man auf stdout schreiben, so benutzt man -
als "Namen".Das Archiv kann man mit tar xvf archiv.tar
wieder entpacken. x
steht dabei für extract (extrahieren).
Zuvor sollte man den Befehl testen, d.h. t
statt x
, um zu überprüfen, was in dem Archiv drin ist.
Oft wird die Archivierung mit der Kompression kombiniert, d.h. erst wird archiviert und anschließend komprimiert. Diese Reichenfolge spiegelt sich in der Endung .tar.gz
wider. Mit dem Schalter z
beim tar
-Kommando kann man mit einem Kommando archivieren und komprimieren bzw. entkomprimieren und entpacken, z.B.
tar ztvf archive.tar.gz
, tar zxvf archive.tar.gz
bzw. tar zcvf archive.tar.gz <datei1> <datei2> ..
.
Bemerkung: Dateibrowser, wie z.B. nautilus unter der gnome-Oberfläche, können in der Regel auch durch "Klick" entkomprimieren/entpacken bzw. packen und komprimieren.
Folgende Fragen sollten Sie ohne Nachschlagen beantworten können:
Allgemein:
Inodes und Dateisysteme:
Rechtesystem: