Ho reindirizzato una riga nello script bash e voglio verificare se la pipe contiene dati, prima di inviarli a un programma.
Cercando ho trovato su test -t 0
ma qui non funziona. Restituisce sempre false.
Quindi, come essere sicuri che la pipe contenga dati?
Esempio:
echo "string" | [ -t 0 ] && echo "empty" || echo "fill"
Output:fill
echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"
Output:fill
A differenza del modo standard/canonico per verificare se la precedente pipeline ha prodotto output? l'input deve essere conservato per passarlo al programma. Questo generalizza Come reindirizzare l'output da un processo all'altro ma eseguire solo se il primo ha output? che si concentra sull'invio di email.
Risposta accettata:
Non c'è modo di dare un'occhiata al contenuto di una pipe usando le utilità della shell comunemente disponibili, né c'è un modo per leggere un carattere dalla pipe e poi reinserirlo. L'unico modo per sapere che una pipe ha dei dati è leggere un byte, quindi devi portare quel byte a destinazione.
Quindi fai proprio questo:leggi un byte; se rilevi una fine del file, fai quello che vuoi fare quando l'input è vuoto; se leggi un byte, esegui il fork di ciò che vuoi fare quando l'input non è vuoto, invia quel byte in esso e invia il resto dei dati.
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
Il ifne
utility da moreutils di Joey Hess esegue un comando se il suo input non è vuoto. Di solito non è installato per impostazione predefinita, ma dovrebbe essere disponibile o facile da costruire sulla maggior parte delle varianti Unix. Se l'input è vuoto, ifne
non fa nulla e restituisce lo stato 0, che non può essere distinto dal comando eseguito correttamente. Se vuoi fare qualcosa se l'input è vuoto, devi fare in modo che il comando non restituisca 0, cosa che può essere fatta facendo in modo che il caso di successo restituisca uno stato di errore distinguibile:
ifne sh -c 'do_stuff_with_input && exit 255'
case $? in
0) echo empty;;
255) echo success;;
*) echo failure;;
esac
test -t 0
non ha nulla a che fare con questo; verifica se lo standard input è un terminale. Non dice nulla in un modo o nell'altro sulla disponibilità di input.