如何设置在父shell变量,从一个子shell?
a=3
(a=4)
echo $a
如何设置在父shell变量,从一个子shell?
a=3
(a=4)
echo $a
子shell的全部意义在于,它不影响通话会话。 在bash子shell是一个子进程,其他炮弹不同,但即使如此,在子shell变量设置不影响调用者。 根据定义。
你需要一个子shell? 如果你只需要一个组,然后使用大括号:
a=3
{ a=4;}
echo $a
给出4
(是一个谨慎的空间)。 或者,写变量值stdout和捕捉它的调用者:
a=3
a=$(a=4;echo $a)
echo $a
避免使用反单引号``,他们已被取消,可能难以阅读。
还有就是GDB-bash的变量黑客:
gdb --batch-silent -ex "attach $$" -ex 'set bind_variable("a", "4", 0)';
虽然始终将在全球范围内的变量,而不仅仅是父范围
你不知道。 子shell没有获得其父的环境。 (至少Bash提供抽象之内,你可能会尝试使用gdb
,或者破坏堆栈,或诸如此类的东西,偷偷获取这种访问。我不会建议,虽然)。
一种选择是在子shell写赋值语句到一个临时文件其父阅读:
a=3
(echo 'a=4' > tmp)
. tmp
rm tmp
echo "$a"
如果问题涉及到一个while循环,解决这个问题的一种方法是通过使用过程换人:
var=0
while read i;
do
# perform computations on $i
((var++))
done < <(find . -type f -name "*.bin" -maxdepth 1)
如下所示: https://stackoverflow.com/a/13727116/2547445
要改变的变量在从父脚本调用脚本,你可以调用前面有一个“”剧本
a=3
echo $a
. ./calledScript.sh
echo $a
在calledScript.sh
a=4
预计输出
3
4
您可以输出在子shell和值分配的子shell输出到呼叫者脚本变量:
# subshell.sh
echo Value
# caller
myvar=$(subshell.sh)
如果子shell有更多的输出,你可以将其重定向到不同的输出流分离的变量值和其他消息:
# subshell.sh
echo "Writing value" 1>&2
echo Value
# caller
myvar=$(subshell.sh 2>/dev/null) # or to somewhere else
echo $myvar
或者,您可以输出变量赋值在子shell,评估他们在调用者脚本,并避免使用文件交换信息:
# subshell.sh
echo "a=4"
# caller
# export $(subshell.sh) would be more secure, since export accepts name=value only.
eval $(subshell.sh)
echo $a
我能想到的最后一个方法是使用退出代码,但这仅涵盖整数值交换(在有限的范围内),并打破了惯例解释退出代码(0为一切成功非0)。
除非你能适用所有的IO管道和使用的文件句柄,基本变量更新内$(命令)和任何其他子进程是不可能的。
常规文件,然而,是bash的正常顺序处理全局变量。 注:由于比赛条件下,这种简单的方法是不适合并行处理。
创建一个集/获取/默认功能是这样的:
globalVariable() { # NEW-VALUE
# set/get/default globalVariable
if [ 0 = "$#" ]; then
# new value not given -- echo the value
[ -e "$aRam/globalVariable" ] \
&& cat "$aRam/globalVariable" \
|| printf "default-value-here"
else
# new value given -- set the value
printf "%s" "$1" > "$aRam/globalVariable"
fi
}
“$亚兰”就是值存储的目录。 我喜欢它是速度和波动性RAM盘:
aRam="$(mktemp -td $(basename "$0").XXX)" # temporary directory
mount -t tmpfs ramdisk "$aRam" # mount the ram disk there
trap "umount "$aRam" && rm -rf "$aRam"" EXIT # auto-eject
要读取值:
v="$(globalVariable)" # or part of any command
要设置值:
globalVariable newValue # newValue will be written to file
要取消值:
rm -f "$aRam/globalVariable"
对于接入功能的唯一的真正原因是为了应用默认值,因为猫会给出错误不存在的文件。 这也是有用的应用其他的get / set逻辑。 否则,它不会在所有需要。
一个丑陋的读取方法避免猫的不存在的文件的错误:
v="$(cat "$aRam/globalVariable 2>/dev/null")"
这种混乱的一个很酷的功能是,你可以打开另一个终端和检查程序运行时,该文件的内容。