Shell-Commands

Siehe auch

Eine unvollständige Liste an Kommandozeilen-Befehlen, nach Themen kategorisiert und mit Tipps & Tricks versehen.

Die Gross-/Kleinschreibung zählt: ssh ist ein anderes Kommando als Ssh oder SSH.

Checksummen prüfen

echo "$VENDOR_CHECKSUM $VENDOR_FILE" | sha256sum -c -

Datum, Zeit

Aktuelle Uhrzeit fortlaufend oben rechts im Terminal-Fenster anzeigen:

while sleep 1; do tput sc; tput cup 0 $(($(tput cols)-29)); date; tput rc; done &

Aktuelles Datum mit Uhrzeit abfragen:

date

Zeitstempel im Format „yyyy-mm-dd“ ausgeben:

date --iso-8601

Zeitstempel im Format „yyyy-mm-dd hh:mm:ss“ ausgeben:

date +"%Y-%m-%d %H:%M:%S"

Tipp

Das „T“ in einer Zeitangabe im Format 2020-11-06T10:38:17 bedeutet nach ISO 8601 (UTC) lediglich, dass nach dem „T“ die Time-Komponente folgt.

Monats- und Tagesangaben ohne führende Null:

date +"%-m %-d"

Zeitstempel im Format „Java (UTC)-Timeformat“ ausgeben:

#2018-07-02T06:49:32Z
date -u +%Y-%m-%dT%H:%M:%SZ

Uhrzeit setzen

date --set="2 OCT 2018 12:34:56"

Aktuellen Wochentag anzeigen:

date +%a

So addiert man zum heutigen Datum 90 Tage, x Minuten etc.:

date --date "+90 days"
date --date "+1231 minutes"

Angaben mit unbekannter Zeitzone wie „Wartungsarbeiten werden Freitag, 23. Januar 2015 um 23:45 AST durchgeführt“ können mit diesem Aufruf in die eigene, lokale Zeit umgerechnet werden:

date --date '2015-01-23 23:45 AST'

Anzahl Sekunden/Millisekunden/Nanosekunden seit 01.01.1970 (UNIX-Epoche):

date +%s
date +%s%N | cut -b1-13
date +%s%N

UNIX-Timestamp in ein Datum umrechnen:

date --date @1437984866

Uhrzeit vor 25h als UNIX-Timestamp

date +%s --date "-25 hours"

Kalender anzeigen:

cal

Anzahl Tage seit dem 01.01.1970:

today=$(date +"%s")
echo $(( $today / 3600 / 24 ))

date hält sich an die konfigurierte Locale, d.h. ein date +"%b" gibt „Mär“ aus. So stellt man die Locale um:

LC_ALL=C date ...
LC_ALL=en_US.utf8 date ...

Man möchte ein Kommando zu einer bestimmten Uhrzeit testen, aber nicht die Systemuhr ändern?

yum -y install libfaketime
faketime 00:30 command

Prozesse, Performance

Anzahl Sekunden zwischen zwei Kommandos pausiere .Dder Befehl sleep kann auch mit Bruchteilen von Sekunden umgehen. Früher war ulseep für das Schlafen in Millisekunden zuständig; dieser Befehl gilt inzwischen als veraltet.

command 1; sleep 0.5; command 2

Befehl für maximal 5 Sekunden laufen lassen:

timeout 5s grep -ir ...

Einen Befehl mit Argumenten füttern, die vom vorhergehenden Kommando produziert wurden:

find / -name '*.bak' | xargs ls
# so "ls" lists all files found by "find"

Die häufigsten Parameter für xargs:

  • -l, --max-lines
    Deprecated, sollte durch -L ersetzt werden. Maximal die angegebene Anzahl Zeilen pro Kommandozeile verwenden. Default: 1.

System und Umgebung

Wie geht es dem System? Kernel Ring Buffer auslesen:

dmesg

# on CentOS 7+ dmesg is more human readable and can use filters
dmesg --reltime --level=emerg,alert,crit,err

dmesg --clear

Aliase anzeigen:

alias

Den Befehl ls so ändern, dass er in Zukunft mit anderen Parametern aufgerufen wird:

