从父进程获取子进程运行结果

从父进程获取子进程运行结果

我知道我可以通过导出变量来读取子进程中的父进程的信息

myVariable=1
bash
echo $myVariable

exit
export myVariable=1
bash
echo $myVariable # 1

如何从父进程访问子进程中定义的变量?

bash
a=2
suspend
echo $a

答案1

你不能这么做。

当你启动一个新 shell 时,它是一个不相关的进程,父进程无法“查看”它以查看其内存中的内容(这是一种安全边界)。它的变量不会被共享,也不会发布到其他人可以看到的地方。

它获取现有环境变量的副本,但对它们所做的任何更改都只针对其自身及其子进程。在 shell 退出之前,不存在“向后”通信,此时只有一个退出代码。

当你这样做的时候互动地正如您所展示的,这就是故事的结局。最好的办法是将数据保存到文件中,然后您可以从中读取数据或source将其返回到父级。如果您真的不能使用文件,我最后有一个糟糕的方法可以做到这一点,但我建议您重新考虑您想要实现的目标 - 能够使其正常工作会很好(并且其他一些 shell 确实有共享变量!),但在这里无法实现。

source如果你正在编写一个非交互运行的程序或 shell 脚本,那么、和将数据打印到标准输出中的部分或全部eval可能会对你有所帮助,如现有的答案。如果退出子 shell,则可以用 在退出代码中传回一个字节的信息,然后在父级中exit 123读取该信息。$?


如果你确实需要迁移某些内容,这里有一个非常讨厌的破解方法,可以以交互方式实现它,而无需中间文件:

$ bash
$ export a=2
$ sleep 60 & echo $!
2198
$ suspend
$ xargs -0 < /proc/2198/environ printf '%s\n' | grep '^a='
a=2
$ a=$(xargs -0 < /proc/2198/environ printf '%s\n' | grep '^a=' | cut -d= -f2-)
$ echo $a
2
$ [1]+  Done                    sleep 60

这里存在很大的局限性,特别是如果您无法控制整个环境 - 例如,环境变量值中的换行符可能会诱骗您设置您不想要的值。

它的工作原理是导出a它,使其出现在子进程的环境中,然后sleep 60在后台启动一个(此处)(&),并打印出 PID sleepecho $!)。当你暂停内壳时,你可以读取进程sleep其父级给出的环境变量从外部来看 - 这些在/proc文件系统中是公开的 - 但它们被空字节分隔开,因此xargs -0将它们分开,printf '%s\n'每行输出一个。此时,有一个完整的变量列表,我们可以取出我们想要的变量,可以选择只取出withgrep后面的值并设置它。会自行结束,这就是我们在转录本末尾看到的内容()。=cutsleep[1]+ Done ...

a如果您想在子进程中获取更改,则需要重新执行所有操作- 并且子进程永远不会看到您a在父进程中所做的更改:我们所做的只是制作另一个副本。进程的原因sleep是我们只能看到进程的入站环境变量,而看不到任何 shell 的内部变量值即使出口

我不建议这样做或依赖它,而且我看不出使用它的任何价值,但如果你最终处于真正、至关重要的必要的情况,那么它应该会起作用。

答案2

Stack Overflow 上的这个问题source解决方案是在执行子进程时使用:

a.shsource b.sh而不是./b.sh


a.sh看起来应该像这样:

#!/bin/bash
export A=1
source b.sh
echo parent "$A"

相关内容