【发布时间】:2018-07-26 06:27:32
【问题描述】:
此 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 行产生了一个错误,该错误被捕获,但没有显示错误消息,并且该行正确地将文件读入数组变量。它可以工作,不报告错误,但会捕获一个“错误”。
如果您注释掉陷阱行或切换到命令/eval/cat 方法将文件读入数组(如建议的here),则不会捕获错误。下面是这个脚本的 command/eval/cat 行的样子(替换第 12 行):
IFS=$'\n' GLOBIGNORE='*' command eval 'new_arr=($(cat eso.out))'
【问题讨论】:
-
我可以在 MacOS High Sierra 上使用 Bash 3.2.57(1) 进行复制,只需
read -d '' variable <<<"moo"; echo $? -
哇。更简单的回购!我已经在 CentOS 6/7、RHEL 6/7 上的 Bash 4 和 Apple Darwin 17.3 (High Sierra) 上的 Bash 3 和 4 上复制了它。
-
跨站复制,详细说明:unix.stackexchange.com/questions/80045/…
-
顺便说一下,
set -e和/或 ERR 陷阱通常被认为是一个坏主意。请参阅BashFAQ #105,如果赶时间,请跳过以下练习的寓言;或set -e的不同 shell 实现之间的不兼容性列表(以及相关的,其行为无法直观预测的程度)here。 -
顺便说一句,一般而言,我建议
readarray -t new_arr <eso.dat(如果您不需要与 bash pre-4.x 兼容)——除非您是从进程替换而不是文件读取,这样通过附加尾随或 NUL 来传递该进程的成功或失败到read的成功是一种非常有用的功能。