bash_1

Kommandozeile, Dateisystem, Rechtesystem und Verketten von Befehlen

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)

Lernziele:

  • Erwerb wesentlicher Grundlagen beim Umgang mit der Kommandozeile
  • Kennenlernen des prinzipiellen Aufbau des Unix/Linux-Dateisystems
  • Kennenlernen des Rechtesystems und der Schutzmechanismen für Dateizugriffe
  • Kennenlernen der Standardein- und Standardausgabe und wie diese umgeleitet werden können.
  • Kennenlernen von ausgewählten Kommandos und wie diese zusammengeschaltet werden können.

Linux

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.

Nebenbemerkung: Mac OS X ist auch ein unixoides Betriebssystem. Die Basis für Mac OS X ist Darwin), welches im Wesentlichen auf Free BSD basiert. Unter Mac OS X ist auch eine Bash-Kommandozeilenumgebung (Programmname: terminal) vorhanden.

Das Linux/Unix Dateisystem

In Unix ist das Dateisystem als Baum organisiert:

  • Ein Baum ist eine Datenstruktur in der Informatik. Dabei wird typischerweise in einer graphischen Darstellung die Wurzel des Baumes (/) oben dargestellt.
  • Keine Laufwerksbuchstaben im Gegensatz zu MS-Windows, da das Betriebsystem Hardwaredetails (hier die verwendeten Laufwerke) verbergen soll.
  • Laufwerke (auch externer Speicher, wie USB-Sticks) werden in den Baum eingehängt (mount).

Typische Linux Dateisystem-Struktur:

image.png

Quelle: https://www.geeksforgeeks.org/unix-file-system/

Ordnerstruktur

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.

In [2]:
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

Kommandozeile / Terminal

"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. 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:~$

  • ~ steht als Abkürzung für Ihr Home-Verzeichnis.
  • $ zeigt an, dass Sie nicht Superuser (Nutzer mit Administratorenrechte) sind. Falls Sie als Superuser eingeloggt sind, steht hier typischerweise ein #. 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.

für Interessierte:

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):

In [3]:
date
Mo 1. Nov 16:48:23 CET 2021

Probieren Sie es aus. Gegen Sie das Kommando date in Ihrer Kommandozeilenumgebung ein und drücken Sie die Eingabe-Taste (enter).

Tastenkürzel für die Kommandozeile

Auf der Kommandozeile können Sie folgende Tastenkürzel verwenden:

  • Die Pfeiltasten ( bzw. ) können Sie die Cursorposition verändern.
    • alternativ mit Strg + b (backward) bzw. Strg + f (forward)
  • Strg + a (oder Pos1) an den Beginn der Zeile spingen.
  • Strg + e (oder Ende) an das Ende der Zeile spingen.
  • Alt + b für ein Wort nach vorne. Worte ergeben sich durch Trennungszeichen, wie z.B. Leerzeichen.
  • Alt + f für ein Wort nach hinten.
  • Backspace für Zeichen rückwärts löschen.
  • Entf für Zeichen vorwärts löschen.
  • Strg + k ab der Cursorposition bis zum Ende der Zeile löschen.
  • Strg + t die beiden vorangehenden Zeichen vertauschen, um z.B. Dreher zu beseitigen.
  • Alt + t die beiden vorangehenden Wörter vertauschen.
  • Strg + l Bildschirm "löschen"

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

Hinweis

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.

