This list will be regularly updated.

Analyze packets on a port

# -i for interface, here I specify which internet interface I want to scan. Otherwise tcpdump take the first one it founds (result of command : ip a)
tcpdump -i ens192 port 10051
tcpdump -i ens192 port 10050

Test a port

# Example with netcat
nc -n -v 10.0.4.131 10050

# Example with telnet
telnet 10.0.4.131 10050

Display listening ports and services

ss -tulpn

Find a string inside a file in a given directory

For example search of ‘ErrorDocument’ in /etc directory and display filename and line where the string was found:

find /etc -type f -exec grep -H 'ErrorDocument' {} \;

Something equivalent with grep (ignoring case (-i) and recursively searching (-r) all files in the current and child folders plus symbolic links, and displaying line number (-n)):

$> grep -inr 'pattern'
$> grep -inr 'error'

The following finds finds including the string error and then filters the list to files that do not contain help using the -v option.

$> grep -inr 'error' | grep -v 'help'

Chmod only directories or files

# chmod 640 on each file inside ./onedirectory
find ./onedirectory -type f -exec chmod 640 {} \;
# chmod 750 on each directory inside ./onedirectory
find ./onedirectory -type d -exec chmod 750 {} \;

Show directories size

# Display the size in Gb of all directories present in the current directory
du -h --max-depth=1 ./

# display size in Gb of mydirectory. --max-depth=0 is equivalent to the option -s
du -h -s mydirectory

Test file

# -a FILE        True if file exists.
# -e FILE        True if file exists.
# -f FILE        True if file exists and is a regular file.
# -r FILE        True if file is readable by you.
# -s FILE        True if file exists and is not empty.
# -w FILE        True if the file is writable by you.

FILE="/path/to/some/file"

if [[ -r $FILE && -w $FILE ]]; then
  # do stuff
else
  # file is either not readable or writable or both
fi

Regular expression and pattern

Here note the importance of double square brackets.

Test filename extension:

[[ $filename == *.sql.bz2 ]] # or [[ "$filename" == *.sql.bz2 ]]

Test a value is a number:

regex_number='^[0-9]+$'
if [[ ! "$port" =~ $regex_number ]]; then
  echo "error $port is not a number"
fi

Ternary operator: booleanExpression ? expression1 : expression2

booleanExpression ? expression1 : expression2   # java version
booleanExpression && expression1 || expression2 # Shell version

Example:

# example 1:
[ $myVariable -eq 5 ] && echo "equal 5" || echo "not equal 5"

#example 2:
a=false
[ $a = true ] && b=1 || b=2
echo $b # will display 2

Last linux boot time

$> who -b
system boot 2022-06-07 12:51

Use -x option to run the shell interpreter to facilitate your debugging session

It can be useful for debuging:

#!/bin/bash -x
#
# myscript.sh

echo "hello world"
i=0
((i++))
echo "i = $i"
$> ./test.sh
+ echo 'hello world'
hello world
+ i=0
+ (( i++ ))
+ echo 'i = 1'
i = 1

IFS: Input Field Separator

IFS is a Unix shell variable which defines the character separators for the shell command line interpreter

You can see it’s value:

$> set | grep ^IFS
IFS=$' \t\n'

As you can see, it’s default value is:

  • space
  • tabbing (\t)
  • line feed (\n)

You can change this value, for example when you don’t want space to be consider as a separator (for instance if you have filename with spaces, …).

Impact of the default IFS value

[root@instance-nicotest2 ~]# df -h
Filesystem                  Size  Used Avail Use% Mounted on
devtmpfs                    4.7G     0  4.7G   0% /dev
tmpfs                       4.8G     0  4.8G   0% /dev/shm
tmpfs                       4.8G   41M  4.7G   1% /run
tmpfs                       4.8G     0  4.8G   0% /sys/fs/cgroup
/dev/mapper/ocivolume-root   36G  8.4G   28G  24% /
/dev/mapper/ocivolume-oled   10G  117M  9.9G   2% /var/oled
/dev/sda2                  1014M  314M  701M  31% /boot
/dev/sda1                   100M  5.1M   95M   6% /boot/efi
tmpfs                       967M     0  967M   0% /run/user/0
tmpfs                       967M     0  967M   0% /run/user/987
/dev/sdb1                    51G   53M   49G   1% /volumetest
tmpfs                       967M     0  967M   0% /run/user/1000
[root@instance-nicotest2 ~]# df=$(df -h)
[root@instance-nicotest2 ~]# echo $df
Filesystem Size Used Avail Use% Mounted on devtmpfs 4.7G 0 4.7G 0% /dev tmpfs 4.8G 0 4.8G 0% /dev/shm tmpfs 4.8G 41M 4.7G 1% /run tmpfs 4.8G 0 4.8G 0% /sys/fs/cgroup /dev/mapper/ocivolume-root 36G 8.4G 28G 24% / /dev/mapper/ocivolume-oled 10G 117M 9.9G 2% /var/oled /dev/sda2 1014M 314M 701M 31% /boot /dev/sda1 100M 5.1M 95M 6% /boot/efi tmpfs 967M 0 967M 0% /run/user/0 tmpfs 967M 0 967M 0% /run/user/987 /dev/sdb1 51G 53M 49G 1% /volumetest tmpfs 967M 0 967M 0% /run/user/1000
[root@instance-nicotest2 ~]# IFS=""
[root@instance-nicotest2 ~]# echo $df
Filesystem                  Size  Used Avail Use% Mounted on
devtmpfs                    4.7G     0  4.7G   0% /dev
tmpfs                       4.8G     0  4.8G   0% /dev/shm
tmpfs                       4.8G     41M  4.7G 1% /run
tmpfs                       4.8G     0  4.8G   0% /sys/fs/cgroup
/dev/mapper/ocivolume-root   36G  8.4G   28G  24% /
/dev/mapper/ocivolume-oled   10G  117M  9.9G   2% /var/oled
/dev/sda2                  1014M  314M  701M  31% /boot
/dev/sda1                   100M  5.1M   95M   6% /boot/efi
tmpfs                       967M     0  967M   0% /run/user/0
tmpfs                       967M     0  967M   0% /run/user/987
/dev/sdb1                    51G   53M   49G   1% /volumetest
tmpfs                       967M     0  967M   0% /run/user/1000
[root@instance-nicotest2 ~]# IFS=$' \t\n'
[root@instance-nicotest2 ~]# echo $df
Filesystem Size Used Avail Use% Mounted on devtmpfs 4.7G 0 4.7G 0% /dev tmpfs 4.8G 0 4.8G 0% /dev/shm tmpfs 4.8G 41M 4.7G 1% /run tmpfs 4.8G 0 4.8G 0% /sys/fs/cgroup /dev/mapper/ocivolume-root 36G 8.4G 28G 24% / /dev/mapper/ocivolume-oled 10G 117M 9.9G 2% /var/oled /dev/sda2 1014M 314M 701M 31% /boot /dev/sda1 100M 5.1M 95M 6% /boot/efi tmpfs 967M 0 967M 0% /run/user/0 tmpfs 967M 0 967M 0% /run/user/987 /dev/sdb1 51G 53M 49G 1% /volumetest tmpfs 967M 0 967M 0% /run/user/1000
[root@instance-nicotest2 ~]# echo "$df"
Filesystem                  Size  Used Avail Use% Mounted on
devtmpfs                    4.7G     0  4.7G   0% /dev
tmpfs                       4.8G     0  4.8G   0% /dev/shm
tmpfs                       4.8G     41M  4.7G 1% /run
tmpfs                       4.8G     0  4.8G   0% /sys/fs/cgroup
/dev/mapper/ocivolume-root   36G  8.4G   28G  24% /
/dev/mapper/ocivolume-oled   10G  117M  9.9G   2% /var/oled
/dev/sda2                  1014M  314M  701M  31% /boot
/dev/sda1                   100M  5.1M   95M   6% /boot/efi
tmpfs                       967M     0  967M   0% /run/user/0
tmpfs                       967M     0  967M   0% /run/user/987
/dev/sdb1                    51G   53M   49G   1% /volumetest
tmpfs                       967M     0  967M   0% /run/user/1000

Above we can see 3 cases that are detailed below:

1/ echo $df without double quote and with IFS set to its default value

df=$(df -h)
# here we don't change IFS value, it is set to its default value
echo $df

When we first echo $df we have an output on only one line. Why? It’s because the command line interpreter broke the text containing by $df into several input parameters to echo, each word separated by a space, or a tabbing, or LF is considered as a parameter. Of course in this example it gives a lot of parameters… 🙂

2/ echo $df without double quotes and IFS set to an empty string

df=$(df -h)
IFS=''
echo $df

When we set IFS to blank, it means there is no input separator character. Thus with the second echo $df we can see the content of $df displayed exactly as the same it was when executing the command df -h.

If you change IFS value for your needs, don’t forget to set it back to its initial value when your treatments are done.

3/ echo $df surrounded with double quotes, and IFS set to its default value

df=$(df -h)
IFS=$' \t\n' # here we set IFS to its default value because it has been changed in step number 2
echo $df

In this case you englobe the whole text between double quote to tell to the interpreter to consider it as only one input field.

Many functions have an option to specify field separator without changing IFS

Here two examples grab from internet:

# Search for the user named vivek and print home directory
# The -F':' set ':' for the input field separator and value of $IFS always ignored 
awk -F':' '/vivek/{ print $6}' /etc/passwd

# Search for the user named vivek and print home directory
# The -d':' set ':' for the input field separator and value of $IFS always ignored 
grep -w "^vivek" /etc/passwd | cut -d':' -f6

For and while loops

IFS is used by for and while loops.

text="text1 text2 text3 text4"
for txt in $text
do
  echo $txt
done

# it will display this:
text1
text2
text3
text4

Test url or resources is available

httpCode=$(curl -o /dev/null --silent -Iw '%{http_code}' https://example.com/my.remote.tarball.gz)
[ "$httpCode" -eq "200" ] && echo "Resource is available"

scp copy file from a host to another through a jump host

If you want to copy a file from a distant hidden host to your local host:

scp -o 'ProxyJump <user_public_host>@<public_ip>' <user_hidden_host>@<private_ip>:/source/path/yourfiletocopy /target/localpath/

Or if you wan to copy a file from your host to an hidden host (hidden behind a JumpHost, it means a public host):

scp -o 'ProxyJump <user_public_host>@<public_ip>' /source/localpath/yourfiletocopy <user_hidden_host>@<private_ip>:/target/path/
#some examples:

scp -o 'ProxyJump nicodevlog@193.193.193.193' nicodevlog@192.168.201.10:/mnt/source/nicodevlog.txt /root/nicodevlog/

scp -o 'ProxyJump nicodevlog@193.193.193.193' /root/nicodevlog/nicodevlog.txt nicodevlog@192.168.201.10:/mnt/target/

What is my public IP on my linux server, command line

curl ifconfig.me

This won’t give you the correct IP if your server is behind a proxy.