This cheat sheet provides a quick reference guide for common Linux and shell commands. Whether you’re a beginner or an experienced user, these commands will help you navigate the Linux environment more efficiently.
Services
# list systemd units
systemctl list-units --no-pager --type=service
# service status
systemctl status ufw.service
systemctl stop sshd
systemctl start sshd
systemctl status sshd
systemctl is-active sshd
systemctl is-failed sshd
systemctl restart sshd
systemctl reload sshd # re-reads the configuration of the service configs
systemctl daemon-reload sshd # re-reads the configuration of the systemd configs of this service
systemctl enable sshd
systemctl disable sshd
systemctl is-system-running # running, degraded, maintenance, initializing, starting, stopping
systemctl --failed
journalctl # show all journal
journalctl --no-pager # do not use less
journalctl -n 10 # only 10 lines
journalctl -S -1d # last 1 day
journalctl -xe # last few logs
journalctl -u ntp # only ntp unit
journalctl _PID=1234Text filtering
# sort by filesize
ls -lS /path/to/folder/
# cat -n gives line numbers
ls | cat -n
# line numbering
nl test.txt
# split file in 10 lines
split -l 10 test.txt prefix_
# get back original file
cat filename* > originalfile
# tail logs
tail -f logs.txt
# split text into 1-2,4 parts with delimiter ' '
cut -d ' ' -f 1-2,4 test.txt
# shuffle lines
shuf test.txt > shuffled.txt
# sort
sort test.txt
# unique line filtering and count
sort test.txt | uniq -c
# replace chars
cat test.txt | tr 'o' 'O'
# count lines
wc -l test.txt
# count words in file
cat file.txt | grep -o -i example | wc -l
# sed regex
sed -r "s/(Z|R|J)/starts with ZRJ/" friends.txt
# substitute (find and replace) "foo" with "bar" on each line
sed 's/foo/bar/' # replaces only 1st instance in a line
sed 's/foo/bar/4' # replaces only 4th instance in a line
sed 's/foo/bar/g' # replaces ALL instances in a line
sed 's/\(.*\)foo\(.*foo\)/\1bar\2/' # replace the next-to-last case
sed 's/\(.*\)foo/\1bar/' # replace only the last case
# substitute "foo" with "bar" ONLY for lines which contain "baz"
sed '/baz/s/foo/bar/g'grep
# extended regex grep
grep -E "a|b" wordsDisk Layout & Filesystem Hierarchy Standard (FHS)
fdisk /dev/sda
mountDebugging boot loader (grub2)
cat /boot/efi/EFI/ubuntu/grub.cfgDebian package management
# pkg sources
cat /etc/apt/sources.list
# check the files and directories a package installed
dpkg -L bzr
# fix broken pkgs
apt install -f
# show pkg info
apt info pkg
# search pkg
apt search pkg
# rm unneeded pkg deps
apt autoremove
Basic Shell Stuff
# what shell is used
readlink /bin/sh # or echo $SHELL
# find out stuff about bins
which ls
whatis ls
whereis ls
# current location
pwd
# info on system
uname -a
# add stuff to PATH
PATH=$PATH:~/opt/bin # persist in .profile
# run last cmd
!!Basic Hashing
md5sum test.txt
sha256sum test.txt
sha512sum test.txtFile Management
# copy 3 letter files
cp ???.* /tmp
# move files containing _.
mv *[_.]* /tmp
# create nested dirs
mkdir -p test/test1/test2
# check file type
file test.txt
# list only files
ls -p | grep -v /
# find case insensitive files starting with a-c
find . f -iname "[a-c]*"
# find & exec on all files altered in the last hour
find . -mmin -60 -exec echo {} \;
# find & rename
find . -name "*.htm" -exec mv '{}' '{}l' \;Compression
# zip
gzip test.txt
# unzip
gunzip test.txt
# tar & compress
tar cvzf file.tar.gz *.txt
# tar extract
tar xvzf file.tar.gzStreams, Redirects, Pipes
Streams: 0 stdin, 1 stdout, 2 stderr
| Symbol | Description |
|---|---|
> | STDOUT to file (overwrite) |
>> | STDOUT to file (append) |
2> | STDERR to file (overwrite) |
2>> | STDERR to file (append) |
&> | STDOUT & STDERR to file (overwrite) |
&>> | STDOUT & STDERR to file (append) |
< | STDIN from file |
<> | Redirect STDIN from the file and send the STDOUT to it |
# example
$ ls
bob jack jadi linus sara who_uses_what.txt
$ ls x*
ls: x*: No such file or directory
$ ls j*
jack jadi
$ ls j* x* > output 2> errors
$ cat output
jack
jadi
$ cat errors
ls: x*: No such file or directory
# &1 and &2 and &0 to refer to the target of STDOUT, STDERR & STDIN
# example: redirect output to file1 and output stderr to same place as stdout (file1)
ls > file1 2>&1
# send errs into abyss
ls j* x* > file1 2>/dev/null
# pipes
cut -f2 -d, who_uses_what.txt | sed -e 's/ //g' | sort | uniq -c | sort -nrxargs & tee
# execute sth on lines
ls -1 | xargs -I HERE echo these HERE are files
# tee (2x stdout)
ls | tee file.txtManaging Processes
# show processes
ps -aux | less
ps -A
ps -e | grep -E 'firefox|chrome'
pstree # tree like process view
# info on threads
ps -eLf
# lookup process by name
pgrep docker
# run binary in background
somebin &
# check jobs with process id
jobs -l
# bring job back to foreground
fg %1
# run independent of shell
nohup script.sh > mynohup.out 2>&1 &
# kill process
kill 8733
kill -15 8733 # default (TERM)
kill -9 8733 # force kill (KILL)
# kill by name
pkill docker
# kill all ps with given name
killall sleep
uptime
# 13:51:49 up 161 days, 4:56, 1 user, load average: 0.00, 0.05, 0.02top
| key during top | functionality |
|---|---|
| h | help |
| q | quit |
| M | sort based on memory usage |
| c | show full commands |
| k | kill after asking pid and signal |
| P | sort based on CPU usage |
tmux
The default command prefix is Ctrl+B and after running the tmux new you can issue these:
| Key | Usage |
|---|---|
| % | Split current window vertically |
| ” | Split current window horizontally |
| D | Detach from the current window |
| & | Kill current window |
| c | new window |
You can list the tmux sessions using tmux ls and re-attach to one using tmux att to connect to the last one or tmux att -t session_name to attach to a specific one.
Filesystem Checking
# free & used space on file systems
df -h
# check used space on specific dirs
du -h .
du -h --max-dept 1 /home/
# show block devices
lsblk
# check filesystem
fsck /dev/sdb
# show auto mounts
cat /etc/fstab
# list mounted fs
mount
# mount & unmount
sudo mount -t ext4 /dev/sda3 /media/mydisk
sudo umount /dev/sda3
sudo umount /media/mydiskFile Permissions & Ownership

