Is there any way to check if there is an error in executing a command?

Example :

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 

I already tried do that but it seems it isn't working. I don't how do that.


The return value is stored in $?. 0 indicates success, others indicates error.

if [ $? -eq 0 ]; then
    echo OK
    echo FAIL

Like any other textual value, you can store it in a variable for future comparison:

do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"

For possible comparison operators, see man test.

  • That's nice ...can i hold the output error ??!! , because in this case i have 2 error : command error "text" ex, file not found and my error "text" Which is in this case failed for example – moata_u Mar 7 '11 at 12:28
  • @moata_u: you can store the value in a variable as shown in my answer. – Lekensteyn Mar 7 '11 at 13:14
  • @moata_u: You need to put a ; before the else and fi: `if ...; then ...; else ...; fi – Lekensteyn Mar 7 '11 at 14:36
  • 4
    This is a useless use of test. – David Foerster Dec 1 '14 at 22:04
  • 2
    @Blauhirn [ $? ] (or equivalently, test $?) does not work because $? evaluates to a number (0, 1, etc.) which is not null. See the docs for test: "If EXPRESSION is omitted, ‘test’ returns false. If EXPRESSION is a single argument, ‘test’ returns false if the argument is null and true otherwise." – Lekensteyn Mar 25 '16 at 18:31

If you only need to know if the command succeeded or failed, don't bother testing $?, just test the command directly. E.g.:

if some_command; then
    printf 'some_command succeeded\n'
    printf 'some_command failed\n'

And assigning the output to a variable doesn't change the return value (well, unless it behaves differently when stdout isn't a terminal of course).

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"

http://mywiki.wooledge.org/BashGuide/TestsAndConditionals explains if in more detail.

  • What if you want to do something other than branching like storing the boolean of whether it failed or not into a .ini? Then your output variable doesn't do that, but $? does, so you're incorrect in saying that testing the command directly is strictly better. – Timothy Swan Nov 30 '17 at 15:53
  • 1
    Assigning the output to a variable may change the return value when one uses local command, i.e. local foo=$(false); echo $?; produces 0 on the output. But local is only relevant inside of bash functions. – Cromax Jan 22 '19 at 13:45
  • I can't seem to use an else with the variable example. Any idea why? – Hashim Aziz Sep 21 '20 at 22:26
  • 1
    @Prometheus hard to say without seeing the code. Perhaps it incorrectly returns 0 in the case you considered a failure, or perhaps you added additional commands to the command substitution without using && between them. – geirha Sep 22 '20 at 20:06
  • I'm not used to bash scripting. Does the if require some brackets or anything? Can I just have... if cd unreliable_dir; then – osullic Feb 12 at 15:38
command && echo OK || echo Failed
  • If command returns error on screen, how to hide it? – Sigur Apr 21 '17 at 1:51
  • 1
    If command writes errors out to stderr, you can use the form command 2> /dev/null && echo OK || echo Failed. The 2> /dev/null redirects stderr output to /dev/null. However, some utilities will write errors to stdout (even though this is bad practice). In this case you can omit the 2 from the redirection, but you will lose any output from the command. This method of checking success is good for simple ternary logic but for more complex behavior it's best to check $? for command success, or use the if block method outlined in @geirha's answer. – Bender the Greatest Jul 24 '17 at 13:27
  • Note that this is not save in all cases. See: github.com/koalaman/shellcheck/wiki/SC2015 – Tobias Gaertner Apr 14 '20 at 12:25

$? should contain the exit status of the previous command, which should be zero for no error.

So, something like;

cd /nonexistant
if [ $? -ne 0 ]
    echo failed
    echo success!

for most cases, it's easier to use the && construct to chain commands that need to depend on each other. So cd /nonexistant && echo success! would not echo success because the command breaks before &&. The corollary of this is ||, where cd /nonexistant || echo fail would echo fail because cd failed. (this becomes useful if you use something like ||exit, which will end the script if the previous command failed.)

  • That's nice ...can i hold the output error ??!! , because in this case i have 2 error : command error "text" ex, file not found and my error "text" Which is in this case failed for example – moata_u Mar 7 '11 at 12:24
  • @moata_u, see mywiki.wooledge.org/BashFAQ/002 – geirha Mar 8 '11 at 23:55

It should be noted that if...then...fi and &&/|| type of approach deals with exit status returned by command we want to test( 0 on success ); however, some commands don't return a non-zero exit status if command failed or couldn't deal with input. This means that the usual if and &&/|| approaches won't work for those particular commands.

For instance, on Linux GNU file still exits with 0 if it received a non-existing file as argument and find couldn't locate the file user specified.

$ find . -name "not_existing_file"                                          
$ echo $?
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?

In such cases, one potential way we could handle the situation is by reading stderr/stdin messages, e.g. those that returned by file command, or parse output of the command like in find. For that purposes, case statement could be used.

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found

( This is a repost of my own answer on related question at unix.stackexchange.com )

command && echo $? || echo $?
  • You mean command; echo $? ? – Javier Buzzi Nov 16 '18 at 10:32
  • No, my line is correct, it gives the actual result code as a number regardless if success or failure. – modrobert Nov 20 '18 at 20:07
  • 1
    Ok, please explain the differences of these to me: true && echo $? || echo $? / true; echo $? and false && echo $? || echo $? / false; echo $? -- you'll find, they do the exact same thing :D – Javier Buzzi Nov 21 '18 at 11:07
  • Yes, the same result but without the condition. The original question asked was "How to check if a command succeeded?", this was based on previous answers. I guess a better example would be: command && echo "success: $?" || echo "fail: $?" – modrobert Nov 22 '18 at 8:16

As mentioned in many other answers, a simple test of $? will do, like this

if [ $? -eq 0 ]; then something; fi

If you want to test if the command failed, you can use a shorter version in bash (but perhaps overkill) as follows:

if (($?)); then something; fi

This works by using the (( )) arithmetic mode, so if the command returned success, i.e. $? = 0 then the test evaluates to ((0)) which tests as false, otherwise it will return true.

To test for success, you could use:

if ! (($?)); then something; fi

but it's already not much shorter than the first example.


For easier debugging, I make commands to only output errors with:

so [-tag] [commands]

After that $? is 0 if success, otherwise failure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.