alias ls="ls -l --color=auto"

Neuen Befehl whatismyip anlegen, der die globale IP-Adresse des Rechners zurückliefert (mehr dazu auf der Webseite ifconfig.me, die jedoch immer schlechter zu erreichen ist):

alias whatismyip="curl ipecho.net/plain"

Tipp

Dauerhaft definiert man einen Alias in der versteckten Datei ~/.bashrc im Home-Verzeichnis für einen Benutzer, oder systemweit für alle Benutzer unter /etc/profile.d (Dateiname ist beliebig). Achtung: man hüte sich, ein „exit“ in solch eine Datei einzubauen. Das führt nach dem Login zum sofortigen Beenden der Shell - und damit zum Logout.

Umgebungsvariablen anzeigen:

env

Temporär Variable vor dem Lauf eines Kommandos setzen:

EDITOR=nano crontab -e

Informationen zur Linux-Umgebung abfragen:

uname --all

Welche Benutzer sind gerade am System angemeldet, und was tun sie?

w

Welche Benutzer sind gerade am System angemeldet?

who

Unter welchem Benutzerkonto arbeite ich gerade?

whoami

Ausführbare Datei, Quelltext/Config-Pfad und Manpage zu einem Programm anzeigen:

whereis rsync

Pfad zur ausführbaren Datei eines Befehls anzeigen:

which ssh

So sendet man dem angemeldeten Benutzer „linus“ eine Nachricht in sein Terminal:

write linus
Hi Linus, my message ...
# press Ctrl-d to exit

Eine Nachricht an alle Benutzer in allen Terminal-Sitzungen senden:

wall -n 'my message'

Was ist in der Vergangenheit an Logins und Reboots auf der Maschine passiert?

last
last reboot

Filesystem

Allgemein

Tipp

Wer mit einer Datei arbeiten will, deren Name mit einem Bindestrich beginnt, wird beispielsweise mit cat -test nicht weit kommen, da die Bash meint, bei -test handelt es sich um einen Parameter. Der Trick: entweder die Escape-Sequenz cat ./-test anwenden, oder zwei aufeinanderfolgende Bindestriche (--) angeben, was in Bash das Ende von Optionen markiert (cat -- -test).

Aktuelles Verzeichnis anzeigen (print working directory; das aktuelle Verzeichnis ist zudem in der Umgebungsvariablen PWD abgelegt):

pwd

In das Verzeichnis /boot wechseln:

cd /boot

In das vorherige Verzeichnis zurückwechseln (arbeitet anhand der Umgebungsvariablen OLDPWD):

cd -

Verzeichnisinhalt in ausführlicher Form anzeigen, neueste Dateien zuletzt:

ls -ltr

Dateien sortiert nach Grösse (Size) auflisten, grösste Dateien zuerst:

ls -lS
ll -S

Nur Verzeichnisse auflisten:

ls -d */

Verzeichnis inkl. aller Unterverzeichnisse erstellen:

mkdir -p /path/to/my/new/dir

Temporäre Datei anlegen:

mktemp

Temporäres Verzeichnis anlegen:

mktemp --directory

Verzeichnisbaum grafisch anzeigen (nur Verzeichnisse, zwei Ebenen):

yum -y install tree
tree -dL 2

Zeige den Inhalt der Datei filename an:

cat filename

Zeige den Inhalt der Datei filename mit Zeilennummern an:

nl filename

Ermittelt den Typ einer Datei:

file filename

Character-Encoding einer Datei ermitteln:

file --brief --mime filename

Nur Dateiname anzeigen:

basename /path/to/file.txt

Dateiname ohne Extension anzeigen (bei bekannter Extension):

basename /path/to/file.txt .txt

Datei /tmp/bigfile in mehrere 700 MB grosse Dateien aufsplitten:

split --bytes 700MiB /tmp/bigfile-part.gz

Alle Attribute und Zeitstempel zu einer Datei anzeigen:

stat filename

Nur die Grösse einer Datei in Bytes anzeigen:

stat --format=%s filename

Zeigt die ersten 17 Zeilen der Datei filename an:

head -17 filename

Zeigt die letzten 23 Zeilen der Datei filename an:

tail -23 filename

