为什么 read 在 bash 中抛出错误但工作正常?

Why does read throw an error in bash but works fine?

此 bash 脚本将数组写入文件,然后将文件读回另一个数组。 (这对于脚本之间基于数组的通信很有用。)但是,IFS 行(第 12 行)捕获了一个奇怪的、未报告的错误。 为什么?

#!/bin/bash

# eso-error-ic

trap 'echo Error trapped, with code $?, on line ${LINENO}' ERR

# write data to a file
arr=(0 abc) && printf "%s\n" "${arr[@]}" > eso.out

# read data from the file into an array
# throws an error!!
IFS=$'\n' read -d '' -a new_arr < eso.out

# but it worked...
echo ${new_arr[0]}
echo ${new_arr[1]}

脚本输出:

Error trapped, with code 1, on line 12
0
abc

缺少的是产生错误时显示的任何类型的消息。您得到的只是来自陷阱的消息,但没有关于 什么 错误 .

的消息

换句话说,IFS/read 行产生了一个错误,该错误被捕获,但没有显示任何错误消息,并且该行正确地将文件读入数组变量。它有效,没有报告错误,但是 "error" 被困住了。

如果您注释掉陷阱行或切换到 command/eval/cat 方法将文件读入数组(如 here 所建议),则不会捕获任何错误。下面是此脚本的 command/eval/cat 行(替换第 12 行):

IFS=$'\n' GLOBIGNORE='*' command eval 'new_arr=($(cat eso.out))'

错误来自未收到 read 期望的分隔符。我和

一样
read -d x variable <<<"hello"

如果我将输入更改为 "hellox",错误就会消失。

如@Aserre 所述,详细分析在我们的 Unix & Linux sister site 中,正如@CharlesDuffy 所指出的,常见的解决方法是

read variable || [[ $variable ]]

即使没有 -d 也可以使用它来处理可能缺少最终终止换行符的文件。