Differences between revisions 1 and 10 (spanning 9 versions)
Revision 1 as of 2007-07-26 13:00:33
Size: 2297
Editor: GreyCat
Comment: "How do I return a string from a function? "return" only lets me give a number."
Revision 10 as of 2011-11-09 21:24:58
Size: 2660
Editor: GreyCat
Comment: clean up
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
== How do I return a string from a function? "return" only lets me give a number. ==

Functions in Bash (as well as all the other Bourne-family shells) work like commands; that is, they only "return" an exit status, which is a number from 0 to 255 inclusive. This is intended to be used only for signaling errors, not for returning the results of computations, or other data.
<<Anchor(faq84)>>
== How do I return a string (or large number, or negative number) from a function? "return" only lets me give a number from 0 to 255. ==
Functions in Bash (as well as all the other Bourne-family shells) work like commands: that is, they only "return" an exit status, which is an integer from 0 to 255 inclusive. This is intended to be used only for signaling errors, not for returning the results of computations, or other data.
Line 13: Line 13:
  echo "foo returned '$x'"}}}
 The drawback of this method is that the function is executed in a ''subshell'', which means that any variable assignments, etc. performed in the function will not take effect in the caller's environment. This may or may not be a problem, depending on the needs of your program and your function.
  echo "foo returned '$x'"
  }}}
 One drawback of this method is that the function is executed in a SubShell, which means that any variable assignments, etc. performed in the function will not take effect in the caller's environment (and incurs a speed penalty as well, due to a `fork()`). This may or may not be a problem, depending on the needs of your program and your function. Another drawback is that ''everything'' printed by the function `foo` is captured and put into the variable instead. This leads to problems if `foo` also writes things that are not intended to be a returned value.
Line 19: Line 20:
     RETURN="this is my data"      return="this is my data"
Line 22: Line 23:
  echo "foo returned '$RETURN'"}}}
 The drawback of this method is that, if the function ''is'' executed in a subshell, then the assignment to a global variable inside the function will ''not'' be seen by the caller. This means you would not be able to use the function in a pipeline, for example.
  echo "foo returned '$return'"
  
}}}
 The drawback of this method is that if the function ''is'' executed in a subshell, then the assignment to a global variable inside the function will ''not'' be seen by the caller. This means you would not be able to use the function in a pipeline, for example.
Line 31: Line 33:
  TMPFILE=$(mktemp) # GNU/Linux
  foo "$TMPFILE"
  echo "foo returned '$(<"$TMPFILE")'"
  rm "$TMPFILE"
  # In the event that this were a real program, there
  #
would have been error checking, and a trap.}}}
  tmpfile=$(mktemp) # GNU/Linux
  foo "$tmpfile"
  echo "foo returned '$(<"$tmpfile")'"
  rm "$tmpfile"
  # If this were a real program, there would have been error checking, and a trap.
  
}}}
Line 38: Line 40:
 For more information about handling temporary files within a shell script, see [#faq62 FAQ 62].  For more information about handling temporary files within a shell script, see [[BashFAQ/062|FAQ 62]].  For traps, see SignalTrap.

How do I return a string (or large number, or negative number) from a function? "return" only lets me give a number from 0 to 255.

Functions in Bash (as well as all the other Bourne-family shells) work like commands: that is, they only "return" an exit status, which is an integer from 0 to 255 inclusive. This is intended to be used only for signaling errors, not for returning the results of computations, or other data.

If you need to send back arbitrary data from a function to its caller, there are at least three methods by which this can be achieved:

  • You may have your function write the data to stdout, and then have the caller capture stdout.
    •   foo() {
           echo "this is my data"
        }
        x=$(foo)
        echo "foo returned '$x'"

    One drawback of this method is that the function is executed in a SubShell, which means that any variable assignments, etc. performed in the function will not take effect in the caller's environment (and incurs a speed penalty as well, due to a fork()). This may or may not be a problem, depending on the needs of your program and your function. Another drawback is that everything printed by the function foo is captured and put into the variable instead. This leads to problems if foo also writes things that are not intended to be a returned value.

  • You may assign data to global variables, and then refer to those variables in the caller.
    •   foo() {
           return="this is my data"
        }
        foo
        echo "foo returned '$return'"

    The drawback of this method is that if the function is executed in a subshell, then the assignment to a global variable inside the function will not be seen by the caller. This means you would not be able to use the function in a pipeline, for example.

  • Your function may write its data to a file, from which the caller can read it.
    •   foo() {
           echo "this is my data" > "$1"
        }
        # This is NOT solid code for handling temp files!
        tmpfile=$(mktemp)   # GNU/Linux
        foo "$tmpfile"
        echo "foo returned '$(<"$tmpfile")'"
        rm "$tmpfile"
        # If this were a real program, there would have been error checking, and a trap.
    The drawbacks of this method should be obvious: you need to manage a temporary file, which is always inconvenient; there must be a writable directory somewhere, and sufficient space to hold the data therein; etc. On the positive side, it will work regardless of whether your function is executed in a subshell.

    For more information about handling temporary files within a shell script, see FAQ 62. For traps, see SignalTrap.

BashFAQ/084 (last edited 2022-11-14 19:36:10 by GreyCat)