Odpowiadając na to pytanie, nie byłem w stanie w pełni wyjaśnić, w jaki sposób sygnały rozprzestrzeniają się w rurociągu.
Rozważ następujące przykłady.
Używanie timeout
jako pierwszego elementu w potoku
Powoduje to, gpg
aby wyskoczyć połów SIGTERM
, który został dostarczony cat
przez timeout
pozostawiając uszkodzonego pliku.
$ timeout 1 cat /dev/urandom | gpg -er attie@attie.co.uk > ./myfile.gpg
gpg: Terminated caught ... exiting
Terminated
$ gpg -d < ./myfile.gpg > /dev/null
You need a passphrase to unlock the secret key for
user: "Attie Grande <attie@attie.co.uk>"
4096-bit RSA key, ID C9AEA6AE, created 2016-12-13 (main key ID 7826F053)
gpg: encrypted with 4096-bit RSA key, ID C9AEA6AE, created 2016-12-13
"Attie Grande <attie@attie.co.uk>"
gpg: block_filter 0x145e790: read error (size=14775,a->size=14775)
gpg: block_filter 0x145f110: read error (size=10710,a->size=10710)
gpg: WARNING: encrypted message has been manipulated!
gpg: block_filter: pending bytes!
gpg: block_filter: pending bytes!
Używanie timeout
w środku rurociągu
Działa to zgodnie z oczekiwaniami - gpg
kończy się czysto.
$ cat /dev/urandom | timeout 1 cat | gpg -er attie@attie.co.uk > ./myfile.gpg
$ gpg -qd < ./myfile.gpg > /dev/null
You need a passphrase to unlock the secret key for
user: "Attie Grande <attie@attie.co.uk>"
4096-bit RSA key, ID C9AEA6AE, created 2016-12-13 (main key ID 7826F053)
Używanie SIGUSR1
zamiastSIGTERM
Ponownie działa to zgodnie z oczekiwaniami - gpg
kończy się czysto. Spodziewam się, ponieważ cat
przestaje działać SIGUSR1
, a gpg
ignoruje to.
$ timeout -sUSR1 1 cat /dev/urandom | gpg -er attie@attie.co.uk > ./myfile.gpg
$ gpg -qd < ./myfile.gpg > /dev/null
You need a passphrase to unlock the secret key for
user: "Attie Grande <attie@attie.co.uk>"
4096-bit RSA key, ID C9AEA6AE, created 2016-12-13 (main key ID 7826F053)
Korzystanie z podstawienia procesu
Znowu to działa - choć się nie spodziewałem.
$ gpg -er attie@attie.co.uk > ./myfile.gpg < <( timeout 1 cat /dev/urandom )
$ gpg -qd < ./myfile.gpg > /dev/null
You need a passphrase to unlock the secret key for
user: "Attie Grande <attie@attie.co.uk>"
4096-bit RSA key, ID C9AEA6AE, created 2016-12-13 (main key ID 7826F053)
Mogę tylko założyć, że sygnał pierwszego elementu w potoku jest propagowany do reszty elementów w potoku (nawet rozdzielenie ich timeout cat | cat | gpg
niepowodzeniem).
Szukałem dokumentacji i bawiłem się set -e
, set -o pipefail
ale nie działały tak, jak się spodziewałem.
- Co się właściwie dzieje?
- Jakie są semantyki?
- Czy mamy nad tym kontrolę?
- Czy istnieje lepszy sposób niż przeniesienie procesu generowania sygnału z przodu rurociągu?