bash 在函数内声明全局变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9871458/
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
Declaring global variable inside a function
提问by Leonid99
What I want to do is following. Inside a function, I need to assign a value to a variable, whose name is taken from another variable. In other words:
我想做的是跟随。在函数内部,我需要为一个变量赋值,该变量的名称取自另一个变量。换句话说:
func() {
#
# Here happens something that ultimately makes $arg="var_name"
#
declare -g ${arg}=5
}
func
echo ${var_name}; # Prints out "5"
The code snippet above works great in bash 4.2. However, in bash before 4.2, declare
doesn't have the -g
option. Everything I found at google says that to define the global variable inside a function, I should just use the var=value
syntax, but unfortunately var
itself depends on another variable. ${arg}=5
doesn't work, either. (It says -bash: var_name=5: command not found
.
上面的代码片段在 bash 4.2 中效果很好。但是,在 bash 4.2 之前,declare
没有-g
选项。我在 google 找到的所有内容都说要在函数内定义全局变量,我应该只使用var=value
语法,但不幸的是,var
它本身取决于另一个变量。${arg}=5
也不行。(它说-bash: var_name=5: command not found
。
For the curious, the reason for all this is that this function actually creates global variables from the script parameters, i.e. running script --arg1=val
automatically creates variable named arg1
with value val
. Saves tons of a boilerplate code.
出于好奇,这一切的原因是这个函数实际上从脚本参数创建了全局变量,即运行script --arg1=val
自动创建以arg1
value命名的变量val
。节省大量样板代码。
采纳答案by minopret
You could construct your var=value as a string and evaluate it using the bash builtin command eval
.
您可以将 var=value 构造为字符串并使用 bash 内置命令对其进行评估eval
。
回答by kipibenkipod
declare
inside a function doesn't work as expected.
I needed read-only global variables declared in a function.
I tried this inside a function but it didn't work:
declare
函数内部无法按预期工作。我需要在函数中声明的只读全局变量。我在一个函数中尝试过这个,但没有用:
declare -r MY_VAR=1
But this didn't work. Using the readonly
command did:
但这没有用。使用readonly
命令做了:
func() {
readonly MY_VAR=1
}
func
echo $MY_VAR
MY_VAR=2
This will print 1 and give the error "MY_VAR: readonly variable" for the second assignment.
这将打印 1 并为第二个赋值给出错误“MY_VAR:只读变量”。
回答by William Pursell
Since this is tagged shell
, it is important to note that declare
is a valid keyword only in a limited set of shells, so whether it supports -g is moot. To do this sort of thing in a generic Bourne shell, you can just use eval:
由于 this 被标记为shell
,重要的是要注意它declare
仅在有限的一组 shell中是一个有效的关键字,因此它是否支持 -g 是没有实际意义的。要在通用 Bourne shell 中执行此类操作,您只需使用 eval:
eval ${arg}=5
回答by gniourf_gniourf
I think you need the printf
builtin with its -v
switch:
我认为你需要printf
内置的-v
开关:
func() {
printf -v "$var" '5'
}
var=var_name
func
echo "$var_name"
will output 5
.
将输出5
.
回答by Beorn Harris
Using "eval" (or any direct assignment) can give you headaches with special characters (or issues with value injection etc).
使用“eval”(或任何直接赋值)会让您对特殊字符(或值注入等问题)感到头疼。
I've had great success just using "read"
我只使用“阅读”就取得了巨大的成功
$ function assign_global() {
> local arg=""
> IFS="" read -d "" $arg <<<""
>}
$ assign_global MYVAR 23
echo $MYVAR
23
$ assign_global MYVAR "\"'"
"'
回答by Zach
If you want something a little less hackish, try using export
in place of declare -g
. It has the added benefit of being an environment variable now.
如果你想要一些不那么骇人听闻的东西,请尝试使用export
代替declare -g
. 它现在具有作为环境变量的额外好处。
func() {
#
# Here happens something that ultimately makes $arg="var_name"
#
export ${arg}=5
}
func
echo ${var_name}; # Prints out "5"
Unfortunately, this still does not work for arrays.
不幸的是,这仍然不适用于数组。
回答by tomy
In Bash for declaring array variables inside a function definition you can use the local
command in combination with the eval
command like in the following example:
在 Bash 中,为了在函数定义中声明数组变量,您可以将该local
命令与eval
以下示例中的命令结合使用:
#!/bin/bash
function test
{
local -g
local array=( AA BB 'C C' DD)
eval ='("${array[@]}")'
}
test VAR
echo VAR=${VAR[@]:1:2}
the output will be:
输出将是:
$./test.sh
VAR=BB C C
works with: GNU bash, Version 4.4.18
适用于:GNU bash,版本 4.4.18
回答by Ekeyme Mo
Maybe your could use the following functions to dynamically assign your global variable in bash(< 4.2). If > 2 args passed, then the value will be array type. E.G
也许您可以使用以下函数在 bash(< 4.2) 中动态分配全局变量。如果 > 2 args 传递,则该值将是数组类型。例如
_set2globals variable_name arg1 [arg2] [arg3] [...]
Source:
来源:
# dynamically set $variable_name()=$values(...) to globals scope
function _set2globals()
{
if (( $# < 2 )); then
printf "$FUNCNAME: expect at least 2 argument, but %d you given.\n" $# >&2
exit 1
fi
local ___pattern_='^[_a-zA-Z][_0-9a-zA-Z]*$'
if [[ ! =~ $___pattern_ ]]; then
printf "$FUNCNAME: invalid variable name: %s.\n" "" >&2
exit 1
fi
local __variable__name__=
shift
local ___v_
local ___values_=()
while (($# > 0)); do
___v_=\'${1//"'"/"'\''"}\'
___values_=("${___values_[@]}" "$___v_") # push to array
shift
done
eval $__variable__name__=\("${___values_[@]}"\)
}
回答by ASG
Eval will work with Array variables...I just had to single quote the local Array variable inside the eval statement.
Eval 将使用 Array 变量...我只需要在 eval 语句中用单引号引用局部 Array 变量。
The below reads in a file (1st arg) a line at a time and then copies it to the variable name passed to the 2nd arg of the get_file.
下面一次读入一个文件(第一个参数)一行,然后将其复制到传递给 get_file 的第二个参数的变量名中。
get_file () {
declare -a Array=();
while read line; do
Array=("${Array[@]}" "($line)")
done <
eval ='("${Array[@]}")'
unset Array
}
declare -a my_array=();
get_file /etc/myfile.conf my_array
echo ${#my_array[@]}