在 tee 进程替换子 shell 中导出全局变量

在 tee 进程替换子 shell 中导出全局变量
command | tee >(var="$(command1)") >(var1="$(command2)")
echo "$var $var1"

还尝试了 moreutils 小便

command | pee 'var="$(command)"' 'var1="$(command2)"' 

还尝试了导出命令 | tee >(导出 var="$(command1)") >(var1="$(command2)")

问题1 我的需要是使用一个命令输出并由多个命令使用它作为输入。

问题2

function() { Array=("$1"); }
function String

以上作品

command | parallel -I %% function %%

上面不工作的数组未设置是否有任何解决方法。请帮忙。

命令输出:

1 word
2 word
3 word
4 word
1 string
2 string
3 string
4 string

我如何设置两个关联数组,一个与单词,另一个与管道输出中的字符串?数组1[1]=字 数组1[2]=字

数组2[1]=字符串 数组2[2]=字符串

答案1

就像@他们所说,进程替换在子 shell 中运行,因此主 shell 不可见那里的分配。pee和 也是如此parallel,虽然至少后者可以使用导出函数,但它仍然启动一个不同的 shell 在其中运行代码。

您还可以使用临时文件结果作为一种解决方法,如果输入数据比结果长,这可能是值得的。例如:

seq 10 | tee >(wc -l > lines) >(wc -c > chars) > /dev/null
lines=$(< lines)
chars=$(< chars)

或者也许与

tmp1=$(mktemp)
tmp2=$(mktemp)
seq 10 | tee >(wc -l > "$tmp1") >(wc -c > "$tmp2") > /dev/null
lines=$(< "$tmp1")
chars=$(< "$tmp2")
rm -f "$tmp1" "$tmp2"

答案2

我假设您打算设置变量的值,以便它们在所示代码的最外壳中可见。

在您展示的所有示例中,变量赋值和export执行都是在子 shell(或子进程)中执行的。在子 shell 中,变量被设置并可以照常使用。但是,当子 shell 终止时,变量就会丢失,无论它是 shell 变量还是环境变量(“导出的 shell 变量”)。子 shell 永远无法影响其父 shell 的环境。

您可以在此处使用临时文件:

some-command >tmpfile

var1=$(other-command1 <tmpfile)
var2=$(other-command2 <tmpfile)

rm -f tmpfile

或者,如果some-command是微不足道的(仅使用 shell 内置实用程序、最少的资源,并且不会产生大量的输出):

var1=$( some-command | other-command1 )
var2=$( some-command | other-command2 )

将换行符分隔的数据读入数组(如果这是您想要做的)是使用readarrayin完成的bash

readarray -t array < <( some-command )

some-command然而,如果命令产生大量输出,这可能不是您想要做的。在这种情况下,您更有可能希望使用awkPython 或其他某种语言来处理管道中的数据。

答案3

parset您正在寻找--pipe --tee

mkfifo myfifo
command > myfifo &
env_parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

例子:

command() { seq 10000; }
command1() { wc -l; }
command2() { wc -c; }
mkfifo myfifo
command > myfifo &
env_parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

如果command1command2被导出,您可以使用parset

export -f command1 command2
mkfifo myfifo
command > myfifo &
parset var,var1 --pipe --tee ::: command1 command2 < myfifo
echo "$var $var1"

如果您的command1command2是具有不同选项的相同命令:

command > myfifo &
parset var,var1 --pipe --tee wc {} ::: -c -l < myfifo
echo "$var $var1"

如果您想要数组中的输出:

command > myfifo &
parset arr --pipe --tee wc {} ::: -c -l < myfifo
echo "${arr[0]} ${arr[1]} ${arr[2]}"

如果您想要关联数组中的输出:

typeset -A myassoc
command > myfifo &
parset myassoc --pipe --tee wc {} ::: -c -l < myfifo
echo "${myassoc[-c]} ${myassoc[-l]}"

正如其他人指出的那样:您不能使用|管道将数据传输到parset/中,parallel因为这会在子 shell 中生成parset/ 。parallel这就是为什么你需要 fifo 技巧。

如果您的 shell 允许,您还可以:

typeset -A myassoc
parset myassoc --pipe --tee wc {} ::: -c -l < <(command)
echo "${myassoc[-c]} ${myassoc[-l]}"

欲了解更多详情,请参阅: https://www.gnu.org/software/parallel/parset.html

相关内容