Linux shell / bash / commands cheatsheet

Use VI like tail -f but with syntax highlighting:

  • vi /var/log/syslog
  • :set autoread | au CursorHold * checktime | call feedkeys("lh")
  • press "G" to go to the end of the file

Explain shell commands

https://explainshell.com/

Bash redirection

to file

  • command > stdout.txt
  • command 2> stderr.txt
  • command &> stdout_and_err.txt
  • command > stdout.txt 2> stderr.txt

pipe

  • command |& cat
    • pipe stdout + stderr
  • or older: "command 2>&1 | cat"

Advanced with pipe

  • command | tee stdout.txt    outputs stdout to shell and stdout.txt

Be careful, tee swallows the exit code!

  • false | tee /dev/null;echo $?
    • "0" !!! = the return code of tee. Workaround, use pipefail:
  • set -o pipefail && false | tee /dev/null;echo $?
    • "1" -> good!

TODO: check the following for exit code preservation:

Output stdout+stderr and log to files:

  • command > >(tee --append stdout.txt) 2> >(tee --append stderr.txt >&2) | cat

Ideal for cronjobs: Logs stdout and stderr to the same file, outputs stderr but hides stdout

  • command > >(tee --append command.log > /dev/null) 2> >(tee --append command.log >&2) | cat

From: http://stackoverflow.com/questions/692000/how-do-i-write-stderr-to-a-file-while-using-tee-with-a-pipe
The final "| cat" returns to the prompt

Ignore a certain exit code (e.g. 127) and return 0 instead:

  • mycommand || [ $? -eq 127 ]

Find

Directory wildcards:

  • find /mydir/2022*/tree ...

Find dirname1 or dirname2

  • find /mypath -type d \( -name dirname1 -o -name dirname2 \) -exec echo '{}' \;

Big files:

Find files in directories which may not exist and supress error message "No such file or directory"
(Note: not possible to use "find -exec" together with redirect "2> /dev/null", xargs --no-run-if-empty is necessary for "ls")

  • find /root -type f -name "do*" 2> /dev/null | xargs --no-run-if-empty ls -l
  • find /root -type f -name "do*" 2> /dev/null | xargs rm -v

Cat / Tail / Head

Show from second line onwards (hide first line):

  • tail --lines=+2 my.file

Show 10 lines starting from line 95:

  • tail --lines=+96 my.file | head --lines=10

cut

  • cut --delimiter=" " --field=1

xargs

Limit to one argument, so echo is called for each file of ls:

  • ls -1 | xargs --max-args=1 echo

Watch

Watch with difference highlighting

  • watch --differences ls -la

Watch without clearing the screen

  • while true; do ls -la; sleep 2; done

Watch without clearing the screen and logging

  • while true; do \
        date | tee --append watch.log; \
        ls -la | tee --append watch.log; \
        sleep 2; \
    done

Remove all partitions

dd if=/dev/zero of=/dev/sdb bs=512 count=1

Or safer, because it warns when overwriting active partitions:

wipefs --all /dev/sdb

sgdisk --zap-all /dev/sdb

List all network devices in local network

nmap -sP 192.168.122.1/24

All running processes

ps -aux

Kill a process: kill -9 2745

Log Top 10 Processes

watch -t -n 10 "top -b -n 1 | head -n 17 | tee -a /var/log/top.log"

  • watch -n 10 (every 10 seconds) -t (without header)
  • top -b (batch)  -n 1 (only one iteration/refresh)
  • head -n 17 (show the first 17 lines)
  • tee -a log.log (-a append)

List open ports

netstat -pntl

Number of files in directory

ls -1 | wc -l

Delete files modified older than one month

Values are in minutes

find /var/lib/php/sessions/ -type f -cmin +43200 -delete

Inodes

Inode information:

df -i

Find directory which uses most inodes

find /var -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n

lsof

"list open files" - show all open handels. Can be used as a last resort action to find out who blocks a file/device

lsof | grep /mnt

fatrace

Shows which process access the harddrive (with "-c"  in the current directory)

fatrace -c

Monitor which files a process accesses

strace -p 1234

Log harddrive access

E.g. to find out what wakes up a hdd

  • echo 1 | sudo tee /proc/sys/vm/block_dump
  • tail -f /var/log/syslog | grep sdb

du

total foreach subdir

du --max-depth=1 -h

or

du ./* -shx

Force du to include hidden directories (.dir/)

du .[!.]* * -shx

sort by size, human readable

du -hs ./* | sort -h

 

date

Get the current unix timestamp

date +%s

parted

Get a list of disks

  • parted
    • print devices

Get uuids of disks for fstab

  • blkid

Get uuid for a device

  • blkid -o value -s UUID /dev/sda1

Great overview over disks and partitions

  • lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,TYPE,LABEL

Remove MBR

E.g. from bootable USB-Stick

  • sudo dd if=/dev/zero of=/dev/sdc bs=446 count=1

fsck

  • fsck.ext3 -v -f -c -y /dev/sdb1
  • smartctl -a /dev/sdb

GUI: palimpsest

tcpdump

Look for incoming ssh traffic

tcpdump 'tcp port 80'

iotop

Look for i/o intensive processes

ip link

Show hardware network interfaces

Correct edit time of files

30 minutes in the future. For the past use "30 minutes ago"

touch -d "30 minutes" filename.txt

@see: http://www.cyberciti.biz/tips/linux-unix-get-yesterdays-tomorrows-date.html

Replicate a directory structure as symlinks

  • cp -avs /source/uploads/ /destination/uploads/

Permanently disable a service

systemctl disable smartmontools

Show logs of shutdown / reboots

Display list of last reboot entries: last reboot | less

Display list of last shutdown entries: last -x | less

or more precisely: last -x | grep shutdown | less

Use comments in single line commands

  • date; `# show the current date`; ls -l; `# show contents of current directory`; hostname --fqdn; `# show fqdn of hostname`

Or split to multiple lines for better readability

  • date;             `# show the current date`; \
    ls -l;            `# show contents of current directory`; \
    hostname --fqdn;  `# show fqdn of hostname`

Add user with disabled password

  • adduser --disabled-password myusername

Get current network interface name

ls /sys/class/net | grep enp

Search and Replace with sed

  • sed 's/search/replace/g'
  • sed 's/^search/replace/g'
    • "search" needs to be at the begining of the line

 

diff / patch

diff:

  • diff --unified oldfile newfile > file.patch

patch:

  • patch -i file.patch mytarget

Idempotent patch:

# To be idempotent never reverse the patch (--forward) and don't create .rej files
# We also swallow the warning "Reversed (or previously applied) patch detected!  Skipping patch. 1 out of 1 hunk ignored" with " 2>&1 /dev/null"
# Further more we need to catch the exit code 1 of "hunks ignored". (appended " || [ $? -eq 1 ]")

  • patch --silent --forward --reject-file=- -i file.patch mytarget 2>&1 /dev/null || [ $? -eq 1 ]

 

Add users and groups

Add user and group with no login and password

  • addgroup vmail
  • adduser --disabled-password --no-create-home --gecos "" --shell /usr/sbin/nologin --ingroup vmail vmail

Funky installer one liner