为什么在 tmux 中运行 gpg 时 mutt 会挂起?

为什么在 tmux 中运行 gpg 时 mutt 会挂起?

我跑mutt进去tmux,当我跑去gpg签名或加密时,gpg 显示一个空白屏幕,我希望在其中输入我的密码。我已经 straced gpg ,它显示它正在挂起等待套接字read()(大概来自gpg-agent。这里发生了什么?

答案1

简短回答

如果您使用 bash,那么 Chris W. 的包装脚本就是您的最佳选择。如果您可能使用 zsh,那么您可以利用~/.zshenv启动脚本从那里进行设置GPG_TTY,无需包装器。由于 bash 没有类似的启动脚本(参见Bash 启动文件),你必须在那里使用包装器。

export GPG_TTY=${TTY}

一些背景:交互式和非交互式 shell

gpg-agent 期望GPG_TTY指向调用它的 tty,以便它可以以安全的方式显示其密码提示。这GnuPG手册建议放入以下内容~/.bashrc(或类似内容):

GPG_TTY=$(tty)
export GPG_TTY

如果您直接从 shell 调用 mutt,这将起作用: GPG_TTY将被设置,mutt 将拾取它并在需要时将其传递给 gpg。

然而,当您通过 tmux 的new-window命令或类似结构启动 mutt 时,有一个重要的区别:之前,您的 mutt 处于所谓的交互式外壳——也就是说,你打开了一个 shell 提示符并从那里启动了 mutt。 tmux new-window推出一个非交互式shell,因为您的 shell 只需要启动 mutt 并且您将无法与它交互。在这种情况下,bath 不会读取.bash_profile.bashrc根本不会读取,因为它们旨在设置您的 shell 以供交互使用。

zsh 做几乎相同的事情: .zshrc对于交互式 shell 读取,对于非交互式 shell 跳过。然而,在 zsh 中,您可以提供第三个启动文件, .zshenv, 读取的是每一个shell,无论它是否是交互式的。因此,如果您GPG_TTY从那里设置,它将始终可用,无论 mutt 以哪种方式启动。由于$TTY是一个始终指向当前 tty 的 shell 内置变量,因此您可以避免tty每次 shell 启动时生成进程的开销。

答案2

我是mutt通过跑步启动的tmux neww muttmutt正在继承 中设置的环境tmux。这包括$GPG_TTY我正在运行的新窗格的不同之处mutt(或者如果不在tmux环境中则取消设置)。我编写了一个名为的包装器gpgtty,可以$GPG_TTY正确设置新窗格。

#!/bin/sh
GPG_TTY=$(tty) $*

然后我启动mutttmux neww gpgtty muttgpg之后就可以正常工作了。仅供参考,这全部用于pinentry-curses密码gpg输入。

相关内容