将修改环境的命令的输出保存到变量中

far*_*mir 8 bash environment-variables output

如何将修改环境的命令的输出保存为变量?

我正在使用 bash shell。

假设我有:

function f () { a=3; b=4 ; echo "`date`: $a $b"; }
Run Code Online (Sandbox Code Playgroud)

现在,我可以使用命令来运行f

$ a=0; b=0; f; echo $a; echo $b; echo $c
Sat Jun 28 21:27:08 CEST 2014: 3 4
3
4
Run Code Online (Sandbox Code Playgroud)

但我想将输出保存f到变量c,所以我尝试:

a=0; b=0; c=""; c=$(f); echo $a; echo $b; echo $c
Run Code Online (Sandbox Code Playgroud)

但不幸的是,我有:

0
0
Sat Jun 28 21:28:03 CEST 2014: 3 4
Run Code Online (Sandbox Code Playgroud)

所以我这里没有任何环境变化。

如何将命令(不仅仅是函数)的输出保存到变量并保存环境更改?

我知道这会$(...)打开新的子外壳,这就是问题所在,但是否可以做一些解决方法?

Mic*_*mer 2

如果您使用的是 Bash 4 或更高版本,则可以使用coprocesses

\n\n
function f () { a=3; b=4 ; echo "`date`: $a $b"; }\ncoproc cat\nf >&${COPROC[1]}\nexec {COPROC[1]}>&-\nread c <&${COPROC[0]}\necho a $a\necho b $b\necho c $c\n
Run Code Online (Sandbox Code Playgroud)\n\n

将输出\n

\n\n
function f () { a=3; b=4 ; echo "`date`: $a $b"; }\ncoproc cat\nf >&${COPROC[1]}\nexec {COPROC[1]}>&-\nread c <&${COPROC[0]}\necho a $a\necho b $b\necho c $c\n
Run Code Online (Sandbox Code Playgroud)\n\n

coproc创建一个运行给定命令的新进程(此处为cat)。它将 PID 保存到数组中COPROC_PID,并将标准输出/输入文件描述符保存到数组中COPROC(就像pipe(2), 或\xc2\xa0 参见此处此处)。

\n\n

在这里,我们运行该函数,其标准输出指向我们的协进程 running cat,然后从中read运行。由于cat只是将其输入吐出,因此我们将函数的输出放入变量中。exec {COPROC[1]}>&-只是关闭文件描述符,这样就cat不会永远等待。\n

\n\n
\n\n

请注意,read一次只需要一行。您可以使用它mapfile来获取行数组,或者仅使用文件描述符,但您想以不同的方式使用它。

\n\n

exec {COPROC[1]}>&-适用于当前版本的 Bash,但早期的 4 系列版本要求您首先将文件描述符保存到一个简单的变量中:fd=${COPROC[1]}; exec {fd}>&-. 如果您的变量未设置,它将关闭标准输出。

\n\n
\n\n

如果您使用的是 3 系列版本的 Bash,则可以使用以下命令获得相同的效果mkfifo,但此时它并不比使用实际文件好多少。

\n