11

In my project I have the following snippet:

local output="$(bash "${1##*/}")"
echo "$?"

This always prints zero due to local, however, removing local causes the $? variable to behave correctly: which is to assume the exit code from the subshell.

My question is: how I can keep this variable local whilst also capturing the exit value?

16
#!/bin/bash
thing() {
   local foo=$(asjkdh) ret="$?"
   echo "$ret"
}

This will echo 127, the correct error code for "command not found".

You can use local to define more than one variable. So I just also create the local variable RET to capture the exit code of the subshell before local succeeds and sets $? to zero.

  • Is it guaranteed that bash evaluates this expression left to right? – Max Ried May 7 '16 at 21:43
  • As far as I am aware, variable assignments are in order, left to right in this context, yes. – DopeGhoti May 7 '16 at 22:19
  • @MaxRied the fact this works reliably would appear to indicate that yes, it is. However, I can find no information about this neither from POSIX nor bash's reference manual. – cat May 7 '16 at 22:19
  • 10
    As an aside, using all-caps variable names is bad form. See the POSIX environment variable spec at pubs.opengroup.org/onlinepubs/009695399/basedefs/…, which describes all-upper-case names as reserved for variables with meaning to the shell or system and names with at least one lower-case character reserved for application-defined use, keeping in mind that shell variables and environment variables share a namespace (since, in the event of collisions, assigning to the former can override the latter). – Charles Duffy May 7 '16 at 23:29
  • Comments are not for extended discussion; this conversation has been moved to chat. – terdon May 9 '16 at 8:06
27

Declare the local variable before you assign to it:

thing() {
  local output
  output="$(bash "${1##*/}")"
  echo "$?"
}

In my opinion this is also more readable than setting an additional RET variable. YMMV on that, but it works just as you would expect.

  • 2
    This is much better than using a separate variable, as should be obvious if you want to check the return code of multiple assignments: simply local var1 var2 ... and Bob's your uncle. – l0b0 May 8 '16 at 8:08
  • @l0b0 Bob is my uncle. :D – cat May 8 '16 at 16:12

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.