在回答这个问题时,我无法完全解释信号如何通过管道传播。
请考虑以下示例。
使用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
但是他们并没有像我期待的那样行事。
- 究竟发生了什么?
- 什么是语义?
- 我们对此有何控制权?
- 有没有比从管道前端移动信号生成过程更好的方法?