Shell
Basic loop to iterate over lines in a file
Section titled “Basic loop to iterate over lines in a file”for pkg in $(cat pkgs.txt); do sudo apt purge "$pkg" -y; doneMore complex loop using ‘if’ statement
Section titled “More complex loop using ‘if’ statement”Useful for control actions, cleaning up output, etc.
for node in $(cat nodes.txt); do \ echo "Node: ${node}"; \ ssh -q -t "$node" 'if [[ $(lsblk | grep -i lvm) ]]; then sudo apt install mdadm -y; fi'; \doneChecking busy log files for their contents
Section titled “Checking busy log files for their contents”This does not hang your console as opposed to using tail -f.
watch -n 0.5 sudo tail /var/log/named/queries.logAlternative conditional logic in loop
Section titled “Alternative conditional logic in loop”Declare nodes variable separately or prepend to loop and separate with semicolon.
for node in "${nodes[@]}"; do \ ping -c 2 -W 0.1 "$node" > /dev/null && \ echo "OK: ${node}" || echo "NOT OK: ${node}"; \done‘while’ loop to iterate over lines in a file
Section titled “‘while’ loop to iterate over lines in a file”Avoids calls to cat as is the case with the for loop example. Using madison command rather than policy seems to be slightly faster.
while read pkg; do \ if [[ $(apt-cache madison "$pkg") ]]; then \ echo "OK: ${pkg} exists in some repo"; \ else \ echo "NOT OK: ${pkg} doesn't exist in any repo"; \ fi; \done < pkgs.txtMatch lines into an array
Section titled “Match lines into an array”types=($(grep -oE 'pattern' input.txt))Grab block of text between two patterns
Section titled “Grab block of text between two patterns”sed -n '/pattern1/,/pattern2/p' input.txtOctal permissions for a file or directory
Section titled “Octal permissions for a file or directory”stat -c '%a' /etc/passwdGrab last character from string
Section titled “Grab last character from string”last_character=${string_variable:-1}Parse output of ‘grep’ into commands
Section titled “Parse output of ‘grep’ into commands”grep -rl '\-\- MARK \-\-' /var/log/* | \ while read line; do \ echo "Working with file '${line}'"; \ grep MARK "$line" | tail -n1; \ doneInclude lines before/after a ‘grep’ match
Section titled “Include lines before/after a ‘grep’ match”grep -B 3 -A 3 -i "hv_fcopy" /var/log/messagesFind all unique directories in listed directories that contain files modified 10 minutes ago since the command was ran
Section titled “Find all unique directories in listed directories that contain files modified 10 minutes ago since the command was ran”ls | xargs -I {} find {} -type f -mmin -10 | cut -d "/" -f2 | sort -uFind all files in the current directories that were modified at least a minute ago, are larger than 500MB, and long list them
Section titled “Find all files in the current directories that were modified at least a minute ago, are larger than 500MB, and long list them”find . -type f -mmin -1 -size +500M -exec ls -lsh {} \;Find all files in the current directories that were modified at least a day ago, are larger than 2GB, and empty their contents
Section titled “Find all files in the current directories that were modified at least a day ago, are larger than 2GB, and empty their contents”find . -type f -mtime -1 -size +2G -exec bash -c 'echo > {}' \;Run command against a list of directories
Section titled “Run command against a list of directories”ls | xargs -I {} git -C {} pullStep-by-step debug Bash scripts
Section titled “Step-by-step debug Bash scripts”Move ahead with Enter key.
set -xtrap read debugChange timezone interactively
Section titled “Change timezone interactively”dpkg-reconfigure tzdataSearch binary file while ignoring case
Section titled “Search binary file while ignoring case”grep -ai "end:" /var/log/syslogSystem call info for a directory listing
Section titled “System call info for a directory listing”strace -c ls test/Show line number during script run
Section titled “Show line number during script run”echo "DEBUG: ${LINENO}"Remove duplicated lines in order
Section titled “Remove duplicated lines in order”awk '!visited[$0]++' your_file > deduplicated_fileRun local script on a remote endpoint
Section titled “Run local script on a remote endpoint”ssh -q <username>@<endpoint> "sudo bash -s" < local_script.shCreate new directory and change into it
Section titled “Create new directory and change into it”mkdir new_directory && cd $_function mkcd () { mkdir "$1" cd "$1"}From here.
Recall argument to last used command
Section titled “Recall argument to last used command”$_!$Alt + .!:1!:1-2From here.
Get SSH key fingerprint
Section titled “Get SSH key fingerprint”ssh-keygen -lf ~/.ssh/id_rsa.pubssh-keygen -E md5 -lf ~/.ssh/id_rsa.pubFind broken symbolic links
Section titled “Find broken symbolic links”find . -xtype lBulk fix relative symbolic links
Section titled “Bulk fix relative symbolic links”find . -lname '<relative-to-source target>*' \ -exec sh -c 'ln -sfn "<new relative-to-source target>/$(basename $0)" $0' {} \;Run remote script on remote endpoint
Section titled “Run remote script on remote endpoint”ssh -q <username>@<endpoint> './location/to/script'Create ISO from directory
Section titled “Create ISO from directory”The -l doesn’t truncate long names and hyphens with underscores aren’t replaced using -iso-level 4.
genisoimage -o data.iso -iso-level 4 -R -l data/List ISO file contents without mounting
Section titled “List ISO file contents without mounting”isoinfo -l -i data.isoSimple colouring for log files
Section titled “Simple colouring for log files”Works for both static and running output.
cat test.log | perl -pe 's/^\[\*\].*/\e[0;36m$&\e[0m/g; s/^\[\+\].*/\e[0;32m$&\e[0m/g; s/^\[\!\].*/\e[0;31m$&\e[0m/g'From here.
Suppress Python warnings
Section titled “Suppress Python warnings”For situations like these.
export PYTHONWARNINGS='ignore'Remove last column using delimiter
Section titled “Remove last column using delimiter”$ string='my_underscored_string_12345'$ echo "$string" | rev | cut -d '_' -f 2- | revmy_underscored_stringDisregard alias execution
Section titled “Disregard alias execution”$ halt -pREALLY!? -p$ alias haltalias halt='echo "REALLY!?"'$ \halt -pConnection to example.com closed by remote host.Pretty print CSV files
Section titled “Pretty print CSV files”function pretty_csv { perl -pe 's/((?<=,)|(?<=^)),/ ,/g;' "$@" | column -t -s, | less -F -S -X -K}
pretty_csv data.csvpretty_csv < data.csvsort data.csv | pretty_csvFrom here
Pretty print TSV files
Section titled “Pretty print TSV files”function pretty_tsv { perl -pe 's/((?<=\t)|(?<=^))\t/ \t/g;' "$@" | column -t -s $'\t' | less -F -S -X -K}
pretty_tsv data.tsvpretty_tsv < data.tsvsort data.tsv | pretty_tsvDiff two files and save output to file
Section titled “Diff two files and save output to file”diff -u file1 file2 > files.diffShow build information for cloud image
Section titled “Show build information for cloud image”$ cat /etc/cloud/build.infobuild_name: serverserial: 20201211.1Show top disk usage and exclude directories
Section titled “Show top disk usage and exclude directories”du -Sh / --exclude=/{proc,sys,dev,var} | sort -rh | head -n 10Use ’:’ for an infinite loop
Section titled “Use ’:’ for an infinite loop”while :; do "looping"; doneExecute Bash to ‘unsource’ variables
Section titled “Execute Bash to ‘unsource’ variables”exec /bin/bashUse binary version of ‘time’
Section titled “Use binary version of ‘time’”This provides access to more information.
$(which time) --verbose echo "test"From here.
Use ‘perf stat’ to repeat a command
Section titled “Use ‘perf stat’ to repeat a command”Also provides additional useful measurements.
perf stat --null --repeat 5 --table echo "test"More examples here.
Change key value in array of JSON
Section titled “Change key value in array of JSON”.parameters.vmObjects.value |= map(if .vmName == "router" then .moduleSnapshot = "fixed" else . end)Use indirect references for dynamic variables
Section titled “Use indirect references for dynamic variables”for host in "${hosts[@]}"; do declare "parent_disk_${host}=$parent_disk"done
for host in "${hosts[@]}"; do parent_disk="parent_disk_${host}" echo "${!parent_disk}"doneTest terminal’s colors
Section titled “Test terminal’s colors”msgcat --color=testBulk rename files in place
Section titled “Bulk rename files in place”find . -type f -name '<file name>' -execdir mv {} "description.txt" \;Encode with Base64 on a single line
Section titled “Encode with Base64 on a single line”echo "text" | base64 -w 0Convert PEM to single-line
Section titled “Convert PEM to single-line”awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' combined.pemStandard output to a new directory
Section titled “Standard output to a new directory”echo "something" | install -D /dev/stdin directory/file.txtFind and delete files older than 1 year
Section titled “Find and delete files older than 1 year”find /the/dir/to/start/in -type f -mtime +365 -ls -exec rm -f -- {} \;View permissions as a tree
Section titled “View permissions as a tree”-p: permissions-u: username/userid-f: full path-i: don’t print indentation lines-d: print directories only
tree -pufidUse wildcard in ‘pip uninstall’
Section titled “Use wildcard in ‘pip uninstall’”pip freeze | grep "azure*" | xargs -n 1 pip uninstall -yShow transaction history for a package
Section titled “Show transaction history for a package”dnf history list <package>Show transaction’s historical info
Section titled “Show transaction’s historical info”dnf history info <transaction ID>More on ‘history’
Undo last transaction
Section titled “Undo last transaction”dnf history undo lastList SystemD timers
Section titled “List SystemD timers”systemctl list-timersShow execution of timer and service
Section titled “Show execution of timer and service”journalctl -u name.timerjournalctl -u name.serviceCopy remote directory to local system
Section titled “Copy remote directory to local system”rsync -azvhP <user>@<remote>:<remote path> <local path>scp -rCp <user>@<remote>:<remote path> <local path>Overwrite existing directory
Section titled “Overwrite existing directory”rsync -av --delete ~/new/ ~/oldCount number of installed kernels
Section titled “Count number of installed kernels”$ sudo dnf list --installed kernel-core* | tail -n +2 | wc -l9Increase number of installed kernels
Section titled “Increase number of installed kernels”This goes in /etc/dnf/dnf.conf.
...installonly_limit=10...Pin specific kernel version
Section titled “Pin specific kernel version”$ sudo dnf install python3-dnf-plugins-extras-versionlock$ # List kernel packages$ rpm -qa kernelkernel-6.0.18-300.fc37.x86_64kernel-6.1.7-200.fc37.x86_64kernel-6.1.8-200.fc37.x86_64$ Add pin$ sudo dnf versionlock add kernel-6.0.18-300.fc37.x86_64Last metadata expiration check: 3:51:11 ago on E 30 jaan 2023 15:47:21.Adding versionlock on: kernel-0:6.0.18-300.fc37.*$ # Remove pin$ sudo dnf versionlock delete kernel-6.0.18-300.fc37.x86_64...Undo ad hoc changes made to a service
Section titled “Undo ad hoc changes made to a service”For example systemd-resolved.
$ systemctl revert systemd-resolved.serviceRemoved "/etc/systemd/system/systemd-resolved.service.d/override.conf".Removed "/etc/systemd/system/systemd-resolved.service.d".$ systemctl restart systemd-resolved.serviceBack up a file using brace expansion
Section titled “Back up a file using brace expansion”Equivalent to cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.
cp /etc/ssh/sshd_config{,.bak}The same can be applied to directories:
cp -aR public{,.bak}More on brace expansion.
Restore a backed up file
Section titled “Restore a backed up file”Equivalent to cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config.
cp /etc/ssh/sshd_config{.bak,}Download older version of a kernel
Section titled “Download older version of a kernel”koji download-build --arch=x86_64 <kernel package name>- More information about Koji
- A list of all kernels built for Fedora
- A list of downloadable kernels built for Fedora
- Some may be removed
Fedora Discussion here.
Parallel execution of lines from a file
Section titled “Parallel execution of lines from a file”readarray -t items < items.txtparallel -kj 20 echo {1} ::: "${items[@]}"Verify SSL certificate against domain
Section titled “Verify SSL certificate against domain”openssl s_client -connect google.com:443 2> /dev/null | openssl x509 -noout -datesRun programs with ‘systemd-run’
Section titled “Run programs with ‘systemd-run’”This will leverage SystemD’s features.
$ systemd-run envRunning as unit: run-19945.service$ journalctl -u run-19945.serviceSep 08 07:37:21 bupkis systemd[1]: Starting /usr/bin/env...Sep 08 07:37:21 bupkis systemd[1]: Started /usr/bin/env.Sep 08 07:37:21 bupkis env[19948]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binSep 08 07:37:21 bupkis env[19948]: LANG=en_US.UTF-8Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20.x86_64Documentation here.
Working with ‘screen’
Section titled “Working with ‘screen’”- Start a session:
screen - Start any long-running commands
- Detach from session:
Ctrl+A+D - List sessions:
screen -ls - Attach to a running session:
screen -r <session ID>
Don’t send anything identifiable over SSH
Section titled “Don’t send anything identifiable over SSH”ssh -a -i /dev/null -o IdentityAgent=/dev/null whoami.filippo.ioUsing Ctrl keys
Section titled “Using Ctrl keys”Ctrl + a: move to the beginning of the lineCtrl + d: if you’ve type something, it deletes the character under the cursor, otherwise it quits the current shellCtrl + e: move to the end of the lineCtrl + k: delete all text from the cursor to the end of the lineCtrl + l: equivalent to clearCtrl + p: same as Up arrowCtrl + n: same as Down arrowCtrl + s: to stop output to terminalCtrl + q: to resume output to terminal afterCtrl + sCtrl + r: begins a backward search through command history, keep pressing to continue moving backwardsCtrl + t: transpose the character before the cursor with the one under the cursorEsc + t: transposes the two words before the cursor
Ctrl + u: cut the line before the cursorCtrl + yto paste it
Ctrl + w: cut the word before the cursorCtrl + yto paste it
Ctrl + x + Backspace: delete all text from the beginning of line to the cursorCtrl + x + Ctrl + e: launch editor defined by$EDITORto input your command- exit the editor (e.g.
wq) and the command will be ran automatically - useful for multi-line commands
- exit the editor (e.g.
Ctrl + z: stop current running process and keep it in backgroundfgto continue the process in the foregroundbgto continue the process in the background
Ctrl + _: undo typing
From here.
Use ampersand in ‘sed’ for efficiency
Section titled “Use ampersand in ‘sed’ for efficiency”The ampersand means that the entirety of what was matched will be used in the replacement.
sed 's/create/&-repo/' input.txt