Anzahl Zeilen, Wörter und Bytes (mit dem Parameter -l nur die Anzahl der Zeilen) in einer Textdatei zählen:

wc filename

Fünf leere Dateien erstellen:

touch /tmp/myfile{1..5}.txt

Mehrere Dateien umbenennen (Batch-Renaming):

# rename search-for replace-with file-glob
rename foo foo00 foo?
rename foo foo0 foo??
rename .htm .html *.htm

Datei mit 10MB Grösse erzeugen. Wichtig: die Base („bs“) darf max. 2G (= 2 GB) gross werden. Mit grösseren Basen kann dd nicht umgehen (Integer-Grenze). Wer eine 10 GB grosse Datei erzeugen möchte, gibt „bs=1G count=10“ an:

# containing zeros
dd if=/dev/zero of=output.dat bs=10M count=1 status=progress
# containing random data
dd if=/dev/urandom of=output.dat bs=10M count=1 status=progress

# using "head"
head --bytes 10M < /dev/urandom > output.dat

Datei leeren - nützlich bei Log-Dateien, deren Berechtigungsschema erhalten oder bei denen der schreibende Prozess nicht unterbrochen werden soll:

# first method
truncate --size=0 filename
# second method
> filename

Datei von einem Encoding-Format in ein anderes umwandeln:

iconv --from-code=iso-8859-1 --to-code=utf-8 file-isoformat > file-utf8format

Verzeichnis inkl. aller Unterverzeichnisse kopieren:

cp -r /path/to/dir1 /path/to/dir2

Datei kopieren - ohne Nachfrage, ob eine existierende Datei überschrieben werden darf. Der Backslash vor cp sorgt dafür, dass der Befehl in seiner ursprünglichen Form ausgeführt und ein eventuell angelegter alias ignoriert wird):

\cp file1 /path/to/file2

Datei verschieben:

mv file1 /path/to/file2

Datei file1 in file2 umbenennen:

mv file{1,2}

Verzeichnis inkl. aller Unterverzeichnisse verschieben:

mv /path/to/dir1 /path/to/dir2

Backup erstellen, z.B. für ein Langzeit-Achiv (bei kollidierenden Dateinamen beide Versionen behalten):

