Use bash to change an IP address from dynamic to static on Linux
Changing the IP address of a Linux system from dynamic to static is not difficult, but requires a little care and a set of commands that you likely rarely use. This post provides a bash script that will run through the process, collect the needed information and then issue the commands required to make the changes while asking as little as possible from the person running it.
The bulk of the script focusses on making sure that the correct settings are used. For example, it collects the 36-charater universally unique identifier (UUID) from the system so that you never have to type it in or copy and paste it into place.
After asking only a question or two, the script runs a series of nmcli (Network Manager) commands that will change the IP address if requested and set the address to be static. Notice that a number of the fields in the commands that it will run as shown below are variables derived from earlier commands in the script.
sudo nmcli connection modify $UUID IPv4.address $IP/$sz sudo nmcli connection modify $UUID IPv4.gateway $router sudo nmcli connection modify $UUID IPv4.method manual sudo nmcli connection down $UUID sudo nmcli connection up $UUID
If a new IP address is requested, the script will check the format of the address requested and make sure that it is compatible with the current network.
Prior to running the commands shown above, the script collects the variables used to make sure the commands are set up correctly—largely by running commands that report on the current settings. The prominent UUID shown in each of them is collected from the output of this command:
$ nmcli connection show NAME UUID TYPE DEVICE Wired connection 1 ec33e575-8059-3a20-b7a5-58393deb1783 ethernet enp0s25
The UUID is saved in the script by the command like that shown below so that it can be used in the nmcli commands shown earlier.
$ UUID=`nmcli connection show | tail -1 | awk ‘{print $4}’` $ echo $UUID ec33e575-8059-3a20-b7a5-58393deb1783
The command below pulls the subnet specification from an ip a command like that shown below. The result will be something like “192.168.0.4/24” where the 24 (i.e., 24 bits) tells us that the first three bytes of the address (192.168.0) represent the network.
$ subnet=`ip a | grep “inet “ | tail -1 | awk ‘{print $2}’` $ echo $subnet 192.168.0.11/24
Getting nearly all the needed information from the system rather than asking the user to provide it makes the process a lot easier and, potentially, more reliable.
The script also gives you the option of changing the current IP address if you don’t like it. While this will leave you disconnected from the system by the time the script ends, you can immediately log back in using the new IP address.
Note that the script uses sudo for the final commands because those commands will change system settings.
Here is the script which I call “set_static_IP”:
#!/bin/bash # get subnet subnet=`ip a | grep “inet “ | tail -1 | awk ‘{print $2}’` # get router/gateway router=`ip route show | head -1 | awk ‘{print $3}’` # get size of network portion of address in bytes sz=`echo $subnet | awk -F / ‘{print $2}’` bytes=`expr $sz / 8` prefix=`echo $subnet | cut -d. -f1-$bytes` # e.g., 192.168.0 # get IP address to be set
IP=`hostname -I | awk ‘{print $1}’` # current IP
echo -n “Keep IP address?—$IP [yn]> “
read ans if [ $ans =="n" ]; then echo -n “Enter new IP address: “ read IP # check if specified IP is properly formatted if [[ ! $IP =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then echo Invalid IP fi # check if specified IP works for local network if [[ ! $IP =~ ^$prefix ]]; then echo “ERROR: Specified IP not usable for local network” exit fi fi # check if specified IP is properly formatted if [[ ! $IP =~ ^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$ ]]; then echo Invalid IP fi # fetch the UUID UUID=`nmcli connection show | tail -1 | awk ‘{print $4}’` # UUID=`nmcli connection show | head -2 | tail -1 | awk ‘{print $3}’` # Mint # run commands to set up the permanent IP address sudo nmcli connection modify $UUID IPv4.address $IP/$sz sudo nmcli connection modify $UUID IPv4.gateway $router sudo nmcli connection modify $UUID IPv4.method manual sudo nmcli connection up $UUID
The script was tested on both Fedora 35 and Linux Mint. Notice that the command for fetching the UUID on Mint is different because the output of the “nmcli connection show” command is different. The command for Mint is included in the script but commented out for an easy switch.
Interaction with the script will look like this:
$ ./set_static_IP Keep IP address?—192.168.0.18 [yn]> y [sudo] password for yourid: Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/24)
After running the script, I ran a find command to look for very recently updated files and found this one that includes the “manual” (i.e., static) setting specified in the thrid command shown above.
$ sudo cat “/etc/NetworkManager/system-connections/Wired connection 1.nmconnection” [connection] id=Wired connection 1 uuid=ec33e575-8059-3a20-b7a5-58393deb1783 type=ethernet autoconnect-priority=-999 interface-name=enp0s25 permissions= timestamp=1653746936 [ethernet] mac-address-blacklist= [ipv4] address1=192.168.0.11/24,192.168.0.1 dns-search= method=manual [ipv6] addr-gen-mode=stable-privacy dns-search= method=auto [proxy]
To find only very recently created or updated files, you can use a command like this that looks for files that have been changed in the last 14.4 minutes:
$ sudo find . -mtime -.01 -print
In case this isn’t clear, the -mtime variable when set to 1 means “1 day”. Since a day is 1440 minutes long, .1 would mean 144 minutes and .01 means 14.4 minutes.
Wrap-Up
Dynamic addressing is great except when it isn’t. It isn’t when the system in question is one you have to connect to fairly often rather than one you only connect from. Knowing how to change an IP address from dynamic to static can be a big deal when you need an IP address that doesn’t change.
Copyright © 2022 IDG Communications, Inc.