我正在尝试找出一种方法,从脚本 A 运行 shell 脚本 B,在脚本 B 中设置或导出变量,并能够在脚本 B 完成并且其子 shell 返回后将该值存储在脚本 A 中。
我不是想获取脚本 B 的源代码。我只想要 1 个特定变量。我可以向脚本 A 添加内容,但我不希望脚本 B 中可能设置的任何变量覆盖脚本 A 中除我特别想要捕获的内容之外的任何内容。
我确信有一些丑陋的方法,比如将我关心的 A 中的所有变量写入文件,源脚本 B,然后从文件中读回所有内容并恢复 A 中的变量,除了我想要的 B 中的变量集。我正在寻找一种相对干净和直接的方法,如果存在的话。
答案1
其他答案很好,它应该是你的首选,特别是如果你的 B 脚本只做一件事,而且做得很好(见Unix 哲学),这个“一件事”的意思是“计算这个特定的变量值”。
但是,如果 B 的主要目的是打印其他内容,或者甚至与用户交互,该怎么办?传递额外的通过 stdout 传输数据需要对检索到的结果进行额外的解析。如果是这样,B 和 A 之间非常需要完全独立的通信渠道。对于你的情况,单向通信就足够了。
临时文件实际上非常适合。但是当你说
丑陋的方式,比如把我关心的 A 中的所有变量都写到一个文件,源脚本 B,然后从文件中读回所有内容并恢复 A 中的变量,除了我想要的 B 中的变量集
你把情况搞得一团糟,这确实很糟糕。正确的方法是使用文件仅传递这一个所需的变量。
在一个:
tmpf_foo=$(mktemp)
然后你用"$tmpf_foo"
命令行参数调用 B,并在"$1"
B 中引用该文件(或者根据设计使用其他数字)。如果 B 已经解析了它的命令行参数,这可能不太方便。
另一种方法是在 A 中并像在 B 中export tmpf_foo
一样引用该文件。"$tmpf_foo"
如果 B 是一个通用工具,不仅可以在 A 内部使用,那么在写入文件之前,最好先在 B 中检查该文件是否存在(例如if [ -f "$tmpf_foo" ]; then …
)。
无论如何,在 B 中,您将所需的值写入文件。例如,文件内容将是:
12345
B 成功完成后,您可以在 A 中像这样检索值:
specificvariable=$(<"$tmpf_foo")
(相当于specificvariable=$(cat "$tmpf_foo")
但没有cat
;但不可移植)。
如果需要将多个变量从 B 传递到 A,则可以使用多行并使用 读取它们(在 A 中)read
。但如果您事先不知道应该更改哪些变量(或者根本不应该更改),则让 B 在文件中创建行,使其看起来像这样:
specificvariable=12345
othervariable="xyz 0"
bar=baz
unset var1
B 成功完成后,在 A 中获取文件:
. "$tmpf_foo"
注意您可以通过任何命令以这种方式(在上面的例子中unset
是一个命令)并且它将从 A 内部执行。因此,您在从 B 内部写入文件时应非常小心,并且应确保没有其他(恶意)进程可以将字符串注入文件。
最后(在 A 中)使用 删除临时文件rm "$tmpf_foo"
。
答案2
将该特定变量写入标准输出,然后在 A 中:
specificvariable=$(/path/to/B.sh)