如何设置影响整个复合命令的一次性变量?
例如,类似:
FOO=1 ./foo.sh && ./foo.sh
其中foo.sh
containsecho "FOO=$FOO"
将打印:
FOO=1
FOO=
我希望FOO
为整个管道设置 的值(但我不想在当前的 shell 中设置或导出它)。子外壳的工作原理:
( export FOO=1; ./foo.sh && ./foo.sh )
...但是有没有一种没有子shell的方法?
答案1
子 shell 方法是输入较少的方法:
(
export FOO="value"
./foo.sh && ./foo.sh
)
另一种方法是启动一个子 shell 并为该 shell 设置环境变量:
FOO="value" sh -c './foo.sh && ./foo.sh'
其他变体是为脚本的每次调用显式设置变量,如下所示
FOO="value" ./foo.sh &&
FOO="value" ./foo.sh
这可以稍微方便一些
foo=( env FOO="value" ./foo.sh )
"${foo[@]}" && "${foo[@]}"
或者,与/bin/sh
,
set -- env FOO="value" ./foo.sh
"$@" && "$@"
或者您可以在调用脚本中设置它,然后在完成后取消设置,如下所示
export FOO="value"
./foo.sh && ./foo.sh
unset FOO
答案2
你所要求的是如果不进行任何黑客攻击就无法实现的事情。原因是当你运行脚本时
FOO=1 ./foo.sh && ./foo.sh
您基本上启动了两个单独的 shell 实例,它们继承了您启动它的父 shell 的所有特征(变量)。如果您$$
在 中打印变量,foo.sh
您将注意到每个启动的脚本都有单独的 proc-id。
现在FOO=1
,第一部分仅影响第一个进程启动的环境。变量是不是甚至可以在父 shell 上启动,但仅限于第一个进程的范围。有不该变量集可以反映在完全在单独的用户空间上运行的第二个进程的环境中。
第二个进程无法在其环境中看到此值,除非该值是从其父级继承的(当从 shell 显式导出该变量时,管道将运行)或者该值再次在本地传递到第二个脚本。