Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

With this script: tstNounset.sh

#!/bin/bash
set -x 
set -o nounset;set -u

echo `echo $str`
function FUNC1() { echo $str; };export -f FUNC1;bash -c FUNC1
function FUNC2() { set -u;echo $str; };export -f FUNC2;bash -c FUNC2
echo "A - should not reach here?"
echo $str
echo "B - doesnt reach here."

I would like to prevent reaching "A", in a global manner, not requiring to check each variable for it.

Also without using set -e (as I take care of errors and workaround most already, as many also are only warnings)

I thought if there could have some way to detect "unbound variable" happened even from subshell/child, so I could force an exit from that?

I couldnt make things work from How to have a bash script perform a specific action on errors of _each_ command? or How to trigger error using Trap command also. I found this old question too.

share|improve this question

2 Answers 2

Subshells

There is no way for a subshell to kill the whole script. Under the effect of set -u, a subshell has no way to tell its parent “hey, I want you to treat this as a fatal error”. This wouldn't even make sense if set -u was in effect in the subshell but not in its parent. All the subshell can do is return a nonzero exit code. It's up to you to handle that exit code in the parent, either manually or through set -e.

(set -u; …; echo $undefined_variable)
# here $? is nonzero
ret=$?; if [ $ret -ne 0 ]; then exit $ret; fi

Subprocesses

What you've done here is not a subshell: you're launching another program. That other program happens to be bash, which is also the interpreter that's executing the present script, but it's a coincidence. There is absolutely no reason why a setting in a program invoked by bash would cause bash itself to exit.

set +e
bash -c 'do something'
echo "A - should and does reach here"

This is no different than if you'd written perl -e 'use strict; print $barf' — Perl would die and return a nonzero status but that doesn't cause the bash script to exit (except under set -e). Use set -e if you want to exit when a subprocess returns a nonzero return code.

share|improve this answer
    
It was right in the first sentence, though the ret= thing might be a little much - if I'm one to talk. I just mean that return/exit etc automatically return $? so it's far more efficient to simply detect failure: (false) || return will always return false's parent shell's $?. –  mikeserv Jul 24 at 3:24
    
I am currently checking if some approach could be done with traps ERR, RETURN and DEBUG, but I am still failing horribly :), as I already use DEBUG one for other thing, I will focus on ERR and RETURN. –  Aquarius Power Jul 24 at 18:18

My script was badly coded, but it can be fixed:

Look at the 1st, 2nd and 3rd comments:

  • 1st A TRAP ERR IS REQUIRED
  • 2rd errors that you take care wont be trapped! do not use if ! ... will prevent getting return value with $?
  • 3nd DO NOT ECHO DIRECTLY, use a intermediary variable so the error can be cautch

tstNounset.sh:

#!/bin/bash
trap 'ErrorHappened;exit 1' ERR #1st A TRAP ERR IS REQUIRED

set -x 
set -o nounset;set -u

#echo `echo $str`
nRet=0;if strA="`echo $str`";then : ;else nRet=$?;echo "Err$nRet";fi #2rd errors that you take care wont be trapped! do not use `if ! ...` will prevent getting return value with $?
echo "0 - should not reach here?"
strA="`echo $str`";echo "$strA" #3nd DO NOT ECHO DIRECTLY, use a intermediary variable so the error can be cautch
echo "1 - should not reach here?"
function FUNC1() { echo $str; };export -f FUNC1;bash -c FUNC1
function FUNC2() { set -u;echo $str; };export -f FUNC2;bash -c FUNC2
echo "A - should not reach here?"
echo $str
echo "B - doesnt reach here."
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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