How to prevent curl output from printing a preceding pipe's output?
curl
does not print the "preceding pipe's output". What happens is curl
and gpg
print some messages to your terminal. The messages interfere with each other.
Remember that piped commands run concurrently.
If you expect the output from successful gpg
never to be empty then use ifne
:
… | gpg … | ifne curl …
(In Debian ifne
is in the moreutils
package.)
The main purpose of ifne
is to prevent a command (here: curl
) from running if the stdin is empty. To know if the stdin is really empty, the tool needs to wait for any data or EOF. This delays the actual command. A delay is what you need.
I expect gpg
to start printing only after it gets the right passphrase. I did not test ifne
thoroughly with preceding gpg
asking for passphrase, but I did test with sudo …
asking for password. If gpg
works as I expect then ifne
can help you. It will run curl
after you provide the passphrase.
Note ifne
will prevent curl
from running if gpg
prints nothing to its stdout (e.g. because the passphrase was wrong). This behavior is often desired. However if the output from successful gpg
can be empty and still should be piped to curl
, then ifne
alone is not the right thing.
If you want to run curl
regardless if gpg
prints anything then keep reading.
The code below is a reduced version of my report
script from this answer. Save it as delay
.
It uses ifne
in a more complicated way. The code must be an executable script (I mean don't try to make it a shell function) because it calls itself via ifne "$0"
(and ifne
cannot run a function).
#!/bin/bash
if [ "$1" = "-X" ]; then
marker=1
fd="$2"
shift 2
else
unset marker
exec {fd}>&1
fi
if [ "$marker" ]; then
( >&"$fd" "$@" )
else
ifne -n "$0" -X "$fd" "$@" | ifne "$0" -X "$fd" "$@"
fi
The purpose of delay
is to delay execution of a command until there is data or EOF in the stdin. It was designed to be used after |
.
You should use it like this:
… | gpg … | delay curl …
curl
will run only after gpg
starts printing to its stdout or closes for whatever reason.
Some technical details are explained in the already linked answer.
The difference between ifne foo
, ifne -n foo
and delay foo
:
ifne foo
waits for data or EOF and then runs foo
iff there is data,
ifne -n foo
waits for data or EOF and then runs foo
iff there is no data,
delay foo
waits for data or EOF and then runs foo
unconditionally.