Emm*_*uel 29 shell bash pipe read
使用 ksh 我使用 read 作为分隔值的便捷方法:
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
2 1
$
Run Code Online (Sandbox Code Playgroud)
但它在 Bash 中失败了:
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
$
Run Code Online (Sandbox Code Playgroud)
我没有在手册页中找到失败的原因,知道吗?
Mic*_*mer 39
bash 在子shell上下文中运行管道的右侧,因此read不会保留对变量的更改(这是什么) - 当子shell执行时,它们会在命令结束时消失。
相反,您可以使用进程替换:
$ read a b dump < <(echo 1 2 3 4 5)
$ echo $b $a
2 1
Run Code Online (Sandbox Code Playgroud)
在这种情况下,read在我们的主 shell 中运行,我们的输出生成命令在子 shell 中运行。该<(...)语法创建了一个子外壳并将其输出连接到管道,我们read使用普通<操作将其重定向到输入。因为read在我们的主 shell 中运行,变量设置正确。
正如评论中指出的那样,如果您的目标是以某种方式将字符串拆分为变量,则可以使用此处的字符串:
read a b dump <<<"1 2 3 4 5"
Run Code Online (Sandbox Code Playgroud)
我认为还有更多的东西,但如果没有,这是一个更好的选择。
jll*_*gre 22
这不是一个bash错误,因为POSIX允许bash和ksh行为,导致您观察到的不幸差异。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_12
另外,多命令管道的每个命令都在一个子shell环境中;然而,作为扩展,管道中的任何或所有命令都可以在当前环境中执行。所有其他命令都应在当前 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
Run Code Online (Sandbox Code Playgroud)
输出:
before:
after: 2 1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10951 次 |
| 最近记录: |