mv --backup=numbered /path/to/dir1/* /path/to/dir2/

Mehrere Dateien kopieren und dabei umbenennen - im Beispiel alle .yml-Dateien nach .yml.sample:

for file in *.yml; do cp $file $file.sample; done

Datei ohne Nachfrage löschen:

rm -f filename
yes | rm filename

Verzeichnis inkl. aller Unterverzeichnisse ohne Nachfrage löschen:

rm -rf /path/to/dir

Achtung

To remove a symbolic link, use either the rm or unlink command followed by the name of the symlink as an argument. When removing a symbolic link that points to a directory do not append a trailing slash to the symlink name. If you have any questions or feedback, feel free to leave a comment

Um symbolische Links zu entfernen, rm oder (besser) unlink verwenden. Falls dabei ein symbolischer Link auf ein Verzeichnis zeigt, AUF KEINEN FALL die Pfadangabe mit einem / abschliessen - das Zielverzeichnis wird sonst ebenfalls entfernt.

Und gelöscht ist gelöscht - wer Dateien per rm entfernt, kann sie in der Regel nicht wiederherstellen. Ein Backup ist demnach Pflicht, oder man modifiziert den rm-Befehl per alias so, dass Dateien per mv in einen /recycle.bin-Ordner verschoben werden (wer danach sucht, wird auf verschiedene Skripte stossen. Hier sollte man eines wählen, welches die offizielle Trash-Definition umsetzt, so dass der Recycle Bin auch zu GNOME & Co. kompatibel ist).

Achtung

Wer rm in Skripten verwendet, sollte mit der Angabe -- das Ende von Optionen markieren. Ein Angreifer könnte sonst eine Datei namens -rf in dem zu löschenden Verzeichnis platzieren, was ohne -- als Option zu einem rm -rf interpretiert wird.

Um den Effekt zu verdeutlichen, kann man die folgenden Kommandos einzeln der Bash übergeben:

yum -y install tree
mkdir -p /tmp/test; cd /tmp/test
mkdir {a,b}
touch a/a.txt; touch -- -rf
tree
rm *
tree

Besser also so:

mkdir -p /tmp/test; cd /tmp/test
mkdir {a,b}
touch a/a.txt; touch -- -rf
tree
rm -- *
tree

df, du

Disk Free, Disk Usage.

Bemerkung

Ohne die -h-Angabe (human readable) listet das Kommando die Grösse in Blocks auf, nicht in Bytes. Daher sollte mit -h oder explizit mit --bytes gearbeitet werden.

Freien Festplattenplatz im human-readable Format anzeigen, inkl. Typ des Gerätes (z.B. ext4 oder iso9660):

df --human-readable --print-type
# shorter
df -hT

Speicherplatzverbrauch aller Dateien und Verzeichnisse unterhalb des aktuellen Verzeichnisses anzeigen, maximal eine Ebene tief, Grössenangaben im human-readable-Format, ohne eingehängte Dateisysteme wie NFS usw:

du --bytes --human-readable --one-file-system --max-depth=1
# shorter
du --bytes -hxd 1

Die zehn grössten Dateien im aktuellen Verzeichnis auflisten:

du --max-depth=1 --summarize --bytes * | sort --numeric-sort | tail

Einige Verzeichnisse von der Statistik ausnehmen:

du --exclude='/home/*' --exclude='/var/*' /

find

Bei Angabe von Wildcards sind die Quotes wichtig, ansonsten expandiert die Shell die Dateiliste vor der Übergabe an das find-Kommando, womit die Syntax nicht mehr stimmt. In so einem Fall erhält man die Meldung „find: paths must precede expression“.

Zeige des Inhalt des aktuellen Verzeichnisses inkl. aller Unterverzeichnisse an:

find

Finde alle Dateien mit der Extension „.php“, ignoriere Gross-/Kleinschreibung:

find -iname '*.php'

Alle Dateien aus dem aktuellen Verzeichnis inkl. aller Unterverzeichnisse mit allen Eigenschaften auflisten:

find -ls

Anzahl Dateien in einem Verzeichnis inkl. aller Unterverzeichnisse zählen:

find | wc --lines

Vom aktuellen Verzeichnis ausgehend alle Dateien >= 100 MB Grösse finden sowie deren Eigenschaften lesbar darstellen:

find -size +100M -ls

Finde nur Dateien / Links, rekursiv zum aktuellen Verzeichnis:

find . -type f
find . -type l

Finde Dateien und bleibe lokal:

find -mount -type f

Finde alle Dateien und stelle dem Dateinamen in der Ausgabe das Dateidatum im Format „Y-m-d H:m“ sowie den String „FILE“ voran:

find -type f -printf "%TY-%Tm-%Td %AH:%AM FILE %p\n"

Suche die zwanzig neuesten (ältesten) Dateien. Bedeutet: finde alle Dateien, rekursiv zum aktuellen Unterverzeichnis, stelle dem Dateinamen in der Ausgabe das Dateidatum im Format „Y-m-d H:m“ voran, sortiere die Ausgabe und liefere nur die ersten zwanzig Zeilen zurück:

find -type f -printf "%TY-%Tm-%Td %AH:%AM %p\n" | sort -nr | head -20

Ignoriere die Verzeichnisse „cache“ und „log“:

find -type f -not -path './cache*' -not -path './log/*' ...

Datei mit einer bestimmten inode-Nummer finden:

find -inum inodenumber

Finde Dateien, die dem Benutzer Linus gehören:

find -user linus

Alle Dateien suchen, die keinem Benutzer und keiner Gruppe gehören:

find / -nouser -o -nogroup

Finde alle XML-Dateien aus dem aktuellen Verzeichnis, die vor mehr als 24h, aber weniger als 48h modifiziert wurden:

# atime = access time, ctime = creation time
find *.xml -type f -mtime 1

Finde alle XML-Dateien aus dem aktuellen Verzeichnis, die vor 24h oder länger modifiziert wurden:

find *.xml -type f -mtime -1

Finde die grössten Dateien:

find -printf '%s %p\n' | sort -nr | head

Finde Dateien mit Änderungsdatum zwischen x und y und liste sie mit Datum auf:

find -type f -newermt 2015-09-07 ! -newermt 2015-09-31

Lösche alle Dateien älter als 10 Tage:

# test before delete:
find -mtime +10 -type f -ls
find -mtime +10 -type f -delete

Leere Ordner löschen:

find /path/to -type d -empty -delete

Junk-Dateien wie .DS_Store, desktop.ini, Thumbs.db löschen:

find -type f -name .DS_Store -delete -o -name desktop.ini -delete -o -name Thumbs.db -delete -o -name '*~' -delete

Finde alle Executables:

find -type f -executable -print

Finde alle Executables und entferne das Executable Bit:

find -type f -executable -exec chmod -x "{}" \;

Finde doppelte Dateien / Duplicates:

find . ! -empty -type f -exec md5sum {} + | sort | uniq -w32 -dD

Finde Dateien, die „korrupt“ sind, also nicht dem erwarteten Dateityp (z.B. anhand der Dateiendung) entsprechen. Die Ausgabe in eine Datei umleiten und anschliessend sortieren - alles, was mit data :::: beginnt, ist nicht identifizierbar:

find -type f -exec file {} \; | awk 'BEGIN {FS=": "} ; {print $2 " :::: " $1}' > /tmp/files.txt

Finde Bilder wie JPG, PNG, SVG, TIFF und andere:

find . -name '*' -exec file {} \; | grep -o -P '^.+: .* image'

grep

grep ist ein Tool, um mit Hilfe regulärer Ausdrücke bestimmte Zeichenketten in Text-Streams und Dateien zu finden. grep liefert in der Standardeinstellung die Zeilen zurück, die dem Such-Ausdruck entsprechen.

Von grep existieren zwei Varianten: egrep und fgrep. egrep entspricht grep --extended-regexp, fgrep entspricht grep --fixed-strings (was man verwendet, falls bei einer Suche keine regulären Ausdrücke notwendig sind). Die direkte Verwendung von egrep und fgrep ist als „deprecated“ (veraltet) eingestuft und sollte daher vermieden werden, ist aus Kompatibilitätsgründen aber noch möglich.

Finde jede Zeile, die das Wort GNU in der Datei /usr/share/doc/redhat-release/GPL enthält - das erste Argument ist die Zeichenkette, nach der gesucht wird, das zweite die Datei, in der gesucht wird:

# using grep directly
grep GNU /usr/share/doc/redhat-release/GPL

# the unefficient way: create a pipe, executing
# "cat file" with its output redirected to the pipe
# and "grep searchstring" with its input redirected
# from the pipe
cat /usr/share/doc/redhat-release/GPL | grep GNU

Suche unterhalb des Verzeichnisses /var/log rekursiv in allen Dateien nach „Permission Denied“ und ignoriere dabei Gross- und Kleinschreibung:

grep -ir 'Permission Denied' /var/log/*

Auch versteckte Dateien (hidden files) durchsuchen:

grep -ir 'Permission Denied' /var/log/* .[^.]*

Anzahl der erfolglosen SSH-Login-Versuche ermitteln:

grep 'Invalid user' /var/log/secure | wc --lines
  • Sucht in einer Datei nach „linus“ oder „anna-lena“, Gross-/Kleinschreibung spielt keine Rolle:

grep -i --extended-regexp 'linus|anna-lena' /var/log/messages

Nur die Dateinamen auflisten, die die Zeichenfolge enthalten:

grep --files-with-matches ...

Durchsucht alle Dateien nach dem Begriff „sysnet“, zeige aber in der Ergebnisliste nur die an, die nicht „copyright“ enthalten:

grep -ir sysnet | grep -i --invert-match copyright

Nur die Anzahl Vorkommnisse des Wortes „myword“ zählen:

grep --only-matching myword myfile | wc -l

Fünf Zeilen vor und sieben Zeilen nach der Fundstelle anzeigen:

grep --before-context=5 --after-context=7 keyword
# shorter
grep -B 5 -A 7 keyword

Finde Leerzeichen am Anfang einer Zeile:

grep --line-number '^[:blank:]' filename

Verzeichnisse ausschliessen, nur bestimmte Dateien durchsuchen:

grep -ir --exclude-dir dirname --include '*php' ...

Nur lokal suchen, nicht über gemountete Dateisysteme:

find / -xdev -type f -print0 | xargs -0 grep -r ‚searchtext‘

Tipp

Mit pdfgrep sucht man in PDF-Dokumenten:

yum -y install pdfgrep
pdfgrep --recursive --ignore-case "selinux" *.pdf

inotify

Zugriffe auf das Dateisystem in der Art wie die Sysinternals-Tools unter Windows anschauen - einmal nur Events zählen und Statistiken nach dem Beenden des Programms ausgeben, und einmal alle Events auf der Konsole ausgeben:

# up to CentOS 7, from EPEL
yum -y install inotify-tools
inotifywatch --recursive /tmp
inotifywait --monitor --recursive /tmp

Nur Änderungen (write und modify) filtern:

inotifywait --monitor --recursive /tmp | grep -E '(MODIFY|CREATE|DELETE)'

Netz, URIs

curl und wget

curl vs wget:

  • wget verhält sich wie ein Browser und folgt beispielsweise Redirects automatisch; curl arbeitet low-level.

  • TLS: Während wget OpenSSL nutzt, verwendet curl die NSS (Mozilla Network Security Services <https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Overview>) Library.

Host-Header mitgeben (nützlich, um lokal virtuelle Name-based Hosts ansprechen zu können (SNI)):

curl --header 'host: www.linuxfabrik.ch' http://server

HTTP Basic-Authentication mit curl:

curl --user "username:password" https://server/path/to/api

Low-Level HTTP Basic-Authentication Header mit curl, Zugangsdaten sollen base64-encoded sein:

curl --header "Authorization: Basic $(echo -n 'user:password' | base64)" \
    https://server/path/to/api

curl-Request mit Bearer-Token Authentication:

curl --header "Authorization: Bearer $TOKEN" \
    --header "Content-Type: application/json" \
    https://server/path/to/api

Authentication mit Angaben im Request Body der Nachricht und einem POST:

curl --request POST \
    --header 'Content-Type: application/json' \
    --data '{"user":"username", "password":"my_password"}' \
    https://server/path/to/api

OPTIONS per curl abfragen (Antworten stecken beim OPTIONS-Request immer im Response Header, den man nur per --verbose zu Gesicht bekommt):

curl --verbose --request OPTIONS https://server

Socket mit curl abrufen / fetch socket instead of HTTP:

curl --no-buffer --unix-socket /run/php-fpm/www.sock http://server/php-status

curl und Cookies - mehrere Cookies durch ; trennen (können z.B. aus Firefox übergeben werden):

curl --cookie "TOKEN1=Yes;TOKEN2=no" https://server

Sämtlichen Output in curl unterbinden:

curl --silent ... > /dev/null

Das Kommandozeilenprogramm wget dient primär dem Herunterladen von Dateien aus dem Internet. Im Gegensatz zu curl folgt es Weiterleitungen automatisch.

Basic Auth mit wget:

wget --user user --password pass http://example.com/

Datei herunterladen und dabei umbenennen:

wget --output-document=newname.zip http://server/filename.zip

Komplette Webseite ziehen, ohne externen Links zu folgen:

wget --mirror --adjust-extension \
    --page-requisites --execute robots=off \
    --convert-links --user-agent=Mozilla \
    http://server

Nur zip-Dateien einer Webseite ziehen:

wget --mirror --accept zip http://server

Zufallszeit zwischen den Downloads und Speed-Limit setzen:

wget --wait=30 --random-wait --limit-rate=100k ...

Unterbrochenen Download fortsetzen:

wget ‐‐continue ftp://server/filename.iso

Dateien nur ziehen, wenn sie neuer sind:

wget ‐‐continue ‐‐timestamping http://server/filename.iso

Daten hinter einer Login-Seite ziehen - einloggen:

wget ‐‐cookies=on ‐‐save-cookies cookies.txt \
    ‐‐keep-session-cookies \
    --post-data 'user=myuser&password=mypwd' \
    http://server/login

wget anweisen, nichts zu speichern (also nur Zugriff zu prüfen), keine Zertifikate zu prüfen (bei curl --insecure), maximal einmal zu wiederholen und nur zwei Sekunden auf Timeout zu warten:

wget --output-document=/dev/null --no-check-certificate --timeout=2 --tries=1 http://server/filename

Tipp

Das Gegenstück zu wget zum Hochladen von Daten heisst wput.

Text-Processing

Allgemein

Ausgabe sortieren und dabei sich wiederholende Zeilen nur einmal anzeigen:

sort --unique myfile.txt

Datei so ausgeben, dass man mit den Cursortasten navigieren, mit / vorwärts (regulär) suchen und mit q die Ansicht beenden kann. less is more: less ist der Nachfolger von more:

less myfile.txt

In Log-Datei nur alles ab dem 8. Zeichen anzeigen:

cut --characters=8- /var/log/messages

Nur die vierte, fünfte und alles ab der siebten Spalte der Log-Datei ausgeben, Spaltentrenner ist das Leerzeichen:

cut --delimiter=" " --fields=4,5,7-99 /var/log/messages

Mehrfach auftretende Zeilen einer Datei filtern:

cut --delimiter=" " --fields=5-99 /var/log/dmesg | uniq

Verketten von Dateien anhand eines eindeutigen Schlüssels. Die Spalte mit den Schlüsselwerten sollte in den Dateien sortiert vorliegen, dann geht:

join --ignore-case myfile1.txt myfile2.txt

Zwei Dateien Seite an Seite anzeigen:

paste myfile1.txt myfile2.txt

Zeilen mehrerer Dateien komma-getrennt miteinander verketten:

paste --delimiters="," myfile1.txt myfile2.txt

Datei sortiert ausgeben:

sort myfile.txt

CSV-Datei sortiert ausgeben. Dabei nicht-druckbare Sonderzeichen und führende Leerzeichen ignorieren und anhand der zweiten Spalte reverse sortieren (Trennzeichen ist das Semikolon):

sort --ignore-leading-blanks --ignore-nonprinting \
  --reverse --unique \
  --field-separator=";" \
  --key=2 \
  myfile.csv

Liste mit IP-Adressen korrekt sortieren - der Trick besteht in der Aufteilung der Zeilen in vier Spalten, die jeweils numerisch sortiert werden:

sort --numeric-sort \
  --field-separator=. \
  --key=1,1 --key=2,2 --key=3,3 --key=4,4 \
  iplist.txt

awk

AWK ist eine für die Verarbeitung von Text entworfene, interpretierte Programmiersprache. Unter Linux heisst das passende Kommando awk. AWK wird oft zum Extrahieren von Spalten aus Textdateien verwendet. Der Name ist aus den Anfangsbuchstaben der Nachnamen ihrer drei Autoren zusammengesetzt.

„Erste Spalte“ bedeutet wirklich erste Spalte; awk zählt ab 1, nicht ab 0.

Erste Spalte der Ausgabe des yum-Befehls extrahieren:

yum list installed | awk '{print $1}'

Output-Spalten mit awk anders anordnen (Spalte 2 wird zu Spalte 1 usw.):

command | awk '{print $2 " " $3 " " $5 " " $1}'

Einen anderen Trenner/Field Separator verwenden:

command | awk 'BEGIN {FS=": "} ; {print $2 " " $3 " " $5 " " $1}'

Alle Werte aus der dritten Spalte einer Textdatei zusammenzählen:

cat myfile.csv | awk '{x += $3} END {print x}'

Wer war jemals auf der Maschine aktiv eingeloggt?

last -w | awk '{print $1}' | sort | uniq

AWK kennt „Built-in“-Variablen wie zum Beispiel:

  • NR: Number of Records. Wenn Anzahl Lines > 1, gebe Spalte 6 aus: awk {'if (NR!=1) print $6'}

Berechnung eines Scores in Prozent mit Hilfe von awk:

MY_SCORE=47
TOTAL_SCORE=250
if [ $TOTAL_SCORE -ne 0 ]; then
    echo "Score in %: "$(echo "$MY_SCORE" "$TOTAL_SCORE" | awk '{printf "%.0f", $1 * 100 / $2}')
fi

sed

sed steht für „Stream Editor“.

Erste Zeile entfernen:

command | sed 1d

Alle Vorkommen von „srv“ in der Datei filename durch „www“ ersetzen (für das Arbeiten direkt in der Datei sorgt der Schalter --in-place oder kurz -i):

sed --in-place 's/srv/www/g' filename

Überflüssige Leerzeilen einer Konfigurations-Datei löschen:

sed --in-place '/^\s*$/d' /etc/postfix/main.cf > /etc/postfix/main.cf.clean

In /var/log/messages alle IP-Adressen extrahieren, die erfolgreich auf die Maschine zugreifen konnten:

grep ACCEPT /var/log/messages | sed -E 's/.SRC\=(.*) DST.*/\1/' | sort | uniq

