我跑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 mutt
。mutt
正在继承 中设置的环境tmux
。这包括$GPG_TTY
我正在运行的新窗格的不同之处mutt
(或者如果不在tmux
环境中则取消设置)。我编写了一个名为的包装器gpgtty
,可以$GPG_TTY
正确设置新窗格。
#!/bin/sh
GPG_TTY=$(tty) $*
然后我启动mutt
:tmux neww gpgtty mutt
。gpg
之后就可以正常工作了。仅供参考,这全部用于pinentry-curses
密码gpg
输入。