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.