一行代码中将相同的环境变量传递给两个进程

3
有没有办法在bash中一行命令中向两个进程传递环境变量?我想在同一行命令中执行两个进程。
# these are ways to execute two processes in the same line
exec1 & exec2
exec1 && exec2
exec1 || exec2
exec1; exec2

这是将环境变量传递给进程的方法:
VAR=value exec

如何将它们结合起来?
# this is not enough because exec2 does not see VAR
VAR=value exec1 & exec2

我知道使用 export 的方法:

export VAR=value; exec1 & exec2; unset EXPORT

有没有不需要导出的另一种方法?

1
除非您将这两个命令封装在一个函数中,否则前置命令环境更改仅适用于简单命令。 - chepner
1
另外,请注意您的解决方法并不等同;如果 VAR 之前有值,那么现在它已经没有了。 - chepner
2个回答

2

是的,你可以这样做:将导出范围限定在子shell中。(如果你从子shell中exec一个进程,那么在到达该行的分支中不会出现效率损失,因为用于生成子shell的fork与否则将运行子进程的fork是相同的)。因此:

(export VAR=value; exec1 & exec exec2)
(export VAR=value; exec1 && exec exec2)
(export VAR=value; exec1 || exec exec2)
(export VAR=value; exec1; exec exec2)

显然,如果您的任一命令不是外部命令而是shell内置命令,则这将产生不良副作用。


然而,我的建议是? 不要这样做。这会使您的代码变得更加晦涩难懂,而收益却非常微小。在这种情况下,重复自己并不是世界末日。


@Mr.Llama,这在“如果您的任一命令实际上不是外部命令,则会产生不希望的副作用”警告中已经涵盖了;毕竟,exit是内置命令。 - Charles Duffy
@Mr.Llama,关于返回代码,子进程以其运行的最后一个命令的退出状态退出--当使用exec时,当然,命令的退出状态会直接传递;唯一可能会有问题的情况是组件被放在后台。 - Charles Duffy
@CharlesDuffy 在我的情况下,我想在我的.bashrc中为一个我经常需要重复且比较复杂的命令创建一个alias。如果我要在脚本中使用它,将其拆分成更多行代码的解决方案将是微不足道的。 - Gabriel Petrovay
使用shell函数比别名更好的实践,因为它们更加强大,可以根据参数实际执行条件逻辑,并且还可以防止您担心代码长度问题。 - Charles Duffy
@GabrielPetrovay,如果你愿意在这里展示你的别名,我很乐意演示如何将其重写为函数。 - Charles Duffy
显示剩余4条评论

0

这可能会变得很混乱,因为引用的地狱:将要调用的命令分组到子shell中

VAR=value sh -c 'exec1 & exec2'

这种方法的效率显然比使用子shell方法要低得多,因为它会 exec 一个新的shell实例 - 但这样做有什么意义呢?(此外,这意味着在形成命令时无法访问任何未导出的变量,除非将它们扩展为代码并因此引入与 eval 等价的安全风险)。 - Charles Duffy
1
我认为“significant”(生成 sh 的真实成本)是有争议的。不过,这个答案与你的答案并没有太大的区别。 - glenn jackman
如果您在内部循环中执行此操作,则生成 sh 的成本会非常快地累积。 (再说一遍,在那里也应该避免使用 forks - 并且使用外部命令)。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接