Hypothesis: in the script you did `set -o pipefail` (if the shell interpreting the script is Bash; other shells may provide similar functionality). From `man 1 bash`: > `pipefail` > If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully. This option is disabled by default. When there is a match, `grep -q` exits early and returns `0`. Then `echo` [may or may not return `141`][1]. It depends on if `echo` manages to write everything to the pipe buffer before `grep` closes its end of the pipe. Even for the same input things may go one way or another, it's a [race condition][2]. If `141` happens then the return value of the pipe will be `141` because of `pipefail`. Assuming you really used `set -o pipefail`, I say the behavior you observed is absolutely not a bug of `grep` nor the shell. The bug is in your script. My answer under the linked question provides solutions. The simplest one for you is: if (echo "$pid_list"; true) | grep -qF "($script_pid)"; then [1]: https://unix.stackexchange.com/q/580117/108618 [2]: https://en.wikipedia.org/wiki/Race_condition