Ich habe eine Zeile im Bash-Skript geleitet und möchte prüfen, ob die Pipeline Daten enthält, bevor ich sie einem Programm zuführe.
Beim Suchen fand ich etwa test -t 0
aber das geht hier nicht. Gibt immer false zurück.
Wie kann man also sicher sein, dass die Pipe Daten enthält?
Beispiel:
echo "string" | [ -t 0 ] && echo "empty" || echo "fill"
Ausgabe:fill
echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"
Ausgabe:fill
Im Gegensatz zur Standard-/kanonischen Methode zum Testen, ob die vorangegangene Pipeline eine Ausgabe erzeugt hat? die Eingabe muss erhalten bleiben, um sie an das Programm zu übergeben. Dies verallgemeinert Wie kann die Ausgabe von einem Prozess an einen anderen weitergeleitet, aber nur ausgeführt werden, wenn der erste eine Ausgabe hat? die sich auf das Versenden von E-Mails konzentriert.
Akzeptierte Antwort:
Es gibt keine Möglichkeit, mit allgemein verfügbaren Shell-Dienstprogrammen auf den Inhalt einer Pipe zu blicken, noch gibt es eine Möglichkeit, ein Zeichen aus der Pipe zu lesen und es dann zurückzusetzen. Der einzige Weg, um zu wissen, dass eine Pipe Daten enthält, besteht darin, ein Byte zu lesen, und dann müssen Sie dieses Byte an sein Ziel bringen.
Tun Sie also genau das:Lesen Sie ein Byte; Wenn Sie ein Dateiende erkennen, tun Sie, was Sie tun möchten, wenn die Eingabe leer ist. Wenn Sie ein Byte lesen, forken Sie, was Sie tun möchten, wenn die Eingabe nicht leer ist, leiten Sie dieses Byte hinein und leiten Sie den Rest der Daten weiter.
first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n | tr -dc 0-9)
if [ -z "$first_byte" ]; then
# stuff to do if the input is empty
else
{
printf "\$first_byte"
cat
} | {
# stuff to do if the input is not empty
}
fi
Das ifne
Utility von Joey Hess’ moreutils führt einen Befehl aus, wenn seine Eingabe nicht leer ist. Es wird normalerweise nicht standardmäßig installiert, sollte aber auf den meisten Unix-Varianten verfügbar oder einfach zu erstellen sein. Wenn die Eingabe leer ist, ifne
tut nichts und gibt den Status 0 zurück, was nicht von der erfolgreichen Ausführung des Befehls zu unterscheiden ist. Wenn Sie etwas tun möchten, wenn die Eingabe leer ist, müssen Sie dafür sorgen, dass der Befehl nicht 0 zurückgibt, was erreicht werden kann, indem Sie den Erfolgsfall einen unterscheidbaren Fehlerstatus zurückgeben lassen:
ifne sh -c 'do_stuff_with_input && exit 255'
case $? in
0) echo empty;;
255) echo success;;
*) echo failure;;
esac
test -t 0
hat damit nichts zu tun; es testet, ob die Standardeingabe ein Terminal ist. Es sagt so oder so nichts darüber aus, ob eine Eingabe verfügbar ist.