I have some SLES 12 SP5 machines with grep version 2.16 and on a single machine I'm heavily using scripts which contained the following grep --quiet
condition:
# $pid_list contains the result of pstree and $script_pid equals $$
if echo "$pid_list" | grep -qF "($script_pid)"; then
continue
fi
if echo "$pid_list" | grep -qF "($script_pid)"; then
echo "Error: grep has a bug!"
continue
fi
I doubled it, because by a chance of ~0.1% the first condition failed, while the second identical condition succeeded?!
After changing the condition as follows, it works flawlessly (Full code here):
if echo "$pid_list" | grep -F "($script_pid)" >/dev/null; then
continue
fi
Regarding the manual the quiet
option should behave as I would expect it. It should even return true if an error happens:
Exit immediately with zero status if any match is found, even if an error was detected
So I'm confused why it fails sometimes. RAM and filesystem of the machine is fine. The grep binary has the correct file hash, too.
I searched for a commit, but the only one I found is from 2001, which should be part of 2.16 as it is from 2014.
Update1
I tried to use a subshell as @kamil suggested, but it still fails (the "Race condition"-error is displayed sometimes):
if (echo "$pid_list"; true) | grep -qF "($script_pid)"; then
continue
elif (echo "$pid_list"; true) | grep -qF "($script_pid)"; then
echo "Error: Race condition!"
continue
fi
This instead works:
if echo "$pid_list" | grep -qF "($script_pid)" || [[ $? -eq 141 ]]; then
continue
fi
pid_list
and a concrete example of$script_pid
? I know it sounds like it's just as given, but we're looking at an "unlikely" bug, so being able to have a fully reproducible test case that we can a couple hundred times until you're sure it would have failed on your machine is necessary.continue
has no point outside of a loop, so please show the loop in question.echo
andgrep
for substring matching, the shell has built-in means, e.g.case "$pid_list" in ; *"($script_pid)"*) do_something ;; esac
$pid_list
and a$script_pid
.