1. Overview

In this tutorial, we’ll discuss the set command in Linux and its use cases. We’ll also see a few options it provides and understand how to use them. 

2. set Command

We use the set command to change the values of shell options and display variables in Bash scripts. We can also use it to debug Bash scripts, export values from shell scripts, terminate programs when they fail, and handle exceptions.

The set command has the following format:

$ set [option] [argument]

Here, we use option to either set or unset a flag while argument is a positional parameter. The option flag impacts how Bash scripts behave to accomplish any desired task.

When we run the set command without any arguments, it returns a list of all system settings. The list  includes the names and values of all shell variables and functions:

$ set
HISTFILE='/root/.ash_history'
HOME='/root'
HOSTNAME='localhost'
IFS=' '
LINENO=''
OLDPWD='/'
OPTIND='1'
PAGER='less' PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PPID='1'
PS1='\h:\w\$ '
PS2='> '
PS4='+ '
PWD='/root'
SHLVL='3'
TERM='linux'
TZ='UTC-01:00' _='--version'
script='/etc/profile.d/*.sh'

Since the list is lengthy, we can use the Page Up and Page Down keys to navigate through it.

3. set Command Options

We have several options we can use with the set command. We’ll discuss the most common ones in this section.

3.1. The -e Option 

When a query returns a non-zero status, the -e flag stops the script. It also detects errors in the currently executing script.

Let’s write a Bash script that displays the contents of a file and outputs a message if the file exists in our directory:

#!/bin/bash 
set -e 
mkdir newfolder 
cat filenotindirectory 
echo 'The file is not in our directory!'

We run the executable file to test out the -e flag:

$ chmod u+x eflag.sh
$ ./eflag.sh
cat: can't open 'filenotindirectory': No such file or directory

When the script tries to display the contents of the file filenotindirectory, it errors out because the file does not exist, and it exits immediately. As a result, the final echo command is also not run.

3.2. The -C Option 

Using the -C flag ensures that we cannot overwrite an existing file with the same name:

$ echo 'An existing file' > myfile
$ set -C
$ echo 'Editing an existing file' > myfile
sh: can't create myfile: File exists

We created a file called myfile, but an error occurred when we tried to overwrite its contents. Using this flag is a good practice to avoid accidental overwriting of files.

3.3. The -f Option 

As we know, we can easily search for files using wildcard characters such as ?*, or []. This method is similar to regex, where we try to find similar texts using patterns. The Bash shell uses the wildcards we specify to generate patterns and match them with filenames. This feature is called globbing.

Let’s try using globbing by searching for files with the .txt extension:

$ ls *.txt
files.txt

We can see that there is one file with the .txt extension.

Next, let’s run the set -f command and then search for files with the .txt extension using a wildcard:

$ set -f
$ ls *.txt
ls: *.txt: No such file or directory

We now get an error as output. The -f prevents us from using wildcards to search for filenames or strings.

We should note that running the ls command without specifying any wildcard pattern would still give an output of all the files in our directories.

3.4. The -x Option 

We use the -x parameter when debugging our scripts to determine the output of individual commands.

To illustrate, let’s create a Bash script that displays a countdown from 3 to 0:

#!/bin/bash
set -x
n=3
while [ $n -gt 0 ]; do
    n=$[ $n-1 ]
    echo $n
    sleep 1
done

Then, we execute the script:

$ bash debugging.sh
+ n=3
+ '[' 3 -gt 0 ']'
+ n=2
+ echo 2
2
+ sleep 1
+ '[' 2 -gt 0 ']'
+ n=1
+ echo 1
1
+ sleep 1
+ '[' 1 -gt 0 ']'
+ n=0
+ echo 0
0
+ sleep 1
+ '[' 0 -gt 0 ']'

We can see that the code executes one line at a time, displaying results before moving to the following line.

3.5. The -a Option 

We can export variables or functions with this flag, making them reusable in subshells or scripts. First, let’s define variables in our terminal:

$ set -a 
$ name='May' 
$ age=22

Next, we write a script:

#!/bin/bash 
echo $name $age

Finally, let’s run the script:

$ bash export.sh 
May 22

We can see above that the script outputs the created variables, as determined by the echo command.

Alternatively, we can also run this set command following this sequence:

$ name='May' 
$ age=22

Next, we write the script:

#!/bin/bash 
echo $name $age

Lastly, we run the script:

$ bash export.sh -a 
May 22

3.6. The -u Option

We use this flag to ensure that Bash does not overlook the non-existent variables in our script. We can see that in normal circumstances, Bash ignores the unassigned variables and runs our script without any errors:

#!/bin/bash
x='Bash scripting is fun'
echo $x $y

Let’s make the script an executable and then run it:

$ chmod u+x testfile.sh
$ ./testfile.sh
Bash scripting is fun

Now, we apply the set command  with the -u option:

#!/bin/bash
set -u
x='Bash scripting is fun'
echo $x $y

Let’s rerun the script:

$ ./testfile.sh
./testfile.sh: line 4: y: unbound variable

We see that we got an error. The -u option prevents Bash from ignoring the non-existent variable.

3.7. The +[argument] Option 

Running the set command with the +[argument] option unsets the option’s functionality. In essence, it nullifies the effect of the -[argument] option.

We will see some examples of shell scripts run with the set  +[argument] commands and their outputs.

Firstly, we consider set +e:

#!/bin/bash
set +e
mkdir newfolder
cat filenotindirectory
echo 'The file is not in our directory!'

Now, let’s make our script an executable and run it:

$ chmod u+x test.sh
$ ./test.sh
cat: filenotfoundindirectory: No such file or directory
The file is not in our directory!

The Bash script outputs the error and still goes ahead to print out the echo command.

Next is the set +C option. Firstly, we add contents to a new file called myfile:

$ echo 'An existing file' > myfile
$ ls
eflag.sh myfile

Next, we attempt to overwrite the existing myfile:

$ set +C
$ echo 'Editing an existing file' > myfile
localhost:~# ls
eflag.sh myfile

We notice that we can overwrite existing files.

Thirdly, we consider the set +f option:

$ set +f
$ ls *.txt
files.txt

By running this command, we can search for files using wildcard patterns.

Next is the set +x option:

#!/bin/bash
set +x
n=3
while [ $n -gt 0 ]; do
  n=$[ $n-1 ]
  echo $n
  sleep 1
done

Let’s execute the script:

$ chmod u+x debuggingflag.sh
$ bash debuggingflag.sh
2
1
0

We view the output according to the pace set by the sleep command, but if we encounter an error in the code, the output will not show any debug message whatsoever.

Lastly, we observe the set +a command:

$ set +a
$ name=’May’
$ age=22

Let’s create a script that echoes the variables:

#!/bin/bash
echo $name $age

Now, we run our script:

$ bash export.sh

We get an empty output, as there is no value to be assigned to the variables in the export.sh file.

4. Conclusion

In this article, we saw how the set command provides us control over the behavior of our scripts by allowing us to manage certain flags and characteristics. These commands are essential because they enable us to protect our scripts and guarantee that they perform as intended.

The set command has many options, but the ones covered in this article are among the most used.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.