Linux print exit code

Get the exit code for a command in Bash and KornShell (ksh)

Now if you look into this code, the few things that I changed are:

  • use of typeset is not necessary, but it is a good practice. It makes cmnd and ret_code local to safeRunCommand
  • use of ret_code is not necessary, but it is a good practice to store the return code in some variable (and store it ASAP), so that you can use it later like I did in printf «Error: [%d] when executing command: ‘$command'» $ret_code
  • pass the command with quotes surrounding the command like safeRunCommand «$command» . If you don’t then cmnd will get only the value ls and not ls -l . And it is even more important if your command contains pipes.
  • you can use typeset cmnd=»$*» instead of typeset cmnd=»$1″ if you want to keep the spaces. You can try with both depending upon how complex is your command argument.
  • ‘eval’ is used to evaluate so that a command containing pipes can work fine

Note: Do remember some commands give 1 as the return code even though there isn’t any error like grep . If grep found something it will return 0, else 1.

I had tested with KornShell and Bash. And it worked fine. Let me know if you face issues running this.

You can see the $command is being used in the safeRunCommand ‘s printf statement. You can use it as it is global. So I am going to change $command to $cmnd (the local variable..

Thanks @havexz. How can I run command like as: command=»ls -l | grep *.log» Unfortunately this command is not work, and all my commands are very complex with many pipe |, grep, awk, sed, .

One more question 🙂 How I can add output of the function safeRunCommand to variable, and in case of failure to process interrupts If I write output=$(safeRunCommand «$command») script is not being interrupt on error inside safeRunCommand function.

Maybe I found answer. Can I write out=$(eval $cmnd) , and after calling safeRunCommand function use out variable?

It should be $cmd instead of $($cmd) . It works fine with that on my box.

Your script works only for one-word commands, like ls. It will not work for «ls cpp». For this to work, replace cmd=»$1″; $cmd with «$@» . And, do not run your script as command=»some cmd»; safeRun command . Run it as safeRun some cmd .

Also, when you have to debug your Bash scripts, execute with ‘-x’ flag. [bash -x s.sh].

To quickly elaborate on why this is correct: $($cmd) will execute $cmd in a new shell, whereas $cmd won’t.

cmd=»$@» will not work; instead, either run «$@» directly (as in @sehe’s answer), or use an array: cmd=(«$@»); «$»

@GordonDavisson: I try on my system before posting anything here. And it is working fine. Here is output on bash -x try.sh . + command=’ls java’ + safeRunCommand ls java + cmnd=’ls java’ + ls java . It is same as doing cmd=»hello world», isn’t it?

@logic_max: try it on a command with a space in an argument, like safeRunCommand grep «this that» file.txt : + cmd=’grep this that file.txt’ + grep this that file.txt grep: that: No such file or directory

Читайте также:  Find linux version name

@logic_max: Yup. I’m not sure why people insist on storing commands in variables before executing them; it just created limitations like this.

There are several things wrong with your script.

Functions (subroutines) should be declared before attempting to call them. You probably want to return() but not exit() from your subroutine to allow the calling block to test the success or failure of a particular command. That aside, you don’t capture ‘ERROR_CODE’ so that is always zero (undefined).

It’s good practice to surround your variable references with curly braces, too. Your code might look like:

#!/bin/sh command="/bin/date -u" #. Example Only safeRunCommand() < cmnd="$@" #. insure whitespace passed and preserved $cmnd ERROR_CODE=$? #. so we have it for the command we want if [ $!= 0 ]; then printf "Error when executing command: '$'\n" exit $ #. consider 'return()' here fi > safeRunCommand $command command="cp" safeRunCommand $command 

cmnd=»$@» will not work; instead, either run «$@» directly (as in @sehe’s answer), or use an array: cmnd=(«$@»); «$»

The normal idea would be to run the command and then use $? to get the exit code. However, sometimes you have multiple cases in which you need to get the exit code. For example, you might need to hide its output, but still return the exit code, or print both the exit code and the output.

ec() < [[ "$1" == "-h" ]] && < shift && eval $* >/dev/null 2>&1; ec=$?; echo $ec; > || eval $*; ec=$?; > 

This will give you the option to suppress the output of the command you want the exit code for. When the output is suppressed for the command, the exit code will directly be returned by the function.

I personally like to put this function in my .bashrc file.

Below I demonstrate a few ways in which you can use this:

# In this example, the output for the command will be # normally displayed, and the exit code will be stored # in the variable $ec. $ ec echo test test $ echo $ec 0 
# In this example, the exit code is output # and the output of the command passed # to the `ec` function is suppressed. $ echo "Exit Code: $(ec -h echo test)" Exit Code: 0 
# In this example, the output of the command # passed to the `ec` function is suppressed # and the exit code is stored in `$ec` $ ec -h echo test $ echo $ec 0 

Solution to your code using this function

#!/bin/bash if [[ "$(ec -h 'ls -l | grep p')" != "0" ]]; then echo "Error when executing command: 'grep p' [$ec]" exit $ec; fi 

You should also note that the exit code you will be seeing will be for the grep command that’s being run, as it is the last command being executed. Not the ls .

Источник

Bash Exit Code of Last Command

When a bash command is executed, it leaves behind the exit code, irrespective of successful or unsuccessful execution. Examining the exit code can offer useful insight into the behavior of the last-run command.

In this guide, check out how to check bash exit code of the last command and some possible usages of it.

Bash Exit Code

Every UNIX/Linux command executed by the shell script or user leaves an exit status. It’s an integer number that remains unchanged unless the next command is run. If the exit code is 0, then the command was successful. If the exit code is non-zero (1-255), then it signifies an error.

Читайте также:  Установка zoom alt linux

There are many potential usages of the bash exit code. The most obvious one is, of course, to verify whether the last command is executed properly, especially if the command doesn’t generate any output.

In the case of bash, the exit code of the previous command is accessible using the shell variable “$?”.

Checking Bash Exit Code

Launch a terminal, and run any command.

Check the value of the shell variable “$?” for the exit code.

As the “date” command ran successfully, the exit code is 0. What would happen if there was an error?

Let’s try running a command that doesn’t exist.

It’s a non-zero value, indicating that the previous command didn’t execute properly.

Now, have a look at the following command:

When working with a command that has one or more pipes, the exit code will be of the last code executed in the pipe. In this case, it’s the grep command.

As the grep command was successful, it will be 0.

In this example, if the grep command fails, then the exit code will be non-zero.

Incorporating Exit Code in Scripts

The exit code can also be used for scripting. One simple way to use it is by assigning it to a shell variable and working with it. Here’s a sample shell script that uses the exit code as a condition to print specific output.

$ #!/bin/bash
$ echo «hello world»
$ status = $?
$ [ $status -eq 0 ] && echo «command successful» || echo «command unsuccessful»

When being run, the script will generate the following output.

Now, let’s see what happens when there’s an invalid command to run.

$ #!/bin/bash
$ random-command
$ status = $?
$ [ $status -eq 0 ] && echo «command successful» || echo «command unsuccessful»

When being run, the output will be different.

Exit Code Value Explanation

When the exit code is non-zero, the value ranges from 1 to 255. Now, what does this value mean?

While the value is limited, the explanation of each value is unique to the program/script. For example, “ls” and “grep” has different explanations for error code 1 and 2.

Defining Exit Status in Script

When writing a script, we can define custom exit code values. It’s a useful method for easier debugging. In bash scripts, it’s the “exit” command followed by the exit code value.

Per the convention, it’s recommended to assign exit code 0 for successful execution and use the rest (1-255) for possible errors. When reaching the exit command, the shell script execution will be terminated, so be careful of its placement.

Have a look at the following shell script. Here, if the condition is met, the script will terminate with the exit code 0. If the condition isn’t met, then the exit code will be 1.

$ #!/bin/bash
$ if [ [ » $(whoami) » ! = root ] ] ; then
$ echo «Not root user.»
$ exit 1
$ fi
$ echo «root user»
$ exit 0

Verify the result of running this script without sudo privilege or “root” user.

Final Thoughts

This guide demonstrates what exit codes are and how you can use them. It also demonstrates how to assign appropriate exit codes in a bash script.

Interested in bash scripting? One of the easiest ways to get started is by writing your own scripts. Check out this simple guide on how to write a simple bash script.

Читайте также:  Менять права доступа linux

About the author

Sidratul Muntaha

Student of CSE. I love Linux and playing with tech and gadgets. I use both Ubuntu and Linux Mint.

Источник

How to configure bash to print exit status for every command?

Every command run in bash returns with an exit code. Whenever I type a command on bash prompt, I want it to show the exit status, i.e., echo $? e.g., if I run echo «hello»; on bash prompt, the output should be:

linux@linux$ hello linux@linux$ 0 

3 Answers 3

The exit code from the last executed command is stored in the $? environment variable. So you just can add this variable to the default command prompt and you will always have the exit code printed there. The prompt is stored in the $PS1 environment variable. It is initially set in the /etc/bash.bashrc script and later in the $HOME/.bashrc .

So edit the line in $HOME/.bashrc ( /etc/bash.bashrc would be system wide) from it’s default value:

So the default prompt in changed to:

The 0 in the brackets is your exit code, see:

user@host:~[0] $ ls user@host:~[0] $ ls /root/ ls: cannot open directory /root/: Permission denied user@host:~[2] $ ^C user@host:~[130] $ 

I tried doing it but for the bash at hand, its not working. it always shows [0] for the machine I am working on.

Are you sure that you run a bash? Can you copy the output of readlink /proc/$$/exe please? 0 means no error, have you tried something that gives an error: ^C or false or asdasdasd ?

@chaos I have my PS1 as PS1=$(printf «%s\\\\u@\h:%s%s\w[$?]$%s » «$yellow» «$end» «$blue» «$end») , but it just shows 0 all the time. Any idea why?

@max It’s because your $? is already expanded to 0 when setting your PS1 . Do echo $PS1 and you’ll see. You have to either use single quotes, or escape it like \$? .

Another way that I picked from the Arch Wiki was to use trap :

$ ( exit 1 ) code 1 $ some-non-existent-command some-non-existent-command: command not found code 127 $ 

That doesn’t quite meet the OP’s requirements, since he wants to print the exit status even if it’s zero — but it’s exactly what I’ve been looking for.

Running the top code through shellcheck prints a couple of warnings: (1) This apostrophe terminated the single quoted string! (2) This word is outside of quotes. Did you intend to ‘nest ‘»‘single quotes'»‘ instead’?. If code is updated to: echo -e «\e[1;33m code $? \e[m\n» it solves the chellcheck warnings and still works exactly as intended.

If using double quotes, then you have to add a backslash to escape the $ :

0 > echo 'ok' ok 0 > bogus bogus: command not found 127 > 

An even better way is to only print the exit code when it is non-zero.

PS1='$> ' # single quote example PS1="\$> " # double quote example (requires extra backslash) 
> echo 'ok' ok > bogus bogus: command not found 127> 

Explanation: $ is a bash parameter expansion that means remove the shortest matching pattern from the front of $var. So in this case, we are removing 0 from the front of $? , which would effectively truncate an exit code of 0 .

If using double quotes, $? would be substituted when PS1 is set, instead of being evaluated each time. Do echo $PS1 to confirm you don’t have a hardcoded value in PS1 .

Источник

Оцените статью
Adblock
detector