Americas

  • United States
sandra_henrystocker
Unix Dweeb

Use bash to change an IP address from dynamic to static on Linux

How-To
May 31, 20225 mins
Linux

The bash script described here can change Linux systems' IP addresses from dynamic to static with much less manual work.

network interface connections
Credit: PikePicture / Getty Images

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.

sandra_henrystocker
Unix Dweeb

Sandra Henry-Stocker has been administering Unix systems for more than 30 years. She describes herself as "USL" (Unix as a second language) but remembers enough English to write books and buy groceries. She lives in the mountains in Virginia where, when not working with or writing about Unix, she's chasing the bears away from her bird feeders.

The opinions expressed in this blog are those of Sandra Henry-Stocker and do not necessarily represent those of IDG Communications, Inc., its parent, subsidiary or affiliated companies.