When you execute a command in Linux, it generates a numeric return code. This happens whether you’re running the command directly from the shell, from a script, or even from an Ansible playbook. You can use those return codes to handle the result of that command properly.
When running commands at a shell prompt, the special variable $? contains a number that indicates the result of the last command executed.
A zero ( 0 ) means everything went fine. Anything else means there is a problem.
A value of 1 generically indicates that some error has happened.
$ who admin2 :1 2022-03-15 10:14 (:1) $ echo $? 0 $ who | grep thisstringdoesnotexist $ echo $? 1
In the example above, I executed the who command, which showed that I am admin2.
Immediately after that, I executed echo $? , and it returned zero because the previous command was executed successfully.
Then I executed the same who command (which I know is working fine) and piped that to grep with the non-existing argument. This time the $? variable contains a 1 .
Why? It’s because the last command executed was grep , which returns 1 when it cannot find the argument in its input.
$ls myfile.cfg ls: cannot access 'myfile.cfg': No such file or directory $echo $? 2
Here I tried to list a file that doesn’t exist. Then when I entered echo $? I got 2 , which is how the ls command indicates that the argument is not a file or directory name.
You can also use the exit command from a shell script to customize the return code to the caller script.
The following script illustrates this:
#!/bin/bash if [ ! -f myfile.cfg ]; then echo The file does not exist and we display an error exit 64 fi echo The file exists and we will do something echo "(Not really doing anything, but this is where we could do it)" exit 0
$./myscrypt.sh The file does not exist and we display an error $echo $? 64 $touch myfile.cfg $./myscrypt.sh The file exists and we will do something (Not really doing anything, but this is where we could do it) $echo $? 0
In this script, I explicitly provide the exit code for the failed and for the successful cases. Some observations:
If you need to test the return code of a command you invoked on your shell script, you just need to test the $? variable immediately after the command executes.
#!/bin/bash # A snipet from a shell script . # Next we will invoke a command or another shell script ./myscript.sh RETURN=$? if [ $RETURN -eq 0 ]; then echo "The script myscript.sh was executed successfuly" exit 0 else echo "The script myscript.sh was NOT executed successfuly and returned the code $RETURN" exit $RETURN fi
In this example, after invoking my command or script, I saved the exit code from $? on a variable for further utilization. (Again, $? returns the status of the last command, so you need to be careful if you run more commands—even a simple echo .).
It is recommended to avoid running shell commands from an Ansible playbook if there is an Ansible module that performs the same action. This is especially because with a module you have better odds of being idempotent.
[ Ready to start automating? Check out this Ansible quick start series. ]
To illustrate how to handle return codes from a shell command, check this simple playbook:
--- - name: Executes a shell script hosts: localhost gather_facts: no tasks: - name: Execute the shell script shell: ./myscript.sh ignore_errors: true register: result - name: Shows the result of executing the script debug: msg: - "Return code. >" - ">"
This is the Ansible playbook executed when a script returns an error:
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [Executes a shell script] ***************************************************************************************** TASK [Execute the shell script] **************************************************************************************** fatal: [localhost]: FAILED! => . ignoring TASK [Shows the result of executing the script] ************************************************************************ ok: [localhost] => < "msg": [ "Return code. 64", [ "The file does not exist and we display an error" ] ] >PLAY RECAP ************************************************************************************************************* localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
Adblock