pv cannot be started in background.
As you can see in the
src/main/main.c file from
pv's source code, they're
TOSTOP flag on the terminal with
tcsetattr() (in the
c.c_lflag of the
termios structure). They're doing that in order to receive a
SIGTTOU when trying to write to the terminal when not in foreground, catch it with a signal handler, and redirect the output to
/dev/null in order not to "mess up" the terminal.
* Set terminal option TOSTOP so we get signal SIGTTOU if we try to
* write to the terminal while backgrounded.
* Also, save the current terminal attributes for later restoration.
memset(&t, 0, sizeof(t));
t_save = t;
t.c_lflag |= TOSTOP;
tcsetattr(STDERR_FILENO, TCSANOW, &t);
This is of course gross, because it doesn't set that flag just for itself, but for all the programs using the terminal.
But that's not all. As explained in the glibc manual:
Function: int tcsetattr (int filedes, int when, const struct termios
If this function is called from a background process on its
controlling terminal, normally all processes in the process group are
sent a SIGTTOU signal, in the same way as if the process were trying
to write to the terminal. The exception is if the calling process
itself is ignoring or blocking SIGTTOU signals, in which case the
operation is performed and no signal is sent. See Job Control.
They're not blocking or ignoring the
SIGTTOU. And they're also not checking the return value of
tcsetattr() (which would return -1 and set
EINTR if they had set the
SIGTTOU signal handler before).
So the process is stopped. If it receives a
SIGCONT (as from the
bg command), it will stop again when trying to complete the
So I guess you should consider it a feature ;-)