Отвечая на этот вопрос, я не смог полностью объяснить, как сигналы распространяются по конвейеру.
Рассмотрим следующие примеры.
Использование timeout
в качестве первого элемента в конвейере
Это заставляет gpg
выручить, поймав SIGTERM
который был доставлен cat
, по timeout
, оставив поврежденный файл.
$ 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!
Использование timeout
в середине конвейера
Это работает, как и ожидалось - gpg
выходит чисто.
$ 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)
Использование SIGUSR1
вместо SIGTERM
Опять же, это работает, как и ожидалось - gpg
выходит чисто. Я ожидаю, потому что cat
выходит на SIGUSR1
, в то время как gpg
игнорирует это.
$ 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)
Использование процесса замены
Опять же, это работает - хотя я не ожидал этого.
$ 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)
Я могу только предположить, что сигнал первого элемента в конвейере распространяется на остальные элементы в конвейере (даже разделение их timeout cat | cat | gpg
не удается).
Я посмотрел документацию и поиграл с set -e
, set -o pipefail
но они не действовали так, как я ожидал.
- Что на самом деле происходит?
- Какова семантика?
- Есть ли у нас контроль над этим?
- Есть ли лучший способ, чем переместить процесс генерации сигнала из передней части конвейера?