如何修改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))'