On Tue, 13 Mar 2018 21:52:01 -0400,
Luke Shumaker wrote:
> From: Luke Shumaker <luke...@parabola.nu>
> `grep -q` may exit as soon as it finds a match; this is a good optimization
> for when the input is a file.  However, if the input is the output of
> another program, then that other program will receive SIGPIPE, and further
> writes will fail.  When this happens, it might (bsdtar does) print a
> message about a "write error" to stderr.  Which is going to confuse and
> alarm the user.
> In one of the cases, this had already been mitigated by wrapping
> bsdtar in "echo "$(bsdtar ...)", as Bash builtin echo doesn't complain
> if it gets SIGPIPE.  However, that means we're storing the entire
> output of bsdtar in memory, which is silly.
> ---

> -                                     echo "$(bsdtar -xf 
> "${FTP_BASE}/${repo}/os/${tarch}/${repo}${db%.tar.*}" -O)" | grep -qv 
> ${pkgname}
> +                                     bsdtar -xf 
> "${FTP_BASE}/${repo}/os/${tarch}/${repo}${db%.tar.*}" -O | grep -v ${pkgname} 
> &>/dev/null

This is broken.

As the commit message said, the subshell soaks up the full output to
avoid SIGPIPE.  But it also has a nother subtle purpose: to ensure
that at least one "\n" is written to grep's stdin (as echo appends
"\n").  Otherwise, if the db is now empty, grep will fail because it
didn't recieve anything.

The correct command is

        ! bsdtar -xf "${FTP_BASE}/${repo}/os/${tarch}/${repo}${db%.tar.*}" -O | 
grep ${pkgname} &>/dev/null

Happy hacking,
~ Luke Shumaker

Reply via email to