0

In the code below, the "if" statement never succeeds because even if getopt returns a non-0 exit code, the local assignment replaces it with a 0 exit code.

function usage {
    echo "Usage: $(basename $0) [ --help | -? | -h ] | [ --email-to --email-sender ]"
}

function parse_args()
    if ! local -r parsed_args=$(getopt --long email-sender:,email-to:,help -o h -- $@); then
        usage
        exit 1
    fi
    # process $parsed_pargs
}

For example:

function inner {
    echo "failed!"
    return 1
}

function outer {
    local -r result=$(inner)
    echo "exit status=$?"
    echo "result='$result'"

    inner
    echo "2nd exit status=$?"
}

outer

Prints to the console:

exit status=0
result='failed!'
failed!
2nd exit status=1

Is there a workaround for this?

Lawrence I. Siden
  • 9,191
  • 10
  • 43
  • 56
  • 1
    The only workaround I can think of is to capture the output in a temporary variable, then assign the value of the temporary to `result`. But if you're happy with that, there's little reason to declare `result` as read-only in the first place. (If it were me, I would skip making the variable read-only.) – chepner Jan 25 '23 at 13:45
  • 1
    Not all shell features are always (or even ever) useful. – chepner Jan 25 '23 at 13:45
  • 1
    `local` is replacing the exit status. This is a FAQ. – Charles Duffy Jan 25 '23 at 14:05
  • `local result; result=$(inner)` is the conventional thing. Skip the read-only flag as chepner suggests. – Charles Duffy Jan 25 '23 at 14:05
  • See [pitfall 27](http://mywiki.wooledge.org/BashPitfalls#local_var.3D.24.28cmd.29) on the bash wiki. – tjm3772 Jan 25 '23 at 14:05
  • (if you _really insist_ on your variable being flagged read-only, you can apply that flag _after_ the assignment, after applying the local flag before, but... why?!) – Charles Duffy Jan 25 '23 at 14:07
  • BTW, try to avoid the `function` keyword; see relevant entries in both 1st and 3rd tables in https://wiki.bash-hackers.org/scripting/obsolete; the best habit to be in from a portability perspective is using POSIX `inner() {` with no `function` preceding. (in ksh, `function` changes behavior of `typeset`, but it _doesn't_ do that in bash, and even in ksh it doesn't impact `declare` or `local`) – Charles Duffy Jan 25 '23 at 14:08
  • To demonstrate what I meant by "apply that flag after the assignment" -- `f() { local v v_rc; v=$(echo 5; false); v_rc=$?; local -r v; declare -p v v_rc; }; f` – Charles Duffy Jan 25 '23 at 14:11

0 Answers0