#!/bin/bash
#gestern zur gleichen zeit
date -d '1 day ago' +%FT%T
#vor einem Monat
date -d '1 month ago' +'%FT00:00:00'
#Monatsanfang
date +"%Y-%m-01"
#Zeit von CET in Z(Zulu = UTC+0) (Elli ...)
TZ=Z date +"%Y-%m-%dT%H:%M:00|%s" -d "22 Dec 2020 15:00 CET"
#Heute in Elli
today=$(LC_ALL=en_EN.utf8 date +"%d. %b %Y,")
#Gestern in Elli
yesterday=$(LC_ALL=en_EN.utf8 date --date "1 day ago" +"%d. %b %Y,")
#Vorgestern in 12 Wochen - Impfabstand für astrazeneca
date -d "-2 day +12 weeks"
#aktuelle Zeit in Nanosekunden seit dem 1.1.1970
#womit sich gut Zeiten vergleichen lassen
date +%s%N
#in der bash ab Version 5 - deutlich kürzer, da kein Prozess
#gestartet wird, als Mikrosekunden
echo ${EPOCHREALTIME//./}
printf -v start "%.3f" $EPOCHREALTIME; start=${start//./}
# mit ps Prozesse auflisten
ps -e -o uname:25=,pid=,ppid=,etimes=,comm=,args=
# mit top Prozess beobachten
while true; do top -bn1 -p 5292|tail -n+8; sleep 1; done
In den docker-Containern sind die Tools qrencode und zbarimg aus den Debian-Repos installiert (apt install -y qrencode zbar-tools).
qrencode -o- -s20 "daddeldu 12345" > qr.png
zbarimg -q --nodbus qr.png
Mit ncat lässt sich ein wirklich kleiner Dienst realisieren:
#!/bin/bash
# qrencoder.sh
read line
qrencode -o- -s10 "$line"
# starte mit ncat -k -l -e ./qrencoder.sh localhost 2001
Für einen Test gibt es ein weiteres kleines Skript namens qrrequest.sh:
#!/bin/bash
# qrrequest.sh
echo "daddeldu 123"
cat >&2
# starte mit ncat -e ./request.sh localhost 2001 2>&1 | zbarimg --nodbus -q -
atomically replacing files and directories
Ab demnächst ein Teil von util-linux: exch
Wer ein paar kleine, schnelle sed-Ausdrücke kennt, baut sich schnell das passende Verwaltungstool für Konfigurationsdateien wie .ssh/config:
# entferne alle Zeilen von /pattern1/ bis einschliesslich /pattern2/
sed -i "/pattern1/,/pattern2/d" ~/.ssh/docker_config
# entferne alle Zeilen zwischen /pattern1/ und /pattern2/
sed -i "/pattern1/,/pattern2/{//!d}" ~/.ssh/docker_config
Wenn ich docker-Container baue, in die ich mit ssh springen will, dann hilft es, eine zweite config-Datei zu haben, die in der .ssh/config am Anfang mit Include ~/.ssh/docker_config inkludiert wird. Dann werden beim Aktivieren eines Containers die passenden Zeile dort angehängt und beim Deaktivieren wieder herausgenommen:
# aktivieren
echo "host ${containername} # auto
hostname ${ip}
user user
" >> ~/.ssh/docker_config
# deaktivieren
sed -i "/host ${containername} # auto$/,/^$/{/.*/d}" ~/.ssh/docker_config
Das und mehr unter https://www.grymoire.com/Unix/Sed.html.
#!/bin/bash
for i in {00001..50000}; do
tr -dc "[[:alnum:]]" </dev/urandom |
head -c1000000 |
fold -w60 >/tmp/file$i
done
tr -dc ...
löscht alles außer der angegebenen Zeichenklasse.</dev/urandom
leitet die Eingabe aus dem Pseudozufalls-Device um. {00001..50000}
produziert die Zahlen in dem Bereich mit führenden Nullen. head -c...
schneidet die ersten Character heraus. fold -w60
bricht Zeilen nach maximal 60 Charactern um.
#!/bin/bash
for i in {00001..50000}; do
md5sum /tmp/file$i
done > /tmp/hashes
Oder einfach direkt in der Shell ohne Schleife:
find /tmp/ -name 'file*' | xargs md5sum > /tmp/hashes
doc.tex
:
\documentclass{scrartcl}
\newcommand{\vorname}{NIX}
\begin{document}
\input{datafile}
Der Wert dieses Datensatzes: \vorname
\end{document}
Und in der Datei datafile.tex
:
\renewcommand{\vorname}{Oliver}
Aber Achtung: Hacking with LaTeX
Mindestens: in dem Verzeichnis ~/.texmf die Datei texmf.cnf anlegen mit dem Inhalt:
openin_any = p
openout_any = p
Zusätzlich beim Aufruf -no-shell-exec
mitgeben. Mit den Mechanismen lässt sich
allerdings (siehe oben) das Lesen von beliebigen Dateien leider nicht verhindern.
:iab dts strftime("%Y-%m-%d")
eintragen, koennen Sie im Text durch Tippen
von dtsdas aktuelle Datum einfuegen.
Das ist der empfohlene Weg: Den regulären Ausdruck einer Variablen zuweisen und dann in doppelten eckigen Klammern ohne doppelte Anführungszeichen darauf zugreifen:
RE="^list|depl$"
[[ "$SSH_ORIGINAL_COMMAND" =~ $RE ]] || exit 1
Im Netz finden sich mancherlei Seiten, auf denen Kommandos zu markieren sind, um sie direkt in die Kommandozeile zu kopieren. Kopieren Sie einmal die folgende Zeile und pasten Sie sie in das Eingabefeld darunter.
echo cool stuff for lazy$(echo and stupid) admins
oder gleich in die Kommandozeile. Dass an der Stelle
$(echo and stupid)
genauso gut etwas sehr
gefährliches stehen könnte, versteht sich von selbst. Also
Obacht...
psql -t -AF $'\t' -c "select * from employees;" | \
while IFS=$'\t' read a b c; do echo "$a,$b,$c"; done
In der Bash kann mit $'\0'
das Nullbyte ausgegeben werden. Als
Delimiter bei *read* sorgt es dafür, dass auch Newlines und Tabs einzeln
eingelesen werden. Mit "$'$CH"
wird der Inhalt der Variablen
wieder ausgegeben - und kann so an printf %d
übergeben werden,
damit der hexcode ausgegeben wird.
echo -e "moin\nmoin\tmoin"| \
while read -d $'\0' -N1 CH ; do
echo "[$CH]"
# printf "%d\n" "'$CH"; # als Integer (%x hex)
done
Das Nullbyte und der Slash sind die einzigen Zeichen, die in einem Unix-Dateinamen nicht enthalten sein können. Der Befehl *find* traversiert das Dateisystem von dem ersten Argument aus - -print0 trennt die Namen dann mit dem Nullbyte.
while IFS= read -r -d $'\0' file; do
echo "$file"
done < <(find . -print0)
Es gibt verschiedene Wege, mit indirekten Variablen umzugehen:
mykey=k456
declare index_$mykey=value123 # bash specific
eval "index_$mykey=value123" # posix compatible
read index_$mykey <<<"value123"
printf -v index_$mykey "value123"
eval "echo \$$index_$mykey"
refname=index_k456
echo ${!refname} # indirect access
Sie werden insbesondere zu der eval-basierten Lösung harsche Kommentare im Netz finden ('eval is evil') - aber denken Sie selber nach, welche Risiken damit wann verbunden sind...
Oft ist es sinnvoller - so die Bash ab Version 4 verfügbar ist - mit Arrays oder assoziativen Arrays (Hashmaps) zu arbeiten:
declare -a myarray #index array
for i in {0..9}; do
myarray[$i]=value$i
done
myarray+=(dynamicappend)
for i in "${myarray[@]}"; do echo "$i"; done
echo "size: ${#myarray[@]}"
declare -A mykeystomyvalues # associative array
mykeystomyvalues[a456]="maybeacomplexvalue"
echo ${mykeystomyvalues[a456]}
for v in "${mykeystomyvalues[@]}"; do echo value: "$v"; done
for k in "${!mykeystomyvalues[@]}"; do
echo key: "$k" value: "${mykeystomyvalues[$k]}";
done
Dazu kommt, dass indizierte Arrays in der Bash sparse strukturiert sind (anders als beispielsweise in Java): Das heisst,
num=$((2**63-1))
mykeys[$num]=myvalue
echo ${mykeys[$num]}
geht, ohne dass 2^63-1 Array-Elemente alloziert werden. Solange es sich also bei den Schlüsseln um Zahlenwerte handelt, verhalten sich indizierte Arrays in der Bash wie Hashmaps.