為什麼 mutt 在 tmux 中執行 gpg 時會掛起?
我跑
mutt
進去tmux
,當我跑去gpg
簽名或加密時,gpg 顯示一個空白螢幕,我希望在其中輸入我的密碼。我已經跟踪了 gpg ,它表明它正在等待一個套接字read()
(大概來自gpg-agent
。這裡發生了什麼?
簡短的回答
如果您使用的是 bash,那麼 Chris W. 的包裝腳本就是您要走的路。如果您使用的是 zsh,那麼您可以利用
~/.zshenv
啟動腳本GPG_TTY
從那裡設置,不需要包裝器。由於 bash 沒有類似的啟動腳本(參見Bash Startup Files),因此您必須在那裡使用包裝器。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中——也就是說,您打開了一個 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 出現時產生程序的成本。