Bash- 如何处理具有多个参数的管道和 -o 管道启用

Bash- how to handle pipeline with multiple argument and -o pipeline enable

所以我在脚本顶部设置了带有 set -o pipefail 的管道。

 local numbr_match
    numbr_match=$(ls -t1 logs/repologs | grep "$name" | wc --lines)
 if [ ! -z "${numbr_match}" ] && [ "${numbr_match}" -le 
   "$logrot_keep"];then
    echo "Found $numbr_match backups matching '$name', don't need to 
     remove until we have more than $logrot_keep"
 else

如果 ls -t1 没有找到任何东西,因此 grep 失败,我相信整个管道因 pipefail 而失败。解决这个问题的最佳解决方案是什么?

不是 ls 的问题。

即使 logs/repologs 是空目录,ls 仍会设置退出状态 0。如果 log/repologs 不存在,ls 会设置退出代码 2。您可以通过用 [[ -d logs/repologs ]] && ...

保护整个管道来捕获后者

主要问题是 grep:

如果目录为空,grep 不会获得任何输入,因此您的 pipefail 会触发。您可以通过执行 a

来避免这种情况
ls -a logs/repologs

但这会产生至少两个额外的条目(...)并且您的 wc 计数将减少 2。它还会包括目录中的其他隐藏条目.

但是,整个语句的目的是什么?如果你只是想计算目录中非隐藏条目的数量,你的方法无论如何都是不可靠的,因为如果你有一个名称包含嵌入换行符的文件,它将被计为两个条目。

更合理的做法是将所有文件加载到一个数组中,并取数组的长度:

shopt -s nullglob
files=(logs/repologs/*"$name"*)
echo Number of non-hidden entries : ${#files[*]}

更新:

为了完整起见:我的解决方案在以下方面与您的略有不同:

假设你会设置

name=foo.bar

在您的解决方案中,条目 fooxbarfooybar 也会被计算在内,而在我的解决方案中,只会计算文字 foo.bar。这同样适用于在简单正则表达式中具有特殊含义的其他字符。