| Symbolic | Octal |
|---|---|
| rwx | 7 |
| rw- | 6 |
| r-x | 5 |
| r— | 4 |
| -wx | 3 |
| -w- | 2 |
| —x | 1 |
| --- | 0 |
Generally: 755 for general executable files or 600 for personal files |
# user
whoami
# groups membership
groups
# show user id, group id & groups
id
# change file ownership & permissions
chmod u=rxw,g=rw,o= test.txt
chown user:group test.txtUser & Group Management
# change password
passwd
passwd newuser
# add user
adduser newuser
# delete user
userdel newuser
# change groups
chgrp group test.txt
# add group
groupadd -g 1200 newgroup
groupdel newgroup
newgrp lxd
# add user to sudo group (addGroup)
usermod -aG sudo user
# check persisted users & groups
cat /etc/passwd
# hashed passwords
cat /etc/shadow
# change password
chage -l user
chage userHard und Symbolic Links
# symlink (soft)
ln -s file_a file_b
# hard link
ln new_file hard_link
# find links
find . -type lBash Scripting
- Unofficial Bash Strict Mode:
set -euxo pipefail
# one-liner: check if file exists
[ ! -f foo.txt ] && echo "File not found!"
[ ! -f foo.txt ] && echo "File not found" || echo "file found"
# or: conditional
if [ ! -f /tmp/foo.txt ]; then
echo "File not found!"
fi
# check for parameter
if [ $# -ne 1 ]
then
echo "I need 1 parameter"
exit 1
else
echo "starting"
cd /tmp
touch $($date +'%Y%m%d-%H%m')-$1
ls -ltrh | tail -3
echo "done"
exit 0
fi
# check last return code
echo $?Conditionals
The command to check conditions is the test command but since it is used a lot, we have a shortcut for it. Instead of test condition you can write [ condition ].
| conditions | what is means |
|---|---|
| ”a” = “b” | if two strings are equal (here it will return False) |
| “a” != “b” | string a is not equal to string b |
| 4 -lt 40 | if 4 is lower than 40 (True) |
| 5 -gt 15 | if 5 is greater than 15 (False) |
| 5 -ge 5 | if 5 is greater or equal 5 |
| 5 -le 3 | if 5 is lower or equal to 3 |
| 9 -ne 2 | 9 is not equal with 2 (True) |
| -f FILENAME | if file FILENAME exists |
| -s FILENAME | if file exists and its size is more than 0 (Zero) |
| -x FILENAME | if file exists and is executable |
Note that [[ is actually a command/program that returns either 0 (true) or 1 (false). Any program that obeys the same logic (like all base utils, such as grep(1) or ping(1)) can be used as condition, see examples.
| conditions | what is means |
|---|---|
[[ -z STRING ]] | Empty string |
[[ -n STRING ]] | Not empty string |
[[ STRING == STRING ]] | Equal |
[[ STRING != STRING ]] | Not Equal |
[[ NUM -eq NUM ]] | Equal |
[[ NUM -ne NUM ]] | Not equal |
[[ NUM -lt NUM ]] | Less than |
[[ NUM -le NUM ]] | Less than or equal |
[[ NUM -gt NUM ]] | Greater than |
[[ NUM -ge NUM ]] | Greater than or equal |
[[ STRING =~ STRING ]] | Regexp |
(( NUM < NUM )) | Numeric conditions |
[[ -o noclobber ]] | If OPTIONNAME is enabled |
[[ ! EXPR ]] | Not |
[[ X && Y ]] | And |
[[ X | Y ]] | Or |
File conditions:
| conditions | what is means |
|---|---|
[[ -e FILE ]] | Exists |
[[ -r FILE ]] | Readable |
[[ -h FILE ]] | Symlink |
[[ -d FILE ]] | Directory |
[[ -w FILE ]] | Writable |
[[ -s FILE ]] | Size is > 0 bytes |
[[ -f FILE ]] | File |
[[ -x FILE ]] | Executable |
[[ FILE1 -nt FILE2 ]] | 1 is more recent than 2 |
[[ FILE1 -ot FILE2 ]] | 2 is more recent than 1 |
[[ FILE1 -ef FILE2 ]] | Same files |
examples
# String
if [[ -z "$string" ]]; then
echo "String is empty"
elif [[ -n "$string" ]]; then
echo "String is not empty"
else
echo "This never happens"
fi
# Combinations
if [[ X && Y ]]; then
...
fi
# Equal
if [[ "$A" == "$B" ]]
# Regex
if [[ "A" =~ . ]]
# smaller than
if (( $a < $b )); then
echo "$a is smaller than $b"
fi
# if file exists
if [[ -e "file.txt" ]]; then
echo "file exists"
fiLoops
#!/bin/bash
for NUM in {1..5};
do
echo $NUM
donewhile
VAR=52
# while greater than
while [ $VAR -gt 42 ]
do
echo VAR is $VAR and it is still greater than 42
let VAR=VAR-1 # let for calc on vars
doneArrays
# Define an array
$ Fruits=('Apple' 'Banana' 'Orange')
Fruits[0]="Apple"
Fruits[1]="Banana"
Fruits[2]="Orange"
# Working with arrays
echo "${Fruits[0]}" # Element #0
echo "${Fruits[-1]}" # Last element
echo "${Fruits[@]}" # All elements, space-separated
echo "${#Fruits[@]}" # Number of elements
echo "${#Fruits}" # String length of the 1st element
echo "${#Fruits[3]}" # String length of the Nth element
echo "${Fruits[@]:3:2}" # Range (from position 3, length 2)
echo "${!Fruits[@]}" # Keys of all elements, space-separated
# Operations
Fruits=("${Fruits[@]}" "Watermelon") # Push
Fruits+=('Watermelon') # Also Push
Fruits=( "${Fruits[@]/Ap*/}" ) # Remove by regex match
unset Fruits[2] # Remove one item
Fruits=("${Fruits[@]}") # Duplicate
Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate
lines=(`cat "logfile"`) # Read from file
# Iteration
for i in "${arrayName[@]}"; do
echo "$i"
doneDirectories
# Declare a directory
declare -A sounds
sounds[dog]="bark"
sounds[cow]="moo"
sounds[bird]="tweet"
sounds[wolf]="howl"
# Working with dictionaries
echo "${sounds[dog]}" # Dog's sound
echo "${sounds[@]}" # All values
echo "${!sounds[@]}" # All keys
echo "${#sounds[@]}" # Number of elements
unset sounds[dog] # Delete dog
# Iteration: values
for val in "${sounds[@]}"; do
echo "$val"
done
# Iteration: keys
for key in "${!sounds[@]}"; do
echo "$key"
doneCommand Substitution
TODAY=$(date +'%Y %m %d - %H:%m')
echo $TODAY
name="John"
echo "${name}"
echo "${name/J/j}" #=> "john" (substitution)
echo "${name:0:2}" #=> "Jo" (slicing)
echo "${name::2}" #=> "Jo" (slicing)
echo "${name::-1}" #=> "Joh" (slicing)
echo "${name:(-1)}" #=> "n" (slicing from right)
echo "${name:(-2):1}" #=> "h" (slicing from right)
echo "${food:-Cake}" #=> $food or "Cake"Cron
# list cronjobs
crontab -l
# edit cronjobs
crontab -eA B C D E command and arguments| filed | Meaning | values |
|---|---|---|
| A | minute | 0-59 |
| B | hour | 0-23 |
| C | day of month | 1-31 |
| D | month | 1-12 (or names, see below) |
| E | day of week | 0-7 (0 or 7 is Sunday, or use names) |
If you replace a field with * it means “whatever” or “all” or “any”. Also if you have @reboot or @daily instead of time fields, the command will be run once after the reboot or daily. Lets see some examples:
5 0 * * * $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
# run at 2:15pm on the first of every month -- output mailed to paul
15 14 1 * * $HOME/bin/monthly
# run at 10 pm on weekdays, annoy Joe
0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
5 4 * * sun echo "run at 5 after 4 every sunday"
*/5 * * * * echo "each 5 mintues"
42 8,18 * * 1-5 echo "8:42 and 18:42 and only on weekdays (monday till friday)"
@reboot echo "runs after the reboot"System & Boot Logs
# kernel ring buffer logs
dmesg
# check log rotation
cat /etc/logrotate.conf # usually in /etc/cron.daily
# system log management
systemctl status rsyslog
cat /etc/rsyslog.conf # config
journalctl # show all journal
journalctl -xe # last few logs
journalctl --no-pager # do not use less
journalctl -n 10 # only 10 lines
journalctl -S -1d # last 1 day
journalctl -u nginx.service --since today # only nginx unit
journalctl _PID=1234 # by process idNetwork Troubleshooting
# show NICs
ip link show
ip addr show
ifconfig -a # old
# hostname
hostname
hostnamectl status
cat /etc/hostname
# remote host: return DNS records (& get ip)
host google.com
host -t TXT google.com
# routing
ip route
ip route add default via 172.31.1.1 # default gateway
ip route add 4.2.2.4 via 172.31.1.1 # static route
# trace
traceroute google.com
# netstat & ss: check open ports (LISTEN)
netstat -tulpen # old
ss -tulpen
# check which user & command is using port
sudo fuser 3000/tcp -v
# set DNS server
cat /etc/resolv.conf
# netcat: listen on port
nc -l 8080
# netcat: check if remote port is open
nc -zv localhost 8080
nc -zv localhost 1-9999
# dig: check dns
dig @8.8.8.8 google.com
# tcpflow & tcpdump
tcpflow -c port 80
tcpdump -i eth0Administration & Security
# change to root with env vars
sudo su -
# change to user
su newuser -
# check system sessions
w
who
# last logins
last
last -f /var/log/btmp # failed logins
# suid & guid
find /usr/bin/ -perm -u+s
# show open files
lsof
sudo lsof -i # show open connection filesssh
# generate ssh key pair in ~/.ssh
ssh-keygen -t ed25519
# ssh agent
ssh-agent /bin/bash
ssh-add # add all keys to agent
# ssh tunnel: enable processes running at foo to connect
# to `localhost:8080` and actually speak to your home computer at port # 3000
ssh -R 8080:localhost:3000 foo.mycompany.com