Kommando 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 /.

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`.
In [4]:
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

Kommandos

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>

  • Der Kommandoname wird gefolgt von einer Argumentliste (Optionen und Dateipfade).
  • Optionen gibt es meist in zwei Varianten: als kurze Optionen (ein Buchstabe) oder als lange Optionen (entsprechen typscherweise englischen Worten).
    • kurze Optionen haben ein vorangestelltes -, z.B. ls -a (alle auch versteckte Dateien anzeigen - wird später erläutert)
    • lange Optionen haben zwei vorangestellte --, z.B. ls --all
  • Ohne übergebene Dateien/Verzeichnisse wird abhängig vom Kommando meist das laufende Verzeichnis (siehe unten) oder die Standardeingabe als Input verwendet, falls das Kommando dies benötigt.
  • Verzeichnisse gelten dabei auch als Dateien (files) - siehe weiter unten.
  • Die Reihenfolge der Optionen und Dateien kann abhängig vom Kommando (eventuell) geändert werden.

Hinweis

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

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.

In [5]:
type echo
echo is a shell builtin

Bei shell builtins und keywords gibt es eine Hilfe mit help.

Aufgabe

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.

Übung

Aufgabe

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/

  • Manpages sind oft sehr umfangreich und schwer zu lesen. Die Webseite https://tldr.sh/ versucht dies zu adressieren, indem die Befehle mit einfachen Beispielen erläutert werden.
  • Außerdem haben viele Befehle auch ein help-Argument (--help), z.B. ls --help.
  • Mit Hilfe des Kommandos apropos lässt sich anzeigen, in welchen Manpages ein Begriff vorkommt:
In [7]:
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.:

In [8]:
whatis passwd
passwd (1)           - change user password
passwd (1ssl)        - compute password hashes
passwd (5)           - the password file
In [9]:
# das geht auch :-)
whatis whatis
whatis (1)           - display one-line manual page descriptions

Kommando 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).

In [10]:
which ls
/bin/ls

Das Programm ls liegt im Verzeichnis /bin.

Aufgabe

Probieren Sie folgenden Befehle und sehen Sie sich die Manpages zur Erklärung an.

  • date
  • cal
    • Was erhält man mittels 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:

Aufgabe

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.
    • Mit welchem Argument kann man die Sortierung beeinflussen, bzw. wonach kann man sortieren?
    • Wozu dient der Options-Schalter -l?
  • Sehen Sie auch die tldr-Beschreibung von ls an: https://tldr.ostera.io/ls

  • man man (auch man hat eine Manpage)

    • Was bedeutet die 5 in man 5 passwd? Was passiert dagegen, wenn man nur man passwd eingibt?
    • Hinweis: Das erklärt auch die Nummerangabe in Klammern bei 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:

In [11]:
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 12:53 /bin/cpio

/usr/:
total 144
drwxr-xr-x   2 root root 69632 Okt 31 10:54 bin
drwxr-xr-x   2 root root  4096 Sep 17 12:02 config
drwxr-xr-x   2 root root  4096 Feb  1  2021 games
drwxr-xr-x  39 root root 16384 Apr 14  2021 include
drwxr-xr-x 155 root root 12288 Okt 31 10:54 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 Okt 31 10:54 sbin
drwxr-xr-x 326 root root 12288 Jun 17 07:19 share
drwxr-xr-x  14 root root  4096 Nov  1 09:26 src

Dabei haben wir uns zwei Verzeichnisse angesehen und sogenannte Wildcards verwendet.

Hinweis zum Begriff root:

  • root steht zum einen für das Wurzelverzeichnis.
  • Der Superuser wird aber auch als root(-user) bezeichnet.

Wildcards / Datei-Globbing

Wildcards sind Platzhalter für andere Zeichen in den Dateinamen (Verzeichnissen):

  • * steht für eine beliebige Folge von Zeichen
  • ? steht für genau ein Zeichen
  • mit eckigen Klammern kann man genau die Zeichen bestimmen, die an der Stelle vorkommen sollen, z.B. ls /bin/c[ph]*
  • mit eckigen Klammern und einem Aufrufezeichen 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]*

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:

In [12]:
ls /*in/c[ph]*
/bin/chacl  /bin/chmod  /bin/chvt  /bin/cpio
/bin/chgrp  /bin/chown  /bin/cp    /sbin/chcpu
In [13]:
ls /b?n/c[!ph]*
/bin/cat
In [14]:
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. Das Quoting wird später genauer erläutert.

In [15]:
echo "Hallo Welt!"
Hallo Welt!
In [16]:
whatis echo
echo (1)             - display a line of text

Hier wird das Glob-Muster expandiert, bevor es zum echo Befehl weitergeleitet wird:

In [17]:
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: (Doppelte) Anführungszeichen verhindern das Expandieren durch das Globbing:

In [18]:
echo "/bin/c[a,h]*"
/bin/c[a,h]*

Brace expansion

Mit geschweiften Klammern (braces) lassen sich Bereiche angeben, die zu einer Sequenz expandiert werden:

In [19]:
# 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
In [20]:
# 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*

Aufgabe

Probieren Sie ls /bin/c{a..k}* aus. Erklären Sie, warum es dabei Fehlermeldungen gibt?

Character classes
  • [: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 werden innerhalb weiterer [ .. ] (Bedeutung der eckigen Klammern siehe oben!) eingesetzt.

Beispiel: Alle Dateien mit Endung (.txt), die mit einem Kleinbuchstaben beginnen:

In [23]:
echo [[:lower:]]*.txt
countries_2.txt countries_3.txt countries_4.txt countries.txt f2.txt f.txt ls-out.txt mylog.txt rechnernamen.txt t.txt
In [24]:
# Beachte: Dieses Glob-Muster trifft auf alle Dateien zu, die mit ":", "l", "o", "w", e" oder "r" beginnen!
echo [:lower:]*
example_scipt.sh example_script.sh lo logfile-example_.log logfile-example.log longlist ls-out.txt rechnernamen.log rechnernamen.txt result-file

Relative und absolute Pfade

Wir können einen Pfad (path) als Weg von einem Verzeichnis zu einem anderen definieren. So können wir zwei Arten von Pfaden unterscheiden

  • Mit einem absoluten Pfad können wir ein beliebiges Verzeichnis über den Pfad vom Wurzelverzeichnis (root-directory) identifizieren.
  • Ein relativer Pfad bestimmt ein beliebiges Verzeichnis über den Pfad vom aktuellen Arbeitsverzeichnis (current directory - auch Arbeitsverzeichnis working directory) genannt.

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:

  • Absolute Pfade starten immer mit der Wurzel /.
  • Steht die Wurzel nicht am Anfang, so handelt es sich um einen relativen Pfad.

Absolute Pfade haben Sie schon kennengelernt, so können Sie sich den Inhalt des Verzeichnis /usr/bin (absoluter Pfad!) mit ls /usr/bin anzeigen.

Was ist das Arbeitsverzeichnis?

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 lässt sich mit ~ (Tilde-Zeichen) referenzieren. Ist dies (wie hier) /home/christian, kann man mit ls ~/Lehre z.B. /home/christian/Lehre erreichen.

Zusammengefasst:

  • . 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 ~.

Wechseln des Arbeitsverzeichnis mit 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!)

In [25]:
type cd
cd is a shell builtin
Aufgaben

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?

  • Wie lautet der Befehl mit Optionen, um die Dateien eines Verzeichnis nach Ihrer Größe sortiert anzusehen.
  • Wie lautet der Befehl mit Optionen, um die Dateien eines Verzeichnis nach dem Änderungsdatum (neuesten zuletzt) anzusehen?
  • Mit welcher Option erhalten Sie die Größen der Dateien für Menschen einfacher lesbar, wie z.B. 1K 234M 2G?
  • Wie können Sie auch "versteckte Dateien" sehen? Versteckte Dateien sind Dateien, die mit einem . beginnen. Diese werden standardmäßig nicht angezeigt.
  • Wie können Sie alle Dateien mit Endung .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.

Dateitypen

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).

  • normale Dateien (regular or plain files)
    • mit Symbol - (dargestellt z.B. als erstes Symbol in der Langdarstellung von ls -l)
  • Verzeichnisse (directories) d
  • Symbolische Links l
  • Blockorientierte Geräte b
  • Zeichenorientierte Geräte c
  • Named Pipes: p
  • Socket-orientierte Geräte 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).

Mit dem Kommando file (determine file type) können Sie den Typ der Datei genauer ausgeben. Das wird aber nicht einfach durch die Endung ermittelt. Genaueres hierzu finden Sie in der Manpage man file.

Übung

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),

Rechtesystem und Schutzmechanismen

  • User haben einen Nutzernamen (login name or user name) und eine numerische Benutzerkennung user id (uid)
  • User gehören Gruppen an. Gruppen haben einen Gruppennamen (group name) und eine numerische Gruppen-ID (gid)
  • Jede Datei hat eine/n Eigentümer/in und eine Gruppe, die bei der Erzeugung der Datei eingetragen werden. Jede/r Nutzer/in kann seine Dateien explizit eine(m/r) anderen Benutzer/in (bzw. einer anderen Gruppe) "schenken". Jede Datei besitzt 12 voneinander unabhängige Schutzbits.
für Interessierte

Das Kommando ls ist in einer Datei gleichen Namens im Ordner /bin abgelegt.
Wir können uns die ausführliche Information (Option -l) zu der Datei ls (mit Hilfe des Kommandos ls) anzeigen lassen:

In [30]:
ls /bin/ls -l
-rwxr-xr-x 1 root root 133792 Jan 18  2018 /bin/ls
  • zum ersten Teil -rwxr-xr-x:

    • das führende (1-te Zeichen) - zeigt an, dass es sich um eine nomale Datei handelt (siehe oben).
    • Die weiteren neun Zeichen stehen für die vergebenen Zugriffs-Rechte (permissions) (9 Schutzbits). Dabei gehören jeweils drei Zeichen zusammen:
      • 2-4 Zeichen für Owner-Rechte. Jede Datei hat eine/n Owner.
      • 5-7 Zeichen für Gruppe-Rechte (group) und
      • 8-10 Zeichen für die Rechte aller Anderen (other).
      • Die jeweils drei zusammengehörigen Zeichen stehen dabei für read, write und execute 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.
    • In diesem Beispiel kann
      • Owner lesen, schreiben und ausführen (Hinweis ls ist ein ausführbares Programm).
      • die Gruppe und alle anderen können nur lesen und ausführen.
  • 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.

Setzen der Rechte

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:

In [32]:
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:

In [33]:
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   117 Apr 15  2021 logfile-example_.log
-rw-r--r-- 1 chris chris   179 Apr 15  2021 logfile-example.log
-rw-rw-r-- 1 chris chris     6 Nov  1 16:48 longlist
-rw-r--r-- 1 chris chris   462 Mär 18  2021 ls-out.txt
In [34]:
# 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):

In [35]:
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:

In [36]:
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:

In [37]:
./longlist
total 272
drwxrwxr-x 2 chris chris  4096 Okt 16 15:48 bar
-rw-r--r-- 1 chris chris   100 Apr 15  2021 countries_2.txt
-rw-r--r-- 1 chris chris    96 Apr 15  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   100 Apr 15  2021 countries_4.txt
-rw-r--r-- 1 chris chris    96 Apr 15  2021 countries_4.txt.orig
-rw-r--r-- 1 chris chris   382 Apr 15  2021 countries_4.txt.rej
-rw-r--r-- 1 chris chris   250 Apr 15  2021 countries_diff
-rw-r--r-- 1 chris chris   334 Apr 15  2021 countries.patch
-rw-r--r-- 1 chris chris   250 Apr 15  2021 countries.patch~
-rw-r--r-- 1 chris chris    79 Nov  1 16:22 countries.txt
-rw-r--r-- 1 chris chris   188 Apr 15  2021 duplicate_countries
-rw-r--r-- 1 chris chris    17 Feb 12  2021 example_scipt.sh
-rwxr--r-- 1 chris chris   222 Apr 12  2021 example_script.sh
-rw-r--r-- 1 chris chris     5 Feb  5  2021 f2.txt
-rw-r--r-- 1 chris chris    11 Okt 12 14:40 File
drwxrwxr-x 2 chris chris  4096 Okt 16 15:48 foo
-rw-r--r-- 1 chris chris     5 Feb  5  2021 f.txt
-rw-rw-r-- 1 chris chris    11 Okt 19 13:24 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 Apr 12  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-r--r-- 1 chris chris 35227 Apr 14  2021 lo
-rw-r--r-- 1 chris chris   117 Apr 15  2021 logfile-example_.log
-rw-r--r-- 1 chris chris   179 Apr 15  2021 logfile-example.log
-rwxrw-r-- 1 chris chris     6 Nov  1 16:48 longlist
-rw-r--r-- 1 chris chris   462 Mär 18  2021 ls-out.txt
drwxr-xr-x 3 chris chris  4096 Feb  5  2021 mydir1
-rw-r--r-- 1 chris chris 17353 Okt 12 14:39 mylog.txt
-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    70 Apr 15  2021 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
drwxr-xr-x 2 chris chris  4096 Feb  9  2021 test1
-rwxr--r-- 1 chris chris     7 Feb 18  2021 test_script.sh
-rw-r--r-- 1 chris chris    12 Apr 15  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

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:

In [38]:
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.

In [39]:
chmod 744 longlist # Wir geben uns auch wieder Ausführungsrechte
In [40]:
./longlist
total 272
drwxrwxr-x 2 chris chris  4096 Okt 16 15:48 bar
-rw-r--r-- 1 chris chris   100 Apr 15  2021 countries_2.txt
-rw-r--r-- 1 chris chris    96 Apr 15  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   100 Apr 15  2021 countries_4.txt
-rw-r--r-- 1 chris chris    96 Apr 15  2021 countries_4.txt.orig
-rw-r--r-- 1 chris chris   382 Apr 15  2021 countries_4.txt.rej
-rw-r--r-- 1 chris chris   250 Apr 15  2021 countries_diff
-rw-r--r-- 1 chris chris   334 Apr 15  2021 countries.patch
-rw-r--r-- 1 chris chris   250 Apr 15  2021 countries.patch~
-rw-r--r-- 1 chris chris    79 Nov  1 16:22 countries.txt
-rw-r--r-- 1 chris chris   188 Apr 15  2021 duplicate_countries
-rw-r--r-- 1 chris chris    17 Feb 12  2021 example_scipt.sh
-rwxr--r-- 1 chris chris   222 Apr 12  2021 example_script.sh
-rw-r--r-- 1 chris chris     5 Feb  5  2021 f2.txt
-rw-r--r-- 1 chris chris    11 Okt 12 14:40 File
drwxrwxr-x 2 chris chris  4096 Okt 16 15:48 foo
-rw-r--r-- 1 chris chris     5 Feb  5  2021 f.txt
-rw-rw-r-- 1 chris chris    11 Okt 19 13:24 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 Apr 12  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-r--r-- 1 chris chris 35227 Apr 14  2021 lo
-rw-r--r-- 1 chris chris   117 Apr 15  2021 logfile-example_.log
-rw-r--r-- 1 chris chris   179 Apr 15  2021 logfile-example.log
-rwxr--r-- 1 chris chris     6 Nov  1 16:48 longlist
-rw-r--r-- 1 chris chris   462 Mär 18  2021 ls-out.txt
drwxr-xr-x 3 chris chris  4096 Feb  5  2021 mydir1
-rw-r--r-- 1 chris chris 17353 Okt 12 14:39 mylog.txt
-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    70 Apr 15  2021 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
drwxr-xr-x 2 chris chris  4096 Feb  9  2021 test1
-rwxr--r-- 1 chris chris     7 Feb 18  2021 test_script.sh
-rw-r--r-- 1 chris chris    12 Apr 15  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

Übung

Aufgabe

Probieren Sie z.B. folgendes:

  • chmod ug+rwx longlist
  • chmod o-r longlist

Machen Sie sich die Bedeutung der Kommandos klar.

Aufgabe

Welche Rechte erhalten User, Group und Others mit chmod 730?

Aufgabe

Sehen Sie sich die man-Pages von chmod und echo an.

Aufgabe

Mit Hilfe des Kommandos chown (change file owner and group) lassen sich die Eigentümer/innen (Nutzer/in, Gruppe) von Dateien ändern. Recherchieren Sie die Benutzung dieses Kommandos.

Aufgabe

Wie könnten Sie eine Datei mit Name long list erstellen (eventuelle Recherche)? Wieso sind Dateinamen mit Leerzeichen unpraktisch?

Weitere Schutzbits

Neben den 9 Bits für die Rechte gibt es drei weitere Schutzbits (Sonderechte). Recherchieren Sie deren Bedeutung, z.B.

Befehl id

Mit dem Befehl id erhalten Sie die (wirkliche und die effektive) User- und Group-ID.

Aufgabe

Welche User-ID haben Sie im System?

Befehl 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.

In [44]:
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.
In [45]:
# 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.

In [46]:
umask # 0002 entspricht 000 000 000 010
0002
Beispiel
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).

Übung

Welche Bedeutung haben die folgenden Befehle?

  • who
  • whoami
  • w
  • passwd

Löschen von Dateien

Dateien können mit dem Kommando rm (remove) gelöscht werden.

In [48]:
rm longlist
Aufgabe

Erstellen Sie eine Datei, entziehen Sie sich das Schreibrecht. Was passiert nun, wenn Sie die Datei löschen wollen.

  • Verwenden Sie zum Erstellen einer leeren Datei den Befehl touch.

Was passiert, wenn man touch auf eine bestehende Datei anwendet?

Erstellen von Verzeichnissen

Mit Hilfe des Kommandos mkdir (make directories) können Sie Verzeichnisse erstellen, z.B.

In [52]:
mkdir myDir
Aufgabe

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".

Löschen von Verzeichnissen

Leere Verzeichnisse können Sie mittels rmdir löschen, z.B.

In [33]:
rmdir neuesVerzeichnis
Übung

Erstellen Sie ein Verzeichnis und in diesem eine neue Datei.

  • Können Sie die Datei samt Verzeichnis löschen?
  • Können Sie ein Verzeichnis auch mit rm (mit Optionen) löschen? Ist es so möglich ein Verzeichnis inkl. Dateien zu löschen?

Hinweis: Seien Sie vorsichtig, insbesondere in Kombination mit Wildcards. Sonst kann es passieren, dass Sie unabsichtlich wichtige Dateien löschen.

Aufgabe

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?

Aufgabe

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.

Anzeigen von Textdateien

Textdateien können durch folgende Befehle angesehen werden:

  • more
  • less - wie bei den Manpages:
    • Hilfe bezgl. der Navigation erhalten sie bei der Anzeige - mit der Taste h.
    • Suche mit der Taste /.
    • Beenden mit der Taste q.
Übung

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):

In [54]:
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:

In [55]:
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.

In [56]:
# mit `-n` kann man die Zeilenzahl bestimmen.
head -n 3 countries.txt
France
Canada
Burkina Faso
In [57]:
# -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.

Kopieren und Verschieben von Dateien

  • Dateien lassen sich mit cp kopieren.
  • Dateien lassen sich mit mv verschieben.
Übung

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

In [58]:
mkdir myDirA
mkdir myDirB
touch myDirA/text1.txt myDirA/text2.txt
In [59]:
# Wie lautet der Befehl zum Verschieben?
In [61]:
#clean up
rm -r myDirA
rm -r myDirB

Wie läßt sich ein Verzeichnis zusammen mit den darin befindlichen Dateien verschieben?

Inodes

(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:

  • Meta-Daten sind Daten über Daten (hier über die Datei). Hier z.B. das Erstellungsdatum der Datei oder die Schutzbits.
  • Zeiger sind Verweise, z.B. auf Speicherbereiche oder Blocks.

(Bild-)Quelle: http://e2fsprogs.sourceforge.net/ext2intro.html unter dem Punkt "Basic File System Concepts" image.png 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).

Aufgabe

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:

In [62]:
ls --inode
17302817 bar                   15867294 IFS_demo~
15867187 countries_2.txt       15867106 inhalt_des_Verzeichnisses
15867191 countries_3.txt       15870086 lo
15867194 countries_3.txt.orig  15870089 logfile-example_.log
15867193 countries_3.txt.rej   15870085 logfile-example.log
15867192 countries_4.txt       15867110 ls-out.txt
15867196 countries_4.txt.orig  15866940 man_page_of_ls
15867197 countries_4.txt.rej   17302692 mydir1
15867188 countries_diff        15867283 mylog.txt
15867195 countries.patch       15867112 mytrivialscript.sh
15867190 countries.patch~      15867107 nohup.out
15867189 countries.txt         15867114 PDFWender.sh
15870091 duplicate_countries   15867115 PDFWender.sh~
15867290 example_scipt.sh      15870087 rechnernamen.log
15867289 example_script.sh     15870088 rechnernamen.txt
15867279 f2.txt                15867285 result-file
15870040 File                  15867108 signal-handler.py
17172117 foo                   15867109 signal-handler.py~
15867280 f.txt                 15867286 st
15866943 greetings             17302851 test1
15867104 grep                  15867292 test_script.sh
15867288 gruesse               15870090 tmp
15870034 hw.sh                 15867105 TODO
15867295 IFS_demo              15867096 t.txt

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.

image.png Quelle: http://e2fsprogs.sourceforge.net/ext2intro.html

(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:

In [130]:
rm countries_second_hard_link.txt
ln countries.txt countries_second_hard_link.txt
In [131]:
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:

In [112]:
stat countries.txt
  File: countries.txt
  Size: 79        	Blocks: 8          IO Block: 4096   regular file
Device: 10303h/66307d	Inode: 15867189    Links: 2
Access: (0644/-rw-r--r--)  Uid: ( 1001/   chris)   Gid: ( 1001/   chris)
Access: 2021-11-02 14:29:22.088090158 +0100
Modify: 2021-11-02 14:29:20.488130626 +0100
Change: 2021-11-03 08:18:05.207647916 +0100
 Birth: -
In [64]:
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.

Übung

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?

In [65]:
whatis ln
ln (1)               - make links between files

Umleitungen und Pipes

Umleitungen

Es gibt drei Standarddateien:

  • stdin (the keyboard)
  • stdout (the screen)
  • stderr (error messages output to the screen)

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 stdin
  • 1 für stdout und
  • 2 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:

In [66]:
# selbe 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)

Aufgabe

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.

In [67]:
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.

In [68]:
# 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 den Inhalt einer Datei löschen:

> greetings

Aufgabe

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

Aufgabe

Sie wollen den Standardfehlerkanal zusammen mit der Standardausgabe in die gleiche Datei weiterleiten. Wie geht dies?

Weiterleitung der Eingabe mit <

Mit < kann die Standardeingabe umgeleitet werden:

In [71]:
< countries.txt cat
France
Canada
Burkina Faso
Democratic Republic of the Congo
Russia
New Zealand
In [72]:
# die Reichenfolge spielt hier keine Rolle, d.h. folgendes ist äquivalent:
cat < countries.txt
France
Canada
Burkina Faso
Democratic Republic of the Congo
Russia
New Zealand
In [43]:
# 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

Aufgabe

Wie kann man den Inhalt der Datei "greetings.txt" an den Inhalt der Datei gruesse.txt anfügen?

Aufgabe

Ä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

Aufgabe

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

Aufgabe (Recherche)

Was ist /dev/null und wie kann es eingesetzt werden?

/dev/null kan als Mülleimer verwendet werden, z.B.

kommando 1> /dev/null Ausgabe des Kommandos wird unterdrückt.

Pipes

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.

In [137]:
# Was wird hier berechnet?

# das -1 bei ls ist eine Eins kein l
ls -1 | wc -l
51
In [138]:
# dies ist (fast) analog (aber effizienter!)
ls -1 > /tmp/tmp.txt
wc -l < /tmp/tmp.txt
rm /tmp/tmp.txt
51

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

Beispiel für Umleitungen

Hier als Motivation ein etwas komplexeres Beispiel:

In [76]:
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

In [77]:
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.

In [78]:
cat greetings | tr -s " " "\n" | sort
an
die
Grüße
Hallo
Hallo
sind
Welt
Welt
Welt

uniq beseitigt mehrfach vorkommende Zeilen (siehe man uniq):

In [79]:
cat greetings | tr -s " " "\n" | sort | uniq
an
die
Grüße
Hallo
sind
Welt

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.

In [80]:
cat greetings | tr -s " " "\n" | sort | uniq | wc -l
6

Unix Philosophie

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:

  • Schreibe Computerprogramme so, dass sie nur eine Aufgabe erledigen und diese gut machen.
  • Schreibe Programme so, dass sie zusammenarbeiten.
  • Schreibe Programme so, dass sie Textströme verarbeiten, denn das ist eine universelle Schnittstelle.

Gewöhnlich wird das verkürzt zu: „Mache nur eine Sache und mache sie gut.“ "
aus dem Wikipedia-Artikel zur Unix-Philsophie

Übung

Befehl xargs

xargs erlaubt es den Standard-Input als Argument für einen anderen Befehls einzusetzen.

Beispiel:

In [84]:
which ping | xargs ls -la
-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) in 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:

In [86]:
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:

In [87]:
which ping | xargs -I {} echo ls {} -la
ls /bin/ping -la

{} ist ein Platzhalter.

Der Platzhalter lässt sich der stdin auch mehrfach verwenden. Hier mit x als Platzhalter.

In [88]:
ls *.txt | xargs -I x echo cp x x.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.txt countries.txt.bak
cp f2.txt f2.txt.bak
cp f.txt f.txt.bak
cp ls-out.txt ls-out.txt.bak
cp mylog.txt mylog.txt.bak
cp rechnernamen.txt rechnernamen.txt.bak
cp t.txt t.txt.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.)

Mehr zu xargs wieder in der Manpage oder auf https://tldr.ostera.io/xargs.

Befehlshistorie

  • Mit der Taste kann man bezüglich der verwendeten Befehle zurückblättern und mit wieder nach vorne.
  • Mit der Tastenkombination Strgr kann man die letzten Befehle "durchsuchen".
  • Mit Hilfe des Kommandos 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.

Aufgabe

  • Nutzen Sie die Tastenkombination der Befehlshistorie und spielen Sie hiermit.
  • Sehen Sie sich alle zuletzt verwendeten Befehle an.

Lernkontrollfragen

Folgende Fragen sollten Sie ohne Nachschlagen beantworten können:

  • Welche Befehle kennen Sie (ink. Schalter) bezüglich
    • Kopieren von Dateien/Verzeichnissen
    • Verschieben von Dateien/Verzeichnissen
    • Löschen von Dateien und Verzeichnissen
    • Ändern des laufenden Arbeitsverzeichnis
    • Anzeigen des laufenden Arbeitsverzeichnis
    • Anzeigen des Inhalts eines Verzeichnis
    • Ändern der Rechte einer Datei
    • Anzeigen von Textdateien
  • Was ist stdin, stdout und stderr?
  • Wie können Befehle verbunden werden?
  • Was sind Pipes und wozu dienen sie?
  • Wie kann man in einer Pipe den weitergereichten stdout als Argument für einen anderen Befehl verwenden?