David C. Rankin's helpful answer 解释了为什么您的代码不起作用。
注意:
仅当无法修改您使用的脚本时才应使用以下解决方案(如果您想了解采购和临时环境变量,该解决方案也可能很有趣)。
否则,请参阅底部讨论的解决方案。
要解决您的问题,您可以尝试以下方法:
x=$(trap 'printf %s "$x"' EXIT; . script1.sh >/dev/null) sh script2.sh
但请注意:
-
script1.sh 将 - 必然 - 由你的 current shell 执行,它可能是也可能不是 sh。
-
script1.sh 的 stdout 输出被抑制,因为必须确保 printf %s "$x" 是命令替换 ($(...)) 内的子 shell 生成的唯一 stdout 输出。
- 这种方法仅限于单个变量(尽管它可以扩展为输出多个变量的值,然后调用脚本必须将其解析回单个值)。
. script1.sh sources 子shell里面的脚本,这意味着子shell直接在自己的环境中执行script1.sh,因此在执行之后会看到脚本的变量(这意味着它会看到@ 987654331@ 即使它没有导出)。
trap 'printf %s "$x"' EXIT设置出口陷阱;即子shell退出时执行的代码,在本例中为printf %s "$x",它只是输出感兴趣的变量的值。
请注意,即使script1.sh 因exit 语句而终止,这种方法对于确保打印$x 的值是必要的;由于script1.sh 由子shell获取,exit 退出整个子shell。
x=$(...) 捕获该值,并通过 预先添加 到命令 sh script2.sh,有效地使生成的 $x 成为 script2.sh 然后的 环境 变量看到了。
通常获取并非设计为可获取的脚本是有问题的:
-
所有由脚本修改或创建的变量以及脚本对 shell 环境所做的任何更改都会影响调用 shell。
- 如果此类脚本执行
exit,它们也会退出调用shell。
如果涉及的脚本由于某种原因无法修改,上面的解决方案是最好的选择,因为它绕过了这些问题,尽管有一些限制。
更强大的通用解决方案(需要修改脚本):
让设置感兴趣的环境变量的脚本自身调用另一个脚本是正确的解决方案,如David's answer 所示。
如果脚本确实需要作为 peers 运行,则需要通过 files 传递值:让设置感兴趣变量的脚本将它们的值写入一个(临时)文件并让其他脚本读取该文件:
script1.sh:
#!/bin/sh
export x=19
# Write to temp. file named for the *parent* process ID.
# Since both script calls will have the same parent process, this
# allows you to avoid a static filename subject to name collisions.
printf %s "$x" > /tmp/x.$PPID
script2.sh:
#!/bin/sh
# Read the value of $x from the temp. file, then delete the file.
x=$(cat /tmp/x.$PPID) && rm /tmp/x.$PPID
echo "x=${x}"