How to Return Exit Code 0 from a Failed Command

How to return exit code 0 from a failed command

Simply append return 0 to the function to force a function to always exit successful.

function a() {
ls aaaaa 2>&1
return 0
}

a
echo $? # prints 0

If you wish to do it inline for any reason you can append || true to the command:

ls aaaaa 2>&1 || true
echo $? # prints 0

If you wish to invert the exit status simple prepend the command with !

! ls aaaaa 2>&1
echo $? # prints 0

! ls /etc/resolv.conf 2>&1
echo $? # prints 1

Also if you state what you are trying to achieve overall we might be able to guide you to better answers.

bash execute whole script but return exit code 0 if any intermediate job has failed

You can trap errors:

#!/bin/bash

echo "test start."

trap 'rc=$?' ERR

./error.sh
./script2.sh

echo "test done."
return ${rc}

For more information on how traps work, see trap.

How to make the sh script return an error code from the executed command?

Just do:

#!/bin/sh

pppd call "${@:-provider}" || exit
...

or

if pppd call "${@:-provider}"; then : ; else exit; fi

If pppd fails, the script will exit and the value it returns will be that returned by pppd. (You could explicitly write exit $?, but that is the default value returned by exit when no argument is given and is not necessary.) If pppd succeeds, the script will continue.

The problem with your script (other than the ill-advised usage of exec, which I will mostly ignore) is that calling [ $? -ne 0 ] resets $?. You could re-write your script as:

#!/bin/sh

pppd call "${@:-provider}"
save_val=$?
if ! [ $save_val -eq 0 ]
then
exit $save_val
fi

but that seems excessively verbose.

Note that in your original script, you would get an error on the line if [ $? !-eq 0 ], since !-eq is not a valid operator. However, you never see that error because your early invocation of exec makes it so that line is never executed.

python subprocess with failed command return code 0

Running the shell command (equivalent to your given subprocess.Popen() call if we disregard the use of "smart quotes")

'python' '-c' '"import xxx"'

correctly exits with status 0, whether or not a module named xxx exists.

This is because "import xxx" is a string, and evaluating a string does not throw an exception. You'd get the exact same behavior from python -c '"hello world"', or any other string.


If you really want to try executing the code import xxx, then you need to remove the extra quotes:

subprocess.Popen(['python', '-c', 'import xxx']).wait()

...will properly return 1 (if no xxx module exists).

How to exit if a command failed?

Try:

my_command || { echo 'my_command failed' ; exit 1; }

Four changes:

  • Change && to ||
  • Use { } in place of ( )
  • Introduce ; after exit and
  • spaces after { and before }

Since you want to print the message and exit only when the command fails ( exits with non-zero value) you need a || not an &&.

cmd1 && cmd2

will run cmd2 when cmd1 succeeds(exit value 0). Where as

cmd1 || cmd2

will run cmd2 when cmd1 fails(exit value non-zero).

Using ( ) makes the command inside them run in a sub-shell and calling a exit from there causes you to exit the sub-shell and not your original shell, hence execution continues in your original shell.

To overcome this use { }

The last two changes are required by bash.

Consider a specific exit code not a failure and proceed

There are some problems cmd1 || $(($?==253 ? true : false) && cmd2:

  • A ) is missing after false.
  • You don't want $(( ... )) but (( ... )). The former would execute the result of the expression (that is a number!) as a command. The latter just evaluates the expression and fails if the result is 0 and succeeds otherwise. Note that is the opposite of how exit codes work.
  • true and false are not commands here, but variables. If an undefined variable is used inside (( ... )) its value is always 0. Therefore the command ((... ? true : false)) always fails.

Here is want you could have written instead:

cmd1 || (($?==253 ? 1 : 0)) && cmd2

Test:

prompt$ true || (($?==253 ? 1 : 0)) && echo ok
ok
prompt$ false || (($?==253 ? 1 : 0)) && echo ok
prompt$ ( exit 253; ) || (($?==253 ? 1 : 0)) && echo ok
ok

However, the ternary operator isn't really needed here. The following would be equivalent:

cmd1 || (($?==253)) && cmd2

Despite that, an if would probably be better. If you don't want to use one inline, you can write a function for that:

# allow all exit codes given as the first argument
# multiple exit codes can be comma separated
allow() {
ok=",$1,"
shift
"$@"
[[ "$ok" = *,$?,* ]]
}
allow 0,253 cmd1 && cmd2

Or define a wrapper just for this one command

cmd1() {
command cmd1 "$@" || (( $? == 253 ))
}
cmd1 && cmd2


Related Topics



Leave a reply



Submit