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

Bre*_*nt 76 variables bash function

我有一个bash函数,可以产生一些输出:

function scan {
  echo "output"
}
Run Code Online (Sandbox Code Playgroud)

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

即.VAR =扫描(当然这不起作用 - 它使VAR等于字符串"scan")

小智 119

VAR=$(scan)
Run Code Online (Sandbox Code Playgroud)

与程序完全相同.

  • 当我做"echo $ VAR"时,我发现换行线被剥离了.如果我引用$ VAR,它会保留换行符. (3认同)
  • 这会创建一个子shell; 有没有办法在同一个shell中做到这一点? (3认同)
  • 这不是100%正确.命令替换始终会删除尾随换行符. (2认同)
  • @lmat-ReinstateMonica 您可以在 bash 4.3 及更高版本中使用所谓的“nameref”来实现这一点。[这个答案](/sf/answers/2795163381/)涵盖了一些概念。 (2认同)

ini*_*_js 18

您可以在命令/管道中使用bash函数,就像使用常规程序一样.这些功能也可用于子壳和传递,命令替换:

VAR=$(scan)
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,是实现所需结果的直接方式.我将在下面概述特殊情况.

保留尾随换行符:

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

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

output


---
Run Code Online (Sandbox Code Playgroud)

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

如果函数试图实现的是将字符串"返回"变量,使用bash v4.3及更高版本,可以使用所谓的a nameref.Namerefs允许函数获取一个或多个变量输出参数的名称.您可以将事物分配给nameref变量,就好像您更改了它指向/ 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}==="
Run Code Online (Sandbox Code Playgroud)

打印:

output

===
Run Code Online (Sandbox Code Playgroud)

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

注意:如果你的函数很大程度上依赖于bash内置函数,使用namerefs可以极大地提高程序的性能,因为它可以避免创建一个刚刚抛弃的子shell.这通常对于经常重复使用的小函数更有意义,例如以函数结尾echo "$returnstring"

这是相关的./sf/answers/2729837701/