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
在您的解决方案中,条目 fooxbar
和 fooybar
也会被计算在内,而在我的解决方案中,只会计算文字 foo.bar
。这同样适用于在简单正则表达式中具有特殊含义的其他字符。
所以我在脚本顶部设置了带有 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
在您的解决方案中,条目 fooxbar
和 fooybar
也会被计算在内,而在我的解决方案中,只会计算文字 foo.bar
。这同样适用于在简单正则表达式中具有特殊含义的其他字符。