从子shell中设置的父shell的变量(Set a parent shell's vari

2019-07-22 07:03发布

如何设置在父shell变量,从一个子shell?

a=3
(a=4)
echo $a

Answer 1:

子shell的全部意义在于,它影响通话会话。 在bash子shell是一个子进程,其他炮弹不同,但即使如此,在子shell变量设置不影响调用者。 根据定义。

你需要一个子shell? 如果你只需要一个组,然后使用大括号:

a=3
{ a=4;}
echo $a

给出4 (是一个谨慎的空间)。 或者,写变量值stdout和捕捉它的调用者:

a=3
a=$(a=4;echo $a)
echo $a

避免使用反单引号``,他们已被取消,可能难以阅读。



Answer 2:

还有就是GDB-bash的变量黑客:

gdb --batch-silent -ex "attach $$" -ex 'set bind_variable("a", "4", 0)'; 

虽然始终将在全球范围内的变量,而不仅仅是父范围



Answer 3:

你不知道。 子shell没有获得其父的环境。 (至少Bash提供抽象之内,你可能会尝试使用gdb ,或者破坏堆栈,或诸如此类的东西,偷偷获取这种访问。我不会建议,虽然)。

一种选择是在子shell写赋值语句到一个临时文件其父阅读:

a=3
(echo 'a=4' > tmp)
. tmp
rm tmp
echo "$a"


Answer 4:

如果问题涉及到一个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



Answer 5:

要改变的变量在从父脚本调用脚本,你可以调用前面有一个“”剧本

a=3
echo $a    
. ./calledScript.sh
echo $a

在calledScript.sh

a=4

预计输出

3
4


Answer 6:

您可以输出在子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)。



Answer 7:

除非你能适用所有的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")"

这种混乱的一个很酷的功能是,你可以打开另一个终端和检查程序运行时,该文件的内容。



文章来源: Set a parent shell's variable from a subshell