Jeder Zeile ein Prefix voranstellen, z.B. #:

sed --expression='s/^/#/' file

Bild-Processing

So lassen sich die Abmessungen eines Bildes ändern:

yum -y install ImageMagick
convert xmpl.png -resize 200×100 xmpl.png

Mail-Versand

Einfache Text-Mail per SMTP versenden:

yum -y install mailx
echo 'body' | mailx -s 'subject' recipient@xmpl.com

Mail mit Body und Attachment:

echo 'body' | mailx -a /path/to/myfile1 -a /path/to/myfile2 -s 'subject' recipient@xmpl.com

Mail über spezifischen SMTP-Server mit festgelegter From-Adresse senden:

echo 'body' | mailx -v \
-s 'subject' \
-S smtp-auth-login \
-S smtp-auth-password="mypassword" \
-S smtp-auth-user="noreply@xmpl.com" \
-S smtp="mail.xmpl.com:587" \
-S ssl-verify=ignore \
-r noreply@xmpl.com \
recipient@xmpl.com

Mail über SMTP-Server mit STARTTLS:

echo "set nss-config-dir=/etc/pki/nssdb" >> /etc/mail.rc
echo 'body' | mailx -v \
-s 'subject' \
-S smtp-auth-password="mypassword" \
-S smtp-auth-user="noreply@xmpl.com" \
-S smtp-auth=login \
-S smtp-use-starttls \
-S smtps="mail.xmpl.com:587" \
-S ssl-verify=ignore \
-r noreply@xmpl.com \
recipient@xmpl.com

