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

问题描述 投票:0回答:4

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

function scan {
  echo "output"
}

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

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

bash variables function
4个回答
208
投票
VAR=$(scan)

与程序完全相同。


38
投票

您可以在命令/管道中使用 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


0
投票

我认为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
}

0
投票

为了清楚起见,现在可以通过“nameref”或“命名引用”将 var 传递给 bash 函数,并且该函数将能够修改该确切引用。

示例:

function scrapeToMem() {
  # param 1: url
  local url=$1
  # param 2: use a 'nameref' to return
  local -n result=$2

  # get html in memory variable:
  result=$(wget -qnv --show-progress -O - "${url}")

  if [[ -z "${result}" ]]; then
    return 1
  fi

  return 0
}

urlLatest='https://www.google.com'
scrapeFile=
scrapeToMem "${urlLatest}" scrapeFile
if [ $? -ne 0 ]; then
  echo "Error encountered #1."
  exit 1
fi

if [[ -z "${scrapeFile}" ]]; then
  echo "Error encountered #1."
fi
© www.soinside.com 2019 - 2024. All rights reserved.