我使用此循环来遍历文件,或者,如果没有文件,则读取stdin:
#!/bin/bash
set -e
cat "$@" | while read arr ; do
echo "Got this line ${arr}"
done
问题是如果文件不存在,则不会出错。
您可以在此处查看完整示例: https://github.com/StackExchange/blackbox/blob/master/tools/mk_rpm_fpmdir
如果找不到任何文件, cat
会返回错误代码1。但是,该错误不会导致程序停止。
如果找不到文件,我如何迭代$@
并失败?
答案 0 :(得分:3)
有几种可用选项。一个是简单地抛弃cat
,因此没有管道(具有避免子shell使用的有利副作用,因此允许更改shell状态 - 变量集等等 - 持续超出内部循环) :
set -e
for f; do # in "$@" is implicit
while read -r -a arr; do
printf 'Got line: '
printf '%q ' "${arr[@]}"
printf '\n'
done <"$f"
done
上述内容也是以完全保留数组读取方式打印内容的方式,并明确打印其内容(区分包含两个元素foo
bar baz
的数组包含三个元素foo
bar
baz
)。
另一种方法是设置pipefail
,如果管道的任何组件返回非零退出状态(包括cat
),将导致管道被视为失败:
set -e
set -o pipefail
cat "$@" | while IFS= read -r; do
printf 'Got line: %q\n' "$REPLY"
done
这可以通过覆盖默认行为来实现,只有管道的右侧才能考虑命令的整体退出状态。
答案 1 :(得分:1)
for f in "${@}"; do
test -f "${f}" || exit # fail if file doesn't exist
cat "${f}" | awk '{print "Got this line" $0}'
done