通过Bash逻辑在当前shell中运行管道

Mar*_*obe 0 bash shell ksh

在我的Korn shell时代,我可以做以下事情:

#!/bin/ksh

(
    echo a=1
    echo b=2
) |
    while read line
    do
        name=${line%%=*}
        val=${line#*=}
        eval "$name=$val"
        eval "echo $name=\$$name"
    done
echo a=$a
echo b=$b
Run Code Online (Sandbox Code Playgroud)

输出:

a=1
b=2
a=1
b=2
Run Code Online (Sandbox Code Playgroud)

意味着while循环在前台shell中运行.

但是当你在bash中运行它时,你得到:

a=1
b=2
a=
b=
Run Code Online (Sandbox Code Playgroud)

这意味着它在子shell中运行.

我知道其他机制可以获得我想要的特定用法,但是,有没有办法让bash像ksh一样在前台运行它?

che*_*ner 5

bash4.2介绍了该lastpipe选项,其中(给出了一些基本上适用于非交互式shell的条件)允许管道中的最后一个命令在当前shell中运行.

shopt -s lastpipe
x=foo
echo bar | read x
echo "$x"   # outputs bar, not foo
Run Code Online (Sandbox Code Playgroud)

在早期版本中,您仅限于诸如进程替换之类的解决方法

while read line; do
...
done < <(echo a=1; echo b=2)
Run Code Online (Sandbox Code Playgroud)

和命名管道

mkfifo p
(echo a=1; echo b=2) > p &
while read line; do
...
done < p
Run Code Online (Sandbox Code Playgroud)

而且,只是为了解决eval这里的用法:

shopt -s lastpipe
( echo a=1; echo b=2 ) |
   while IFS== read -r name value; do
       IFS= read -r "$name" <<< "$value"
   done
Run Code Online (Sandbox Code Playgroud)