我知道我可以通过导出变量来读取子进程中的父进程的信息
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 sleep
(echo $!
)。当你暂停内壳时,你可以读取进程sleep
的其父级给出的环境变量从外部来看 - 这些在/proc
文件系统中是公开的 - 但它们被空字节分隔开,因此xargs -0
将它们分开,printf '%s\n'
每行输出一个。此时,有一个完整的变量列表,我们可以取出我们想要的变量,可以选择只取出withgrep
后面的值并设置它。会自行结束,这就是我们在转录本末尾看到的内容()。=
cut
sleep
[1]+ Done ...
a
如果您想在子进程中获取更改,则需要重新执行所有操作- 并且子进程永远不会看到您a
在父进程中所做的更改:我们所做的只是制作另一个副本。进程的原因sleep
是我们只能看到进程的入站环境变量,而看不到任何 shell 的内部变量值即使出口。
我不建议这样做或依赖它,而且我看不出使用它的任何价值,但如果你最终处于真正、至关重要的必要的情况,那么它应该会起作用。
答案2
从Stack Overflow 上的这个问题source
解决方案是在执行子进程时使用:
在a.sh
做source b.sh
而不是./b.sh
a.sh
看起来应该像这样:
#!/bin/bash
export A=1
source b.sh
echo parent "$A"