Answers:
bash
在子外壳程序上下文中运行管道的右侧,因此read
不会保留对变量的更改(变量所做的更改),这些更改将在命令末尾在子外壳程序执行时死亡。
相反,您可以使用流程替换:
$ read a b dump < <(echo 1 2 3 4 5)
$ echo $b $a
2 1
在这种情况下,read
它在我们的主shell中运行,而我们的output-production命令在子shell中运行。该<(...)
语法创建了一个子外壳,并将其输出连接到管道,我们read
通过普通<
操作将其重定向到输入。因为read
在我们的主外壳中运行,所以变量设置正确。
如评论中所指出,如果您的目标是从字面上将字符串以某种方式拆分为变量,则可以使用here字符串:
read a b dump <<<"1 2 3 4 5"
我认为还有更多,但如果没有,这是一个更好的选择。
read a b dump <<< '1 2 3 4 5'
。
cat /etc/passwd | (read -r line ; echo $line)
。但接下来echo
的$line
这是不是在屏幕上的管道放什么,因为价值只是括号之间(子shell)存在。希望,它可以帮助某人。
这不是一个bash
问题,问题POSIX
同时允许bash
和ksh
行为,从而导致不幸的差异所观察。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_12
另外,多命令管道中的每个命令都在子shell环境中。但是,作为扩展,流水线中的任何或所有命令都可以在当前环境中执行。所有其他命令应在当前的外壳环境中执行。
但是,对于bash 4.2
更新的版本,您可以lastpipe
在非交互式脚本中设置该选项以获得预期的结果,例如:
#!/bin/bash
echo 1 2 3 4 5 | read a b dump
echo before: $b $a
shopt -s lastpipe
echo 1 2 3 4 5 | read a b dump
echo after: $b $a
输出:
before:
after: 2 1
lastpipe
在于它不能在其他shell中工作(例如破折号)。除了运行该子外壳中的所有内容外,基本上没有任何方法可以进行此便携式移植,请参见stackoverflow.com/questions/36268479/…–