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")
即。 VAR =扫描(当然这不起作用 - 它使VAR等于字符串“scan”)
3 个解决方案
#1
96
VAR=$(scan)
Exactly the same way as for programs.
与程序完全相同。
#2
9
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函数,就像使用常规程序一样。这些功能也可用于子壳和传递,命令替换:
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及更高版本,可以使用所谓的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}==="
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://*.com/a/38997681/5556676
这是相关的。 https://*.com/a/38997681/5556676
#3
0
I think init_js should use declare instead of local!
我认为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
}
#1
96
VAR=$(scan)
Exactly the same way as for programs.
与程序完全相同。
#2
9
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函数,就像使用常规程序一样。这些功能也可用于子壳和传递,命令替换:
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及更高版本,可以使用所谓的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}==="
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://*.com/a/38997681/5556676
这是相关的。 https://*.com/a/38997681/5556676
#3
0
I think init_js should use declare instead of local!
我认为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
}