如何修改bash中的函数内的全局variables?

我正在处理这个问题:

GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) 

我有一个像下面的脚本:

 #!/bin/bash e=2 function test1() { e=4 echo "hello" } test1 echo "$e" 

哪个返回:

 hello 4 

但是如果我把函数的结果赋值给一个variables,全局variablese就不会被修改:

 #!/bin/bash e=2 function test1() { e=4 echo "hello" } ret=$(test1) echo "$ret" echo "$e" 

返回:

 hello 2 

在这种情况下,我听说过使用eval ,所以我在test1做了这个:

 eval 'e=4' 

但是同样的结果。

你能解释一下为什么它没有被修改? 我怎样才能将ret1中的test1函数的回声保存起来,并修改全局variables呢?

当您使用命令replace(即$(...)构造)时,您正在创build一个子shell。 子壳从它们的父壳体inheritancevariables,但是这只能用一种方法 – 一个子壳不能修改它的父壳体的环境。 你的variablese被设置在一个子shell中,但不是父shell。 有两种方法可以将一个子shell的值传递给它的父项。 首先,你可以输出一些标准输出,然后用一个命令replace来捕获它:

 myfunc() { echo "Hello" } var="$(myfunc)" echo "$var" 

得到:

 Hello 

对于0-255的数值,可以使用return来传递数字作为退出状态:

 myotherfunc() { echo "Hello" return 4 } var="$(myotherfunc)" num_var=$? echo "$var - num is $num_var" 

得到:

 Hello - num is 4 

你在做什么,你正在执行test1

$(test1)

在子shell(子shell)和子shell中不能修改父项中的任何东西

你可以在bash 手册中find它

请检查:在这里的东西产生一个子shell

也许你可以使用一个文件,写入文件里面的function,后面的文件读取。 我已经改变了一个数组。 在这个例子中,当读回数组时,空格被用作分隔符。

 #!/bin/bash declare -ae e[0]="first" e[1]="secondddd" function test1 () { e[2]="third" e[1]="second" echo "${e[@]}" > /tmp/tempout echo hi } ret=$(test1) echo "$ret" read -r -ae < /tmp/tempout echo "${e[@]}" echo "${e[0]}" echo "${e[1]}" echo "${e[2]}" 

输出:

 hi first second third first second third 

我有一个类似的问题,当我想自动删除我创build的临时文件。 我提出的解决scheme不是使用命令replace,而是将variables名称(应该将最终结果)传递给函数。 例如

 #! /bin/bash remove_later="" new_tmp_file() { file=$(mktemp) remove_later="$remove_later $file" eval $1=$file } remove_tmp_files() { rm $remove_later } trap remove_tmp_files EXIT new_tmp_file tmpfile1 new_tmp_file tmpfile2 

所以,在你的情况下,将是:

 #!/bin/bash e=2 function test1() { e=4 eval $1="hello" } test1 ret echo "$ret" echo "$e" 

工作并没有“返回值”的限制。

这是因为命令replace是在一个子shell中执行的,所以当子shellinheritance这些variables时,当子shell结束时,它们的变化将会丢失。

参考 :

命令replace ,用圆括号分组的命令以及asynchronous命令在shell环境的副本环境中调用

您始终可以使用别名:

 alias next='printf "blah_%02d" $count;count=$((count+1))'