ungekürzte Fassung
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. /var
steht für "variable". Ein Verzeichnis für Dateien, die sich schnell ändern, z.B. Emails oder Prozess-ID Lockdateien./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/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 /
bin etc lib mnt run swapfile usr boot home lib64 opt sbin sys var cdrom initrd.img lost+found proc snap target vmlinuz dev initrd.img.old media root srv tmp vmlinuz.old
"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 (Pseudo-)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
Do 28. Apr 09:48:09 CEST 2022
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
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
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 (Standard).
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 /
bin etc lib mnt run swapfile usr boot home lib64 opt sbin sys var cdrom initrd.img lost+found proc snap target vmlinuz dev initrd.img.old media root srv tmp vmlinuz.old
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
echo is a shell builtin
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
arch (1) - print machine hardware name (same as uname -m) ecryptfs-generate-tpm-key (1) - generate an eCryptfs key for TPM hardware. ethtool (8) - query or control network driver and hardware settings hwdb (7) - Hardware Database irqbalance (1) - distribute hardware interrupts across processors on a ... lshw (1) - list hardware sensors-detect (8) - detect hardware monitoring chips systemd-hwdb (8) - hardware database management tool tc-mqprio (8) - Multiqueue Priority Qdisc (Offloaded Hardware QOS) wdctl (8) - show hardware watchdog status
Mittels whatis
bekommt man eine einzeilige Beschreibung samt Manpage Nummern, z.B.:
whatis passwd
passwd (1) - change user password passwd (1ssl) - compute password hashes passwd (5) - the password file
# das geht auch :-)
whatis whatis
whatis (1) - display one-line manual page descriptions
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), d.h. man kann sich den Pfad zum korrespondierenden Programm anzeigen lassen.
which ls
/bin/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
-rwxr-xr-x 1 root root 35064 Jan 18 2018 /bin/cat -rwxr-xr-x 1 root root 14328 Apr 21 2017 /bin/chacl -rwxr-xr-x 1 root root 63672 Jan 18 2018 /bin/chgrp -rwxr-xr-x 1 root root 59608 Jan 18 2018 /bin/chmod -rwxr-xr-x 1 root root 67768 Jan 18 2018 /bin/chown -rwxr-xr-x 1 root root 10312 Jan 22 2018 /bin/chvt -rwxr-xr-x 1 root root 141528 Jan 18 2018 /bin/cp -rwxr-xr-x 1 root root 157224 Aug 25 2021 /bin/cpio /usr/: total 140 drwxr-xr-x 2 root root 69632 Apr 27 14:09 bin drwxr-xr-x 2 root root 4096 Feb 13 17:22 games drwxr-xr-x 40 root root 16384 Apr 6 08:36 include drwxr-xr-x 159 root root 12288 Apr 17 12:30 lib drwxr-xr-x 3 root root 4096 Jun 4 2020 libexec drwxr-xr-x 11 root root 4096 Dez 23 2020 local drwxr-xr-x 2 root root 12288 Apr 12 08:13 sbin drwxr-xr-x 337 root root 12288 Apr 14 19:40 share drwxr-xr-x 17 root root 4096 Apr 28 07:40 src
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). Da hier die Wildcards auf Dateinamen zielen, spricht man auch von Filename Expansion.
Beispiele:
echo /*in/c[ph]*
/bin/chacl /bin/chgrp /bin/chmod /bin/chown /bin/chvt /bin/cp /bin/cpio /sbin/chcpu
ls /b?n/c[!ph]*
/bin/cat
ls /bin/c{at,ha}*
/bin/cat /bin/chacl
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!"
Hallo Welt!
whatis echo
echo (1) - display a line of text echo (1posix) - write arguments to standard output
Hier wird das Glob-Muster expandiert, bevor es zum echo
Befehl weitergeleitet wird:
echo /bin/c[ah]*
/bin/cat /bin/chacl /bin/chgrp /bin/chmod /bin/chown /bin/chvt
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]*'
/bin/cat /bin/chacl /bin/chgrp /bin/chmod /bin/chown /bin/chvt /bin/c[a,h]* /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
1 2 3 4 5 6 7 8 9 10 11 20 18 16 14 12 10 z w t q n k h e b a1 a2 b3 b4 b5 b6
# Beachte, falls zu einem (expandierten) Muster keine Dateien gefunden werden,
# wird das "*" an den Befehl (hier echo) weitergegeben.
echo /bin/c{a..k}*
/bin/cat /bin/cb* /bin/cc* /bin/cd* /bin/ce* /bin/cf* /bin/cg* /bin/chacl /bin/chgrp /bin/chmod /bin/chown /bin/chvt /bin/ci* /bin/cj* /bin/ck*
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
countries_1.txt countries_2.txt countries_3.txt countries_4.txt countries_second_hard_link.txt countries_soft_link.txt countries.txt f2.txt f.txt inhalt_des_verzeichnisses.txt ls-out.txt mylog.txt rechnernamen.txt stderr.txt text_with_urls.txt t.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
ls-out.txt rechnernamen.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 das Heimatverzeichnis /home/<username>/
ist (tilde-Expansion). 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.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
cd is a shell builtin
Hinweis: cd
ohne weitere Angabe ist identisch mit 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
-rwxr-xr-x 1 root root 133792 Jan 18 2018 /bin/ls
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.
-rw-r--r-- 1 chris chris 35227 Apr 14 2021 lo -rw-r--r-- 1 chris chris 116 Nov 13 19:19 logfile-example_.log -rw-r--r-- 1 chris chris 178 Nov 17 09:51 logfile-example.log -rw-rw-r-- 1 chris chris 6 Apr 28 09:49 longlist -rw-r--r-- 1 chris chris 462 Mär 18 2021 ls-out.txt
# dump the file - see "man hexdump"
hexdump -b longlist
echo
hexdump -c longlist
0000000 154 163 040 055 154 012 0000006 0000000 l s - l \n 0000006
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
ls -l
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. Dies ist (fast) schon ein Shell-Skript. Dabei liest der Interpreter der Shell den Inhalt und führt ihn wie bei einer Eingabe auf der Kommandozeile aus:
./longlist
total 336 -rw-rw-r-- 1 chris chris 20 Nov 7 2021 2021-11-07T13:23:47+01:00_command_errors.log drwxrwxr-x 2 chris chris 4096 Okt 16 2021 bar -rw-rw-r-- 1 chris chris 227 Nov 3 18:09 case-eample.sh -rwxrw-r-- 1 chris chris 242 Nov 3 18:20 case-example.sh -rw-rw-r-- 1 chris chris 23 Mai 12 13:48 countries_1.txt -rw-r--r-- 1 chris chris 100 Dez 6 2021 countries_2.txt -rw-r--r-- 1 chris chris 96 Dez 6 2021 countries_3.txt -rw-r--r-- 1 chris chris 79 Apr 15 2021 countries_3.txt.orig -rw-r--r-- 1 chris chris 359 Apr 15 2021 countries_3.txt.rej -rw-r--r-- 1 chris chris 96 Dez 6 2021 countries_4.txt -rw-r--r-- 1 chris chris 96 Dez 6 2021 countries_4.txt.orig -rw-rw-r-- 1 chris chris 382 Dez 6 2021 countries_4.txt.rej -rw-r--r-- 1 chris chris 250 Apr 15 2021 countries_diff -rw-r--r-- 1 chris chris 382 Dez 6 2021 countries.patch -rw-r--r-- 1 chris chris 250 Apr 15 2021 countries.patch~ -rw-rw-r-- 2 chris chris 80 Mai 12 13:48 countries_second_hard_link.txt lrwxrwxrwx 1 chris chris 13 Nov 3 2021 countries_soft_link.txt -> countries.txt -rw-rw-r-- 2 chris chris 80 Mai 12 13:48 countries.txt -rw-r--r-- 1 chris chris 190 Mai 12 13:49 duplicate_countries -rw-rw-r-- 1 chris chris 760 Nov 17 2021 EOF -rw-rw-r-- 1 chris chris 380 Nov 17 2021 EOFS -rw-r--r-- 1 chris chris 17 Feb 12 2021 example_scipt.sh -rwxr--r-- 1 chris chris 191 Nov 17 2021 example_script.sh -rw-r--r-- 1 chris chris 5 Feb 5 2021 f2.txt -rw-r--r-- 1 chris chris 11 Nov 1 2021 File drwxrwxr-x 2 chris chris 4096 Okt 16 2021 foo -rw-r--r-- 1 chris chris 5 Feb 5 2021 f.txt -rw-rw-r-- 1 chris chris 34 Jun 9 08:48 greetings -rw-r--r-- 1 chris chris 116 Mär 7 2021 grep -rw-r--r-- 1 chris chris 47 Feb 8 2021 gruesse -rwxr--r-- 1 chris chris 37 Nov 2 2021 hw.sh -rwxr--r-- 1 chris chris 86 Feb 18 2021 IFS_demo -rwxr--r-- 1 chris chris 86 Feb 18 2021 IFS_demo~ -rw-r--r-- 1 chris chris 224 Mär 11 2021 inhalt_des_Verzeichnisses -rw-rw-r-- 1 chris chris 818 Nov 13 2021 inhalt_des_verzeichnisses.txt -rw-r--r-- 1 chris chris 35227 Apr 14 2021 lo -rw-r--r-- 1 chris chris 116 Mai 12 13:49 logfile-example_.log -rw-r--r-- 1 chris chris 178 Mai 12 13:48 logfile-example.log -rwxr--r-- 1 chris chris 6 Apr 28 2022 longlist -rw-r--r-- 1 chris chris 462 Mär 18 2021 ls-out.txt drwxrwxr-x 2 chris chris 4096 Apr 28 2022 myDir drwxr-xr-x 3 chris chris 4096 Feb 5 2021 mydir1 -rw-r--r-- 1 chris chris 17353 Okt 12 2021 mylog.txt -rwxrw-r-- 1 chris chris 456 Nov 17 2021 mysignal.py -rwxr--r-- 1 chris chris 58 Mär 30 2021 mytrivialscript.sh -rw------- 1 chris chris 0 Mär 17 2021 nohup.out -rwxr--r-- 1 chris chris 2324 Mär 30 2021 PDFWender.sh -rwxr--r-- 1 chris chris 2326 Mär 30 2021 PDFWender.sh~ -rw-r--r-- 1 chris chris 47 Apr 14 2021 rechnernamen.log -rw-r--r-- 1 chris chris 69 Mai 12 13:48 rechnernamen.txt -rw-r--r-- 1 chris chris 2 Feb 7 2021 result-file -rwxr--r-- 1 chris chris 308 Mär 16 2021 signal-handler.py -rwxr--r-- 1 chris chris 247 Mär 16 2021 signal-handler.py~ -rw-r--r-- 1 chris chris 34371 Feb 8 2021 st -rwx-wx--- 1 chris chris 0 Nov 7 2021 stderr.txt drwxr-xr-x 2 chris chris 4096 Feb 9 2021 test1 -rwxr--r-- 1 chris chris 7 Feb 18 2021 test_script.sh -rw-rw-r-- 1 chris chris 1030 Mai 12 13:56 text_with_urls.txt -rw-rw-r-- 1 chris chris 1015 Nov 8 2021 text_with_urls.txt~ -rw-rw-r-- 1 chris chris 12 Nov 17 2021 tmp -rw-r--r-- 1 chris chris 116 Mär 7 2021 TODO -rw-r--r-- 1 chris chris 7962 Feb 6 2021 t.txt -rw-rw-r-- 1 chris chris 20 Mai 12 13:50 xaa -rw-rw-r-- 1 chris chris 20 Mai 12 13:50 xab -rw-rw-r-- 1 chris chris 20 Mai 12 13:50 xac -rw-rw-r-- 1 chris chris 20 Mai 12 13:50 xad
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
-rwxr--r-- 1 chris chris 6 Apr 28 10:02 longlist
cat longlist
ls -l
# kann für die Nutzer:in ausgeführt werden
./longlist
total 328 -rw-rw-r-- 1 chris chris 20 Nov 7 2021 2021-11-07T13:23:47+01:00_command_errors.log drwxrwxr-x 2 chris chris 4096 Okt 16 2021 bar -rw-rw-r-- 1 chris chris 23 Mai 12 13:48 countries_1.txt -rw-r--r-- 1 chris chris 100 Dez 6 09:44 countries_2.txt -rw-r--r-- 1 chris chris 96 Dez 6 10:13 countries_3.txt -rw-r--r-- 1 chris chris 79 Apr 15 2021 countries_3.txt.orig -rw-r--r-- 1 chris chris 359 Apr 15 2021 countries_3.txt.rej -rw-r--r-- 1 chris chris 96 Dez 6 10:13 countries_4.txt -rw-r--r-- 1 chris chris 96 Dez 6 10:13 countries_4.txt.orig -rw-rw-r-- 1 chris chris 382 Dez 6 10:13 countries_4.txt.rej -rw-r--r-- 1 chris chris 250 Apr 15 2021 countries_diff -rw-r--r-- 1 chris chris 382 Dez 6 10:13 countries.patch -rw-r--r-- 1 chris chris 250 Apr 15 2021 countries.patch~ -rw-rw-r-- 2 chris chris 80 Mai 12 13:48 countries_second_hard_link.txt lrwxrwxrwx 1 chris chris 13 Nov 3 2021 countries_soft_link.txt -> countries.txt -rw-rw-r-- 2 chris chris 80 Mai 12 13:48 countries.txt -rw-r--r-- 1 chris chris 190 Mai 12 13:49 duplicate_countries -rw-rw-r-- 1 chris chris 760 Nov 17 2021 EOF -rw-rw-r-- 1 chris chris 380 Nov 17 2021 EOFS -rw-r--r-- 1 chris chris 17 Feb 12 2021 example_scipt.sh -rwxr--r-- 1 chris chris 191 Nov 17 2021 example_script.sh -rw-r--r-- 1 chris chris 5 Feb 5 2021 f2.txt -rw-r--r-- 1 chris chris 11 Nov 1 2021 File drwxrwxr-x 2 chris chris 4096 Okt 16 2021 foo -rw-r--r-- 1 chris chris 5 Feb 5 2021 f.txt -rw-rw-r-- 1 chris chris 47 Mai 19 09:00 greetings -rw-r--r-- 1 chris chris 116 Mär 7 2021 grep -rw-r--r-- 1 chris chris 47 Feb 8 2021 gruesse -rwxr--r-- 1 chris chris 37 Nov 2 2021 hw.sh -rwxr--r-- 1 chris chris 86 Feb 18 2021 IFS_demo -rwxr--r-- 1 chris chris 86 Feb 18 2021 IFS_demo~ -rw-r--r-- 1 chris chris 224 Mär 11 2021 inhalt_des_Verzeichnisses -rw-rw-r-- 1 chris chris 818 Nov 13 2021 inhalt_des_verzeichnisses.txt -rw-r--r-- 1 chris chris 35227 Apr 14 2021 lo -rw-r--r-- 1 chris chris 116 Mai 12 13:49 logfile-example_.log -rw-r--r-- 1 chris chris 178 Mai 12 13:48 logfile-example.log -rwxr--r-- 1 chris chris 6 Apr 28 10:02 longlist -rw-r--r-- 1 chris chris 462 Mär 18 2021 ls-out.txt drwxrwxr-x 2 chris chris 4096 Apr 28 09:59 myDir drwxr-xr-x 3 chris chris 4096 Feb 5 2021 mydir1 -rw-r--r-- 1 chris chris 17353 Okt 12 2021 mylog.txt -rwxrw-r-- 1 chris chris 456 Nov 17 2021 mysignal.py -rwxr--r-- 1 chris chris 58 Mär 30 2021 mytrivialscript.sh -rw------- 1 chris chris 0 Mär 17 2021 nohup.out -rwxr--r-- 1 chris chris 2324 Mär 30 2021 PDFWender.sh -rwxr--r-- 1 chris chris 2326 Mär 30 2021 PDFWender.sh~ -rw-r--r-- 1 chris chris 47 Apr 14 2021 rechnernamen.log -rw-r--r-- 1 chris chris 69 Mai 12 13:48 rechnernamen.txt -rw-r--r-- 1 chris chris 2 Feb 7 2021 result-file -rwxr--r-- 1 chris chris 308 Mär 16 2021 signal-handler.py -rwxr--r-- 1 chris chris 247 Mär 16 2021 signal-handler.py~ -rw-r--r-- 1 chris chris 34371 Feb 8 2021 st -rwx-wx--- 1 chris chris 0 Nov 7 2021 stderr.txt drwxr-xr-x 2 chris chris 4096 Feb 9 2021 test1 -rwxr--r-- 1 chris chris 7 Feb 18 2021 test_script.sh -rw-rw-r-- 1 chris chris 1030 Mai 12 13:56 text_with_urls.txt -rw-rw-r-- 1 chris chris 1015 Nov 8 2021 text_with_urls.txt~ -rw-rw-r-- 1 chris chris 12 Nov 17 2021 tmp -rw-r--r-- 1 chris chris 116 Mär 7 2021 TODO -rw-r--r-- 1 chris chris 7962 Feb 6 2021 t.txt -rw-rw-r-- 1 chris chris 20 Mai 12 13:50 xaa -rw-rw-r-- 1 chris chris 20 Mai 12 13:50 xab -rw-rw-r-- 1 chris chris 20 Mai 12 13:50 xac -rw-rw-r-- 1 chris chris 20 Mai 12 13:50 xad
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
umask: umask [-p] [-S] [mode] Display or set file mode mask. Sets the user file-creation mask to MODE. If MODE is omitted, prints the current value of the mask. If MODE begins with a digit, it is interpreted as an octal number; otherwise it is a symbolic mode string like that accepted by chmod(1). Options: -p if MODE is omitted, output in a form that may be reused as input -S makes the output symbolic; otherwise an octal number is output Exit Status: Returns success unless MODE is invalid or an invalid option is given.
# hier nur anzeigen
umask -S
u=rwx,g=rwx,o=rx
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
0002
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).
- `whoami`
- `w`
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
France$ Canada$ Burkina Faso$ Democratic Republic of the Congo$ Russia$ New Zealand$
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
France Canada Burkina Faso
# -2 als Abkürzung für -n 2
tail -2 countries.txt
Russia New Zealand
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
15865796 2021-11-07T13:23:47+01:00_command_errors.log 17302817 bar 15866941 countries_1.txt 15867187 countries_2.txt 15867191 countries_3.txt 15867194 countries_3.txt.orig 15867193 countries_3.txt.rej 15866783 countries_4.txt 15866784 countries_4.txt.orig 15866785 countries_4.txt.rej 15867188 countries_diff 15867195 countries.patch 15867190 countries.patch~ 15865794 countries_second_hard_link.txt 15865793 countries_soft_link.txt 15865794 countries.txt 15870091 duplicate_countries 15866774 EOF 15866775 EOFS 15867290 example_scipt.sh 15867289 example_script.sh 15867279 f2.txt 15870040 File 17172117 foo 15867280 f.txt 15866943 greetings 15867104 grep 15867288 gruesse 15870034 hw.sh 15867295 IFS_demo 15867294 IFS_demo~ 15867106 inhalt_des_Verzeichnisses 15865795 inhalt_des_verzeichnisses.txt 15870086 lo 15870089 logfile-example_.log 15870085 logfile-example.log 15867110 ls-out.txt 15859713 man_page_of_ls 17043634 myDir 17302692 mydir1 15867283 mylog.txt 15866776 mysignal.py 15867112 mytrivialscript.sh 15867107 nohup.out 15867114 PDFWender.sh 15867115 PDFWender.sh~ 15870087 rechnernamen.log 15870088 rechnernamen.txt 15867285 result-file 15867108 signal-handler.py 15867109 signal-handler.py~ 15867286 st 15865797 stderr.txt 17302851 test1 15867292 test_script.sh 15865799 text_with_urls.txt 15865801 text_with_urls.txt~ 15866773 tmp 15867105 TODO 15867096 t.txt 15865798 xaa 15865800 xab 15866770 xac 15866771 xad
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}*
15865794 countries_second_hard_link.txt 15865794 countries.txt
15865793 countries_soft_link.txt
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
File: countries.txt Size: 79 Blocks: 8 IO Block: 4096 regular file Device: 10303h/66307d Inode: 15865794 Links: 2 Access: (0664/-rw-rw-r--) Uid: ( 1001/ chris) Gid: ( 1001/ chris) Access: 2022-04-28 10:01:22.886994711 +0200 Modify: 2022-04-28 09:59:24.306990961 +0200 Change: 2022-04-28 10:01:39.446499096 +0200 Birth: -
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?
Es gibt drei Standarddatenströme / Standarddateien:
Jeder dieser Standarddatenströme 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 (stdout) 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
Hallo Welt Hallo Welt sind Grüße an die Welt
Hinweis: So kann man auch 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?
Lesen Sie ggf. https://catonmat.net/bash-one-liners-explained-part-three
<
¶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
6 countries.txt 6
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
64
# dies ist (fast) analog (aber effizienter!)
ls -1 > /tmp/tmp.txt
wc -l < /tmp/tmp.txt
rm /tmp/tmp.txt
64
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
6
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
Hallo Welt Hallo Welt sind Grüße an die Welt
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? /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
-rwsr-xr-x 1 root root 64424 Jun 28 2019 /bin/ping
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
ls -la /bin/ping
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
ls /bin/ping -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
cp countries_1.txt countries_1.txt.bak cp countries_2.txt countries_2.txt.bak cp countries_3.txt countries_3.txt.bak cp countries_4.txt countries_4.txt.bak cp countries_second_hard_link.txt countries_second_hard_link.txt.bak cp countries_soft_link.txt countries_soft_link.txt.bak cp countries.txt countries.txt.bak cp f2.txt f2.txt.bak cp f.txt f.txt.bak cp inhalt_des_verzeichnisses.txt inhalt_des_verzeichnisses.txt.bak cp ls-out.txt ls-out.txt.bak cp mylog.txt mylog.txt.bak cp rechnernamen.txt rechnernamen.txt.bak cp stderr.txt stderr.txt.bak cp text_with_urls.txt text_with_urls.txt.bak cp t.txt t.txt.bak
xargs
¶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