Die Parameter lassen sich fix konfigurieren, so dass sie nicht mehr auf der Kommandozeile angegeben werden müssen.

/etc/mail.rc, ~/.mailrc
set smtp-auth-password=mypass
set smtp-auth-user=mymail@linuxfabrik.ch
set smtp-auth=login
set smtp-use-starttls
set smtp=smtps://smtp.linuxfabrik.ch:587
set ssl-verify=ignore

QR-Codes auf der Kommandozeile generieren

dnf -y install qrencode

QR-Code für URLs:

qrencode --size 20 --level H --output qr.png https://example.com
# creates a 980x980 pixel QR code

Die wichtigsten Optionen:

--output=FILENAME
  write image to FILENAME. If '-' is specified, the result will be
  output  to  standard  output. If -S is given, structured symbols
  are written to FILENAME-01.png, FILENAME-02.png, ... (suffix  is
  removed from FILENAME, if specified)

--read-from=FILENAME
  read input data from FILENAME.

--size=NUMBER
  specify the size of dot (pixel). (default=3)

--level={LMQH}
  specify  error  correction level from L (lowest) to H (highest).
  (default=L)

--dpi=NUMBER
  specify the DPI of the generated PNG. (default=72)

--type={PNG,PNG32,EPS,SVG,XPM,ANSI,ANSI256,ASCII,ASCIIi,UTF8,UTF8i,AN‐
SIUTF8,ANSIUTF8i,ANSI256UTF8}
  specify the type of the generated image. (default=PNG)

--foreground=RRGGBB[AA]
--background=RRGGBB[AA]
  specify foreground/background  color  in  hexadecimal  notation.
  6-digit  (RGB) or 8-digit (RGBA) form are supported.  Color out‐
  put support available only in PNG, EPS and SVG.

Built on 2024-03-28