Up until now, we have been using a command called exit
intermittently to exit scripts. For those of you who are curious, you may have already scoured the web to find out what this command does, but the key concept to remember is that every script, command, or binary exits with a return code. Return codes are numeric and are limited to being between 0-255 because an unsigned 8-bit integer is used. If you use a value of -1
, it will return 255
.
Okay, so return codes are useful in which ways? Return codes are useful when you want to know whether you found a match when performing a match (for example), and whether the command was completely successfully or there was an error. Let's dig into a real example using the ls
command on the console:
$ ls ~/this.file.no.exist ls: cannot access '/home/rbrash/this.file.no.exist': No such file or directory $ echo $? 2 $ ls ~/.bashrc /home/rbrash/.bashrc $ echo $? 0
Notice the return values? 0
or 2
in this example mean either success (0) or that there are errors (1 and 2). These are obtained by retrieving the $?
variable and we could even set it to a variable like this:
$ ls ~/this.file.no.exist ls: cannot access '/home/rbrash/this.file.no.exist': No such file or directory $ TEST=$? $ echo $TEST 2
From this example, we now know what return codes are, and how we can use them to utilize results returned from functions, scripts, and commands.
Dig into your terminal and create the following Bash script:
#!/bin/bash GLOBAL_RET=255 function my_function_global() { ls /home/${USER}/.bashrc GLOBAL_RET=$? } function my_function_return() { ls /home/${USER}/.bashrc return $? } function my_function_str() { local UNAME=$1 local OUTPUT="" if [ -e /home/${UNAME}/.bashrc ]; then OUTPUT='FOUND IT' else OUTPUT='NOT FOUND' fi echo ${OUTPUT} } echo "Current ret: ${GLOBAL_RET}" my_function_global "${USER}" echo "Current ret after: ${GLOBAL_RET}" GLOBAL_RET=255 echo "Current ret: ${GLOBAL_RET}" my_function_return "${USER}" GLOBAL_RET=$? echo "Current ret after: ${GLOBAL_RET}" # And for giggles, we can pass back output too! GLOBAL_RET="" echo "Current ret: ${GLOBAL_RET}" GLOBAL_RET=$(my_function_str ${USER}) # You could also use GLOBAL_RET=`my_function_str ${USER}` # Notice the back ticks "`" echo "Current ret after: $GLOBAL_RET" exit 0
The script will output the following before exiting with a return code of 0
(remember that ls returns 0
if run successfully):
rbrash@moon:~$ bash test.sh Current ret: 255 /home/rbrash/.bashrc Current ret after: 0 Current ret: 255 /home/rbrash/.bashrc Current ret after: 0 Current ret: Current ret after: FOUND IT $
In this section, there are three functions that leverage three concepts:
my_function_global
uses aglobal
variable to return the command's return codemy_function_return
uses the reserved word,return
, and a value (the command's return code)my_function_str
uses afork
(a special operation) to execute a command and get the output (our string, which is echoed)