How can I assign the output of a function to a variable using bash?

前端 未结 3 1725
小蘑菇
小蘑菇 2020-12-23 09:06

I have a bash function that produces some output:

function scan {
  echo \"output\"
}

How can I assign this output to a variable?

相关标签:
3条回答
  • 2020-12-23 09:21

    You may use bash functions in commands/pipelines as you would otherwise use regular programs. The functions are also available to subshells and transitively, Command Substitution:

    VAR=$(scan)
    

    Is the straighforward way to achieve the result you want in most cases. I will outline special cases below.

    Preserving trailing Newlines:

    One of the (usually helpful) side effects of Command Substitution is that it will strip any number of trailing newlines. If one wishes to preserve trailing newlines, one can append a dummy character to output of the subshell, and subsequently strip it with parameter expansion.

    function scan2 () {
        local nl=$'\x0a';  # that's just \n
        echo "output${nl}${nl}" # 2 in the string + 1 by echo
    }
    
    # append a character to the total output.
    # and strip it with %% parameter expansion.
    VAR=$(scan2; echo "x"); VAR="${VAR%%x}"
    
    echo "${VAR}---"
    

    prints (3 newlines kept):

    output
    
    
    ---
    

    Use an output parameter: avoiding the subshell (and preserving newlines)

    If what the function tries to achieve is to "return" a string into a variable , with bash v4.3 and up, one can use what's called a nameref. Namerefs allows a function to take the name of one or more variables output parameters. You can assign things to a nameref variable, and it is as if you changed the variable it 'points to/references'.

    function scan3() {
        local -n outvar=$1    # -n makes it a nameref.
        local nl=$'\x0a'
        outvar="output${nl}${nl}"  # two total. quotes preserve newlines
    }
    
    VAR="some prior value which will get overwritten"
    
    # you pass the name of the variable. VAR will be modified.
    scan3 VAR
    
    # newlines are also preserved.
    echo "${VAR}==="
    

    prints:

    output
    
    ===
    

    This form has a few advantages. Namely, it allows your function to modify the environment of the caller without using global variables everywhere.

    Note: using namerefs can improve the performance of your program greatly if your functions rely heavily on bash builtins, because it avoids the creation of a subshell that is thrown away just after. This generally makes more sense for small functions reused often, e.g. functions ending in echo "$returnstring"

    This is relevant. https://stackoverflow.com/a/38997681/5556676

    0 讨论(0)
  • 2020-12-23 09:41
    VAR=$(scan)
    

    Exactly the same way as for programs.

    0 讨论(0)
  • 2020-12-23 09:43

    I think init_js should use declare instead of local!

    function scan3() {
        declare -n outvar=$1    # -n makes it a nameref.
        local nl=$'\x0a'
        outvar="output${nl}${nl}"  # two total. quotes preserve newlines
    }
    
    0 讨论(0)
提交回复
热议问题