Lee*_*ton 5 bash built-in io-redirection
我有一个脚本,我要从中返回多个值,每个值都在一个新行上。为了将这些值捕获为 bash 变量,我使用了read内置函数(如这里推荐的那样)。
问题是,当我使用换行符作为 的分隔符时read,我似乎总是得到一个非零的退出代码。这对我检查操作结果的其余脚本造成了严重破坏。
这是我正在做的事情的简化版本:
$ read -d '\n' a b c < <(echo -e "1\n2\n3"); echo $?; echo $a $b $c
1
1 2 3
Run Code Online (Sandbox Code Playgroud)
注意退出状态 1。
我不想重写我的脚本(echo上面的命令)以使用不同的分隔符(因为在代码的其他地方使用新行是有意义的)。
read当它成功读取 3 个值时,我如何玩得很好并返回零退出状态?
更新
嗯,看来我可能错误地使用了“分隔符”。从手册页:
Run Code Online (Sandbox Code Playgroud)-d *delim* The first character of delim is used to terminate the input line, rather than newline.
因此,我可以达到预期结果的一种方法是这样做:
read -d '#' a b c < <(echo -e "1\n2\n3\n## END ##"); echo $?; echo $a $b $c
Run Code Online (Sandbox Code Playgroud)
也许有更好的方法?
这里的“问题”是read当它达到时返回非零,EOF当分隔符不在输入末尾时会发生这种情况。
因此,在输入末尾添加换行符将使其按照您期望的方式工作(并将参数修复为-dgniourf_gniourf 的评论中所示)。
您的示例中发生的情况是在找到它之前read进行扫描\和点击EOF。然后输入行被分割\n(因为IFS)并分配给$a、$b和$c。然后read返回非零。
使用-d这个很好,但它\n是默认的分隔符,所以如果你这样做,你就不会改变任何东西,并且如果你首先得到了正确的分隔符(),你会发现你的示例根本不起作用(尽管它会从读取-d $'\n'返回)。0(参见http://ideone.com/MWvgu7)
read使用(大多使用非标准值 for时的常见习惯用法-d是测试 的read返回值以及分配给的变量是否具有值。read -d '' line || [ "$line" ]例如。即使由于以下原因在输入的最后“行”上读取失败,该习惯用法也可以工作结尾处缺少终结符。
因此,为了让您的示例正常工作,您需要按照readchepner 指示的方式使用多个调用,或者(如果您确实想要单个调用)那么您需要(请参阅http://ideone.com/xTL8Yn):
IFS=$'\n' read -d '' a b c < <(printf '1 1\n2 2\n3 3')
echo $?
printf '[%s]\n' "$a" "$b" "$c"
Run Code Online (Sandbox Code Playgroud)
添加\0到输入流的末尾(例如printf '1 1\n2 2\n3 3\0')或放在|| [ "$a" ]末尾将避免调用失败返回read。
for read的设置IFS是为了防止 shell 在空格上进行分词并错误地分解我的输入。-d ''已read开启\0。
-d在这里使用是错误的。您真正想要的是三个单独的读取调用:
{ read a; read b; read c; } < <(echo $'1\n2\n3\n')
Run Code Online (Sandbox Code Playgroud)
确保输入以换行符结尾,以便最终的read退出状态为 0。
如果您事先不知道输入中有多少行,则需要将值读入数组中。在bash4 中,只需调用一次readarray:
readarray -t arr < <(echo $'1\n2\n3\n')
Run Code Online (Sandbox Code Playgroud)
在4之前bash,需要使用循环:
while read value; do
arr+=("$value")
done < <(echo $'1\n2\n3\n')
Run Code Online (Sandbox Code Playgroud)
read总是读取单行输入;该-d选项改变了read终止一行的想法。一个例子:
$ while read -d'#' value; do
> echo "$value"
> done << EOF
> a#b#c#
> EOF
a
b
c
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
995 次 |
| 最近记录: |