Bash Tips

Some bash one-liners:

echo ${!X*}

Will print all the names of variables whos name starts with X. To output the contents of a variable so it can be parsed by
bash

declare -p VARNAME

Pattern Matching

Operator: ${foo#t*is}

Function: deletes the shortest possible match from the left

Operator: ${foo##t*is}

Function: deletes the longest possible match from the left

Operator: ${foo%t*st}

Function: deletes the shortest possible match from the right

Operator: ${foo%%t*st}

Function: deletes the longest possible match from the right MNEMONIC: The # key is on the left side of the $ key and operates from the left. The % key is on the right of the $ key and operates from the right.

Substitution

Operator: ${foo:-bar}

Function: If $foo exists and is not null, return $foo. If it doesn't exist or is null, return bar.

Operator: ${foo:=bar}

Function: If $foo exists and is not null, return $foo. If it doesn't exist or is null, set $foo to bar and return bar.

Operator: ${foo:+bar}

Function: If $foo exists and is not null, return bar. If it doesn't exist or is null, return a null.

Operator: ${foo:?"error message"}

Function: If $foo exists and isn't null, return its value. If it doesn't exist or is null, print the error message. If no error message is given, it prints parameter null or not set. In a non-interactive shell, this aborts the current script. In an interactive shell, this simply prints the error message.

$$ for Subshell

When running a sub-shell in bash the $$ construct still returns the process id of the main shell. Use the following construct to determine the correct IP address:

mypid=$(sh -c 'echo $$PPID')

Yes, it looks nasty.

Retrieving an IP address.

Updated 2023-10-20

To get the IP address, the easiest way is to use:

ip -br a

Results in:

lo               UNKNOWN        127.0.0.1/8 ::1/128 
enp1s0           DOWN           
eno1             UP             192.168.101.64/24 fd42:bf4e:715f:6ef5:95b0:ecc9:68fa:ac07/64 fe80::82db:4389:522c:332d/64 
wlp3s0           DOWN           
virbr0           DOWN           192.168.122.1/24 
docker0          UP             172.17.0.1/16 fe80::42:95ff:fe8e:29b0/64 
br-6f79780fe7d1  DOWN           172.18.0.1/16 
veth8758d36@if8  UP             fe80::a84f:c3ff:fe8f:45b/64 

Which is easy to parse. Another option is:

ip -o a

Results:

1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
1: lo    inet6 ::1/128 scope host proto kernel_lo \       valid_lft forever preferred_lft forever
3: eno1    inet 192.168.101.64/24 brd 192.168.101.255 scope global dynamic noprefixroute eno1\       valid_lft 26700sec preferred_lft 26700sec
3: eno1    inet6 fd42:bf4e:715f:6ef5:95b0:ecc9:68fa:ac07/64 scope global dynamic noprefixroute \       valid_lft 1534sec preferred_lft 1534sec
3: eno1    inet6 fe80::82db:4389:522c:332d/64 scope link noprefixroute \       valid_lft forever preferred_lft forever
5: virbr0    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0\       valid_lft forever preferred_lft forever
6: docker0    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0\       valid_lft forever preferred_lft forever
6: docker0    inet6 fe80::42:95ff:fe8e:29b0/64 scope link proto kernel_ll \       valid_lft forever preferred_lft forever
7: br-6f79780fe7d1    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-6f79780fe7d1\       valid_lft forever preferred_lft forever
9: veth8758d36    inet6 fe80::a84f:c3ff:fe8f:45b/64 scope link proto kernel_ll \       valid_lft forever preferred_lft forever

Has more information, but it is still fairly parsable.

Identifying virtual Network Interfaces

If you need to identify which network interfaces are virtua, use:

readlink /sys/class/net/virbr0

Results in:

../../devices/virtual/net/virbr0

The output contains /virtual/ in the path. Physical NICs would have something related to the bus that the NIC is connected to.