So I have this pipeline with set -o pipefail in the top of script.
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
If ls -t1 are not finding anything therefore grep fails I belive whole pipeline fails with pipefail. Whats the best solution to use to come around this?
The problem is not the ls.
Even if logs/repologs is an empty directory, ls
would still set exit status 0. If log/repologs does not exist, ls
sets exit code 2. You could catch the latter by guarding the whole pipe with a [[ -d logs/repologs ]] && ...
The main problem is the grep:
If the directory is empty, grep
does not get any input, and therefore your pipefail fires. You could avoid this by doing a
ls -a logs/repologs
but this produces at least two additional entries (.
and ..
) and your wc
count would be off by 2. It would also include other hidden entries in the directories.
However, what's the purpose of the whole statement? If you just want to count the number of non-hidden entries in the directory, your method is unreliable anyway, for if you have a file where the name contains an embedded newline character, it would be counted as two entries.
A more reasonable approach would be to load all the files into an array and take the length of the array:
shopt -s nullglob
files=(logs/repologs/*"$name"*)
echo Number of non-hidden entries : ${#files[*]}
UPDATE:
For completeness: My solution is a bit different to yours in the following respect:
Assume that you would set
name=foo.bar
In your solution, entries fooxbar
and fooybar
would be counted as well, while in my solution, only a literal foo.bar
would be counted. The same applies to other characters which have a special meaning inside a simple regular expression.