【问题标题】:How can I assign the output of a function to a variable using bash?如何使用 bash 将函数的输出分配给变量?
【发布时间】:2010-12-21 01:28:13
【问题描述】:

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

function scan {
  echo "output"
}

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

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

【问题讨论】:

标签: bash variables function


【解决方案1】:
VAR=$(scan)

与程序完全相同。

【讨论】:

  • 我发现当我执行“echo $VAR”时,换行符被剥离了。相反,如果我引用 $VAR,它会保留换行符。
  • 这不是 100% 正确的。命令替换总是去掉尾随的换行符。
  • 这会创建一个子shell;有什么办法可以在同一个shell中做到这一点?
  • @lmat-ReinstateMonica 您可以在 bash 4.3 及更高版本中使用所谓的 nameref 来实现这一目标。 this answer 涵盖了一些概念。
【解决方案2】:

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

VAR=$(scan)

在大多数情况下,这是实现您想要的结果的直接方法。我将在下面概述特殊情况。

保留尾随换行符:

命令替换的一个(通常有用的)副作用是它会去除任意数量的尾随换行符。如果希望保留尾随换行符,可以在子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}---"

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

output


---

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

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

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}==="

打印:

output

===

这种形式有几个优点。也就是说,它允许您的函数修改调用者的环境,而无需在任何地方使用全局变量。

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

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

【讨论】:

    【解决方案3】:

    我认为 init_js 应该使用 declare 而不是 local!

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

    【讨论】:

    • local builtin 将接受 declare builtin 将接受的任何选项。从快速测试来看,似乎declare -n 在函数范围内也提供了变量局部范围。似乎它们在这里可以互换。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    相关资源
    最近更新 更多