如何使用 bash 将函数的输出分配给变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1809899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:43:41  来源:igfitidea点击:

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

bashvariablesfunction

提问by Brent

I have a bash function that produces some output:

我有一个生成一些输出的 bash 函数:

function scan {
  echo "output"
}

How can I assign this output to a variable?

如何将此输出分配给变量?

ie. VAR=scan (of course this doesn't work - it makes VAR equal the string "scan")

IE。VAR=scan(当然这不起作用 - 它使 VAR 等于字符串“scan”)

回答by Robert Obryk

VAR=$(scan)

Exactly the same way as for programs.

与程序完全相同的方式。

回答by init_js

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:

您可以在命令/管道中使用 bash 函数,就像使用常规程序一样。这些函数也可用于 subshel​​l 和可传递的命令替换:

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.

命令替换的一个(通常有用的)副作用是它会删除任意数量的尾随换行符。如果希望保留尾随换行符,可以在子 shell 的输出中附加一个虚拟字符,然后通过参数扩展将其剥离。

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):

打印(保留 3 个换行符):

output


---

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

使用输出参数:避免使用子shell(并保留换行符)

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'.

如果该函数试图实现的是将一个字符串“返回”到一个变量中,在 bash v4.3 及更高版本中,可以使用所谓的 a nameref。Namerefs 允许函数采用一个或多个变量的名称作为输出参数。您可以将事物分配给 nameref 变量,就好像您更改了它“指向/引用”的变量一样。

function scan3() {
    local -n outvar=    # -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"

注意:如果您的函数严重依赖 bash 内置函数,则使用 namerefs 可以极大地提高程序的性能,因为它避免了创建之后被丢弃的子shell。这通常对于经常重用的小函数更有意义,例如以echo "$returnstring"

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

这是相关的。https://stackoverflow.com/a/38997681/5556676

回答by Hamid Reza Hasani

I think init_js should use declare instead of local!

我认为 init_js 应该使用声明而不是本地!

function scan3() {
    declare -n outvar=    # -n makes it a nameref.
    local nl=$'\x0a'
    outvar="output${nl}${nl}"  # two total. quotes preserve newlines
}