是否可以在用户空间中将环境变量从子级传递到父级?

是否可以在用户空间中将环境变量从子级传递到父级?

正如标题所示,我希望能够从子进程(通常是脚本)更改父进程(特别是 shell)中的环境变量。从伪终端/dev/pts/id尝试key=value从子脚本导出,因此导出的变量必须以某种方式传递给父级(如果可能的话)?

echoingcmd > /proc/$$/fd/0不执行cmd,仅在 shell 终端模拟器中查看命令,当然使用$(cmd)而不是cmd在子 shell 中执行,并且export不向父进程添加变量。

  1. 我更喜欢所有的工作都在子端完成。

  2. 有人在评论中问我,我想实现什么目标?这是一个一般性问题,我试图使用肯定的答案来传递由(父)shell 执行(生成)的脚本中的变量,以便用户可以从添加的变量中受益,而无需任何进一步的工作。例如,我想让一个脚本安装一个应用程序,并且应用程序目录应该添加到父shell路径中。

答案1

, 这是不可能的

并非没有某种解决方法

环境变量只能从父级传递到子级(作为环境导出/继承的一部分),而不是相反。

答案2

您可以通过文件或命名管道将变量值从子进程传输到其父进程。

这是一个理论上最简单的例子:

子进程:

echo ${variable} >/tmp/file

父进程:

read variable </tmp/file

答案3

如果父进程不期待并与它合作,这将非常棘手。在这种情况下,请参阅改变正在运行的进程的环境有没有办法改变另一个进程的环境变量?

如果父进程需要该值并配合传输,简单的方法是使用命令替换:

出口VAR=$(指令

这假设变量的值为仅有的程序想要写的东西。如果子进程需要能够写入屏幕(特别是父进程的标准输出),我们可以通过将父进程的文件描述符 1 隐藏在另一个文件描述符中来实现:

exec 3>&1       # Copy our file descriptor 1 into file descriptor 3.
                # child_prog will be invoked with file descriptor 1 pointing to a pipe
                # for the command substitution, but all other file descriptors intact.
                # Specifically, fd3 will point to our stdout.
export var=$(child_prog)
exec 3>&-       # (Optionally) close fd3 as cleanup.

现在,如果child_prog简短且简单,那么最简单的方法可能是将变量的值写入文件描述符 1 并使用文件描述符 3 ( cmd >&3) 作为标准输出。如果它很大和/或很复杂,您会想要执行以下操作:

exec 5>&1       # Redirect fd1 (the command substitution pipe) to fd5.
exec 1>&3       # Set our fd1 (stdout) to our parent's stdout (which was passed in as fd3).
exec 3>&-       # Close fd3; it’s no longer needed.

然后正常使用stdout,并用于>&5写入值。

到目前为止,我一直假设您只想将一个值传递给一个变量。如果您有多个值,则只需使用保证不会出现在任何值中的字符(或字符串)来分隔它们即可。如果我们选择@@,那么家长可以说

exec 3>&1
temp=$(child_prog)
exec 3>&-
export var1="${temp%%@@*}"
rest="${temp#*@@}"
export var2="${rest%%@@*}"
export var3="${rest#*@@}"

而且孩子可以说 。echo "value1@@value2@@value3" >&5

如果很难找到保证不会出现在任何值中的打印字符字符串,则可以使用换行符。只需将@@上述命令中更改为换行符即可:

家长:

export var1="${temp%%
*}"
rest="${temp#*
}"
export var2="${rest%%
*}"
export var3="${rest#*
}"

孩子:

printf "%s\n" "值1” “值2” “值3>&5


另一种变化是让孩子喂食命令 回到父母,而不是价值观。如果父进程说. <(child_prog),它会运行子进程,捕获输出,并执行它。然后孩子就可以做

printf "导出 var1='值1'\n导出 var2='值2' var3=\"值3\"\n" >&5

(我用一个测试了这个value3包含一个撇号,所以我必须用 引用它\"…\",并且我这样保留它只是为了说明替代语法。)

该技术的一个特点是您可以添加要导出的变量,而无需更改父级中的代码。

这种方法要求父进程运行 bash(或者可能是其他高级 shell 之一?),因为 POSIX 不支持.<(cmd)

相关内容