![为什么管道会因 GPG 而失效?](https://linux22.com/image/1483931/%E4%B8%BA%E4%BB%80%E4%B9%88%E7%AE%A1%E9%81%93%E4%BC%9A%E5%9B%A0%20GPG%20%E8%80%8C%E5%A4%B1%E6%95%88%EF%BC%9F.png)
我正在寻求将密码传输到 gpg 中进行对称加密,但它表现得好像我没有传输任何内容,仍然要求我输入密码并重新输入。
以下是我正在尝试的操作(以“enter”作为密码):
(echo 'enter'; echo 'enter') | gpg -c test.py
这为什么不起作用?
我已经知道您可以使用--batch --yes --passphrase='enter'
,但这会在任务管理器的任务中显示密码(因此似乎不太安全 - 如果我错了请告诉我)。
编辑:我刚刚意识到 echo 可能仍会显示在任务管理器中(只是与 gpg 命令分开)。因此,为了解决这个问题,我可以将密码保存到临时文件中,并使用cat myPasswordFile
而不是echo myPassword
。这样,他们就必须从临时文件中实时获取密码(当它存在时),而不是仅记录所有已运行的任务并在闲暇时获取密码。
答案1
您可以使用--passphrase-fd 0
告诉 gpg 从 stdin 读取密码。这应该与管道配合得很好。不要发送两次;这仅在您以交互方式执行时才需要进行拼写检查。
通常 gpg 从 tty 读取,因此您可以重定向输入和输出,并且仍然能够输入密码。
在正常的登录会话中,您的 shell 通过 3 个文件描述符连接到终端:stdin、stdout 和 stderr。管道和重定向运算符会更改这些文件描述符指向的位置。
如果您运行的命令没有任何重定向操作符,则其所有文件描述符都将从 shell 继承。当它从 stdin 读取时,它就是从 tty 读取。
如果使用<
重定向运算符运行相同的命令,则其 stdin 将连接到名称出现在 之后的文件<
。 如果将命令放在运算符的右侧|
,则其 stdin 将连接到管道文件描述符(其另一端连接到 左侧命令的标准输出|
)。
这些你可能已经知道了。你不知道的是,除了文件描述符之外,还有另一个东西将终端和进程联系起来:控制终端。您的 shell 进程有一个控制终端,它被所有子进程继承,在本例中也包括您的gpg
。
当程序想要从用户那里获取键盘输入时,尽管 stdin 不是终端,它也可以通过打开特殊文件来访问其控制终端/dev/tty
。
严重依赖此功能的一种程序是分页程序(例如more
)less
。如果您运行somecommand | less
,它less
要做的是从 stdin 上的管道读取一些输入,显示第一个屏幕,然后从键盘读取以等待您按下某个键来告诉它下一步该做什么。stdin 不能同时是管道和键盘,因此less
打开/dev/tty
。
TTY
进程的控制终端在列中列出ps
。