====== Bash ======
FIXME
CheatSheet: https://devhints.io/bash
==== root-check ====
if [ $UID -eq 0 ];then echo "root";fi
==== online-check ====
ping -c 1 ${HOST} -W 1 >/dev/null
if [ $? -eq 0 ];
then
echo "host is alive"
fi
==== Dateigröße ====
fs=$(wc -c < file)
if [ $fs -eq 0 ];
then
echo "file is empty"
fi
==== Massen-Datei-Verarbeitung ====
for file in *.html
do
mv "$file" "${file%.html}.txt"
#"${file%.*}.txt"
done
#auch gut, um z.b. von mehreren Dateien die Checksumme zu errechnen und in gleichnamiger Datei zu hinterlegen
for file in *.gz; do md5sum "$file" >"$file.md5";done
#auch mit der Klammern-Auswertung lassen sich bestimmte Sachen machen
ls *.{php,html}
==== Farben ====
clr_red=$'\e[1;31m'
clr_green=$'\e[1;32m'
clr_yellow=$'\e[1;33m'
clr_blue=$'\e[1;34m'
clr_reset=$'\e[0m'
echo ${clr_red}test${clr_reset}
==== logging ====
einzelnen Befehl mitloggen (nur stderr) und gleichzeitig anzeigen (stdout+stderr)
#via Process Substitution (https://www.gnu.org/software/bash/manual/bash.html#Process-Substitution)
make 2> >( tee "$logfile" ) ; echo $?
ganzen Block mitloggen:
exec 3> >(tee logfile)
make alpha 2>&3 &&
make bravo 2>&3 &&
make charlie 2>&3 && success=1
exec 3>&-
komplettes script mitloggen (mit Anzeige):
exec &> >(tee -a "$logfile")
Möglichkeiten echo an stderr zu schicken:
echoerr() { echo "$@" 1>&2; }
echoerr hello world
https://stackoverflow.com/a/2990533
==== Debug-Modus ====
am Anfang des Scripts:
test -n "$DEBUG" && set -x
#Anzeige der aktuellen Datei (funktioniert auch wenn ge-source-d)
test -n "$DEBUG" && echo ${BASH_SOURCE[0]}
Aufruf mit:
DEBUG=y script.sh
ggf. mit PS4 die Ausgabe anpassen ([[https://qastack.com.de/server/16204/how-to-make-bash-scripts-print-out-every-command-before-it-executes|Quelle]])
PS4='Line $LINENO @ $(date +%s.%N): ' bash -x script
==== vorherige Instanzen beenden ====
#kill previous instances of current script
script_name=${BASH_SOURCE[0]}
for pid in $(pidof -x $script_name); do
if [ $pid != $$ ]; then
kill -9 $pid
fi
done
https://unix.stackexchange.com/a/213293
==== Case ====
case "$string" in
*foo*)
# irgendwas
;;
[1-6]*)
#zahlenbereiche
;;
"2" | "3")
multiple values
;;
*)
#alles andere
;;
esac
fallthrough (;&) and resume (;;&) https://stackoverflow.com/a/24544780
==== arrays ====
arr=(a b c d e f g h)
arr[8]="i"
unset arr[2] #entfernt 3. Element
echo ${arr[@]} #ganzes Array anzeigen
echo ${#arr[@]} #Anzahl der Elemente
arr+=('foo') #Element anhängen
==== Eingabe mit Vorbelegung ====
name="uImage"
read -e -i "$name" -p "Please enter filename: " input
name="${input:-$name}"
==== Stringmanipulation ====
In Bash 4:
alles klein
$ echo "${string,,}"
alles groß:
$ echo "${string^^}"
[[https://stackoverflow.com/questions/2264428/converting-string-to-lower-case-in-bash|Quelle]]
=== Pfad / Verzeichnis ===
$ VAR=/home/me/mydir/file.c
$ DIR=$(dirname "${VAR}")
$ echo "${DIR}"
/home/me/mydir
$ basename "${VAR}"
file.c
~% FILE="example.tar.gz"
~% echo "${FILE%%.*}"
example
~% echo "${FILE%.*}"
example.tar
~% echo "${FILE#*.}"
tar.gz
~% echo "${FILE##*.}"
gz
mehr infos [[https://linuxgazette.net/18/bash.html|hier]]
=== Teilstrings ===
a=string
b=${a:p:l}
#p=Position (0-basiert),l=Länge
=== ersetzen ===
orig="AxxBCyyyDEFzzLMN"
mod=${orig//[xyz]/_}
=== Regex-Prüfung ===
string='My string';
if [[ $string =~ .*My.* ]]
then
echo "It's there!"
fi
=== Split via Trennzeichen ===
OLDIFS="$IFS"
IFS='|' read -r -a array <<< "$str"
#echo "array ("${#array[@]}"): "${array[@]};
#echo "first item: ${array[0]}"
IFS="$OLDIFS"
Alternative wenn mehrere Teile direkt weiterverwendet werden sollen (hier Berechnung der nächsten Kernelversion für inkrementellen Patch):
k=$(make kernelversion)
#4.4.140
kn=$(echo $k|awk -F. '{print $1"."$2"."($3+1)}')
#4.4.141
kf=$(echo $k|awk -F. '{print $1"."$2"."$3"-"($3+1)}')
#4.4.140-141
=== string mehrfach ===
printf '=%.0s' {1..100};echo
https://stackoverflow.com/questions/5349718/how-can-i-repeat-a-character-in-bash
==== rechnen ====
GPIO_NO=$((232+25))
alternativ (z.B. für array-Index)
COL=0
id=${array[$[ COL++ ]]}
Ausführzeit
P1=$(date +%s) #starttime as unix-time
#do something
P2=$(date +%s) #endtime as unixtime
echo $[$P2-$P1] #calculate and print the difference
==== Zahlenbereiche ====
ls IMG_20170923_{17..18}*
==== Sprache ====
kurzzeitig umstellen (z.b. um Fehlermeldungen auf englisch zu bekommen für Foren):
LANG=C
==== Prompt ====
export PS1="[\D{%F %T}] \u@\h\n\w$"
in die ~/.bashrc
Farben lassen sich so realisieren
\[\033[1;31m\] => rot
\[\033[1;32m\] => grün
\[\033[1;33m\] => gelb
https://wiki.ubuntuusers.de/Bash/Prompt/#Farben
==== LS_COLORS ====
export LS_COLORS='di=1;32:fi=0:ln=31:pi=5:so=5:bd=5:cd=5:or=31:mi=0:ex=35:*~=90:*.bak=90:*.zip=35:*.tar=35:*.gz=35:*.bz2=35'
[[http://www.bigsoft.co.uk/blog/2008/04/11/configuring-ls_colors]]
=== Farben temporär deaktivieren ===
\ls
Oder
dir
==== Zeit-Darstellung ====
eigene locale für Datum nehmen
LC_ALL=de_DE.utf8 date '+%x'
eigene Zeitzone
export TZ=Europe/Berlin
dt=$(date +"%Y-%m-%d %H:%M:%S")
==== Zeitrechnung ====
Zeitstempel als String (für Backups)
D=$(date +"%Y-%m-%d %H:%M:%S")
Zeitrechnung (+1 Tag)
DT=$(date -d "+1 day" +"%Y-%m-%d")
Umrechnung in Unix-Zeitstempel
date -d "2018-06-14 03:00:00" +%s
1528938000
Unix-Zeitstempel zurückformatieren
date -d "@1528938000" "+%d.%m.%y %H:%M:%S"
14.06.18 03:00:00
Berechung (MySQL-Zeitstempel -10 Minuten)
sd=$(date -d "2018-06-14 03:00:00" +%s)
sd2=$(($sd-10*60))
date -d "@$sd2" "+%y-%m-%d %H:%M:%S"
18-06-14 02:50:00
==== MySQL in Bash ====
H=host
U=user
P=password
D=database
T=table
LOGFILE=/tmp/script.log
Q="SELECT * FROM $T";
data=$(mysql -h$H -u$U -p$P -D$D -Bse "$Q" 2>&1)
[ $? = 0 ] || echo $data >> $LOGFILE
while read line; do
echo "Zeile: $line"
IFS=$'\t' read -ra STR_ARRAY <<< "$line"
echo "1st col: ${STR_ARRAY[0]}"
echo "2nd col: ${STR_ARRAY[1]}"
echo "3rd col: ${STR_ARRAY[2]}"
done <<< "$data"
==== Grep ====
nach mehreren Strings suchen (ODER)
grep 'echo\|then' file.txt
regex
grep 'e[c][h]o' file.txt
==== SED ====
suchen ersetzen
sed 's/echo/blah/' file.txt
sed 's/\(echo\)/blah_\1/' file.txt
Mehrfach-Ersetzung:
sed -e 's/a/b/g ; s/b/d/g' file
sed -ibak -e 's/a/b/g' -e 's/b/d/g' file
https://unix.stackexchange.com/questions/268640/make-multiple-edits-with-a-single-call-to-sed#
text zwischen Start- und Endmarkierung ausgeben
sed -n -e '/^BEGIN$/,/^END$/{//!p}' file.txt
==== diff ====
git diff ähnliche Ausgabe
diff -urpN
==== tar ====
Zielverzeichnis angeben
tar -C $dir -xzf $file
System-backup
tar -cvpzf backup.tar.gz --exclude=backup.tar.gz --one-file-system /
==== Parameter parsen ====
[[https://gist.github.com/jehiah/855086]]
#!/bin/bash
LOG=0
TEST=0
usage() {
echo "$0 allowed options:"
echo -e '\t -l|--log|--logging\tenable Logging'
echo -e '\t -t|--test\tenable Testmode'
}
while [ "$1" != "" ]; do
PARAM=$(echo $1 | awk -F= '{print $1}')
VALUE=$(echo $1 | sed 's/^[^=]*=//g')
echo $PARAM"=>"$VALUE
case $PARAM in
-l|--log|--logging)
echo "LOG"
LOG=1;
;;
-t|--test)
echo "TEST"
TEST=1;
;;
*)
echo "ERROR: unknown parameter \"$PARAM\""
usage
exit 1
;;
esac
shift
done
==== ip-adresse ====
ip -4 -o addr show enp3s0 | sed 's/^.*inet \(.*\) brd.*$/\1/'
==== find / exec ====
find . -name '*.rej' -exec rm {} \+
==== Dateien umbenennen/an programme geben ====
OLDIFS=$IFS;IFS=$'\n'; for i in *.mp4; do ffmpeg -i "$i" "${i%.*}.mp3";done;IFS=$OLDIFS;
mögliche Alternative (ganz unten wg. Whitespaces):
https://unix.stackexchange.com/questions/114908/bash-script-to-convert-all-flac-to-mp3-with-ffmpeg
==== alias / oneline function ====
alias t='...'
unalias t
hxd() { hd "$1" | less; }
==== git info ====
parseGitBranch() {
git rev-parse --abbrev-ref HEAD 2> /dev/null | sed -e 's/\(.*\)/(\1)/'
}
gitstatus() {
status=$(git status --short 2> /dev/null)
if [[ $? -eq 0 ]];then
modified=$(echo "$status"|grep "^.\?M" | wc -l)
untracked=$(echo "$status"|grep "??" | wc -l)
echo " [${modified}M${untracked}U]";
fi
}
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\] $(parseGitBranch)$(gitstatus)\n\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w $(parseGitBranch)$(gitstatus)\n\$ '
fi
unset color_prompt force_color_prompt
==== xterm title ====
trap 'echo -ne "\033]0;$BASH_COMMAND\007"' DEBUG
function show_name(){
if [[ -n "$BASH_COMMAND" ]];
then
echo -en "\033]0;$(basename $(pwd))\007";
else
echo -en "\033]0;$BASH_COMMAND\007";
fi
}
export PROMPT_COMMAND='show_name'
https://unix.stackexchange.com/a/91796