$? is used to return the return code / exit code of the last run command. For example, since whoami is a valid command the return code will be 0 (success).
~]# whoami
john.doe
~]# echo $?
0
On the other hand, since "bogus" is not a valid command, the return code will be something other than 0, often 127.
~]$ bogus
-bash: bogus: command not found
~]$ echo $?
127
Or, if you do not have permission to run a valid command, the return code should be 1.
~]# shutdown now
Permission denied
~]# echo $?
1
Or, a valid command that expects stdout to be returned but no stdout is returned may return 1 (failed).
~]$ ps -ef | grep -v grep | grep bogus
~]$ echo $?
1
Determine if a file contains a string
The grep command is used to search for a certain string in a file. If grep is able to find one or more occurrences of the string in the file, the exit code will be 0 (success).
~]# grep "hello world" example.file
hello world
~]# echo $?
0
On the other hand, if there are zero occurrences of the string in the file, the exit code will be 1 (failure).
~]# grep "hello world" example.file
~]# echo $?
1
This can be useful in a script, to do something when a file contains a certain string, or to do something else if the file does not contain a certain string.
#!/bin/bash
abc=$(grep "hello world" example.file)
result=$?
if [ $result == 0 ];
then
echo "example.file does contain hello world"
else
echo "example.file does not contain hello world"
fi
Exit code in bash script
Here is a basic example of how to do something in a bash shell script using the return code of a command.
#!/bin/bash
mkdir /tmp/my_temporary_directory
return_code=$?
if [ $return_code -eq 0 ]; then
echo "successfully created directory /tmp/my_temporary_directory"
else
echo "failed to create directory /tmp/my_temporary_directory - got return code $return_code"
exit 1
fi
Or, sometimes something like this makes more sense.
#!/bin/bash
cmd="mkdir /tmp/my_temporary_directory"
return_code=$?
echo "command $cmd returned exit code $return_code"
if [ $return_code -ne 0 ]; then
exit 1
fi
Be aware that if you set the Internal Field Separator (IFS), you may start getting exit code 127 returned. For example, like this.
#!/bin/bash
IFS=$'\n'
cmd="mkdir /tmp/example"
$cmd
rc=$?
echo return code $rc
exit
Running this script returned the following. So, perhaps just set Internal Field Separator (IFS) only if needed, and unset once done.
]$ bash example.sh
example.sh: line 3: mkdir /tmp/example: No such file or directory
return code 127
Did you find this article helpful?
If so, consider buying me a coffee over at