====== Codeschnipsel für Shell-Programmierung ======
Eine kleine Auswahl an Codeschnipseln für bestimmte Aufgaben in Shell-Skripten.
==== Sichere Verwendung von Variablen ====
${VAR:?}
Überprüft, ob die Variable gesetzt ist statt eines leeren Strings zu verwenden.
Negativbeispiel: [[linux:steam|Steam unter Linux]], Valve hatte
rm -rf "$STEAMROOT/"*
im Code stehen, $STEAMROOT kann leer sein. Dadurch wird der Befehl zu ''rm -rf /*''. Kann durch ''${STEAMROOT:?}'' verhindert werden, da so mit einem Fehler abgebrochen wird, wenn die Variable leer oder nicht gesetzt ist.
==== Dateiendungen entfernen ====
name=${$path%.*}
''%'' löscht den kürzesten Treffer vom Ende des Strings, ''%%'' löscht den längsten Treffer vom Ende aus.
==== Kompletten Pfad entfernen ====
name=${$path##*/}
''#'' löscht den kürzesten Treffen vom Beginn des Strings, ''##'' löscht den längsten Treffer vom Beginn aus.
==== Letzten Teil des aktuellen Pfades entfernen (basename) ====
"${PWD%/*}"
==== Zum Vorherigen Verzeichnis wechseln ====
cd -
==== Basispfad des ausgeführten Skripts ermitteln ====
DIR=$( cd -- "$( dirname -- "$(readlink -f "${BASH_SOURCE[0]}" || ${BASH_SOURCE[0]})" )" &> /dev/null && pwd )
Folgt auch Symlinks und funktioniert, wenn es mit ''source'' ausgeführt wird, ''#!/bin/sh'' hat bei mir ebenfalls geklappt.
==== Formatierung ''date'' ====
date +"%A, %e. %B %Y %k:%M:%S %Z"
Liefert eine Ausgabe in der Form "Donnerstag, 1. Januar 1970 0:00:00 CET"
==== printf rechts ausrichten ====
col=$(tput cols)
printf '%*s%s' $col "[OK]"
Oder als Einzeiler
printf '%*s%s' $(tput cols) "[OK]"
==== watch mehrere Argumente mehrzeilig ====
watch -t -n 10 'printf "%*s%s" $(tput cols) "$(date)"; echo -e "\n" \
&& echo "Jobs running:" && qstat | grep R | grep $USER | wc -l'
==== Installationszeitpunkt Linux ermitteln ====
sudo tune2fs -l $(mount | grep 'on \/ ' | awk '{print $1}') | grep 'Filesystem created:' | awk '{print $5, $4, $7}'
==== Array ohne Dopplungen ausgeben ====
awk '!a[$0]++' file
Entfernt doppelte Einträge ohne sortieren. ''$0'' bedeutet die ganze Zeile in ''awk'', ''%%'a'%%'' steht für Array, Ausgabe falls nicht in Array.
==== Berechnungen, Zahlen runden ====
Berechnungen allgemein können mit ''bc'' ausgeführt werden:
echo "3.14+7/8-(5.42*3.14)" | bc
Das ganze lässt sich auch mit ''printf'' formatieren:
printf "%.3f\n" $(echo 5/3 | bc -l)
Allerdings bereitet dies in Sprachen Probleme, in denen ein Komma statt eines Punkts als Dezimaltrennzeichen verwendet wird. Alternative:
round(){
local l=$2
[ "$l" == "" ] && l=2 # use 2 decimal places if not specified
echo "scale=$l;(10^$l*$1+0.5)/10^$l" | bc -l | sed 's/^\./0./' # last sed adds leading zero in case of numbers smaller than 1 (bc returns e. g. .7 instead of 0.7)
}
Beispielaufrufe:
round 42/3.14159
round 17/13 7
==== Überprüfen, ob Kernel-Module geladen sind ====
#!/bin/sh
# check if a kernel module is loaded
[ "$1" == "" ] && echo "Usage: $0 MODULE [q]" && exit 0
#if lsmod | grep -Eq "$1" &> /dev/null ; then
if grep -Eq "$1" /proc/modules &> /dev/null ; then
[ "$2" == "q" ] || echo "$1 is loaded!"
exit 0
else
[ "$2" == "q" ] || echo "$1 is not loaded!"
exit 1
fi
{{tag>linux shell bash scripting programming}}