为什么管道会因 GPG 而失效?

为什么管道会因 GPG 而失效?

我正在寻求将密码传输到 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

严重依赖此功能的一种程序是分页程序(例如moreless。如果您运行somecommand | less,它less要做的是从 stdin 上的管道读取一些输入,显示第一个屏幕,然后从键盘读取以等待您按下某个键来告诉它下一步该做什么。stdin 不能同时是管道和键盘,因此less打开/dev/tty

TTY进程的控制终端在列中列出ps

相关内容