如何使用 ssh-agent 作為包裝程序?
我正在嘗試將
awesome
Windows 管理器作為ssh-agent
. 當我使用startx
(ssh-agent startx
)時它起作用了。但現在我正試圖讓它在lightdm
.
lightdm
開始/usr/bin/xinitrcsession-helper
:#!/bin/bash exec $HOME/.xinitrc
~/.xinitrc
:ssh-agent awesome
我得到的是:
509 1 lightdm /usr/bin/lightdm 526 509 Xorg /usr/lib/Xorg :0 -seat seat0 -auth /run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch 877 509 lightdm lightdm --session-child 14 21 1003 877 xinitrcse /bin/bash /usr/bin/xinitrcsession-helper 1028 1003 awesome awesome 1029 1028 ssh-a ssh-agent awesome
並且
set | grep SSH
什麼也不返回。然後我開始另一個
xterm
(ssh-agent xterm
) 並且它有效:1636 1 xterm xterm 1638 1636 bash bash 1651 1638 vim vim 9435 1651 xterm xterm 9447 9435 ssh-a ssh-agent xterm 9449 9435 bash bash 10464 9449 ps ps -eHo pid,ppid,comm,args 10465 9449 les less
這里奇怪的是
ssh-agent
它啟動的程序是一個子程序。你能解釋一下嗎?以及如何執行
awesome
以便之後啟動的程序可以看到ssh-agent
?UPD關於
ssh-agent
成為它執行的命令的孩子。那是為了能夠替換command
為ssh-agent command
. 所以,ssh-agent
forks 和 parentexec
是command
.UPD我的不好,我用
xbindkeys
的是 startxterm
,而前者恰好是之前啟動的ssh-agent
。就像在,xbindkeys && ssh-agent awesome
。所以,它沒有SSH_*
變數可以傳遞給xterm
. 或者說是我最可能的解釋。當使用awesome
’s 的內置工具啟動時xterm
,環境變數是可以傳遞下來的。
在您的更新中,您提到您
xterm
從開始xbindkeys
並從執行開始xbindkeys && ssh-agent awesome
bindkeys
不會有與 SSH 相關的環境,因此xterm
也不會。為了解決這個問題,我建議
eval "$(ssh-agent)" xbindkeys && awesome
現在,這將為兩者設置變數
xbindkeys
and (這很可能是您需要和想要的),但是當您註銷時awesome
它不會自動終止該程序。ssh-agent
為此,您可以使用 (with
bash
),eval "$(ssh-agent)" trap 'eval "$(ssh-agent -k)"' EXIT xbindkeys && awesome
或類似的東西。這將呼叫
ssh-agent -k
which 將殺死代理,只要該 shell 退出或被TERM
,HUP
或終止INT
。
eval
在 的輸出上執行ssh-agent -k
只會取消設置 SSH 變數,並且可能不需要它(因為腳本無論如何都將退出),因此可以將陷阱設置為僅執行ssh-agent -k >/dev/null
。
ssh-agent
作為它啟動的命令的子程序的事情看起來很奇怪。
ssh-agent
分叉出實際的代理程序,然後用它應該執行的命令替換原始程序(使用exec()
)。結果是原始程序(xterm
在您的第二個程序樹中)是代理的父程序:/* * Fork, and have the parent execute the command, if any, or present * the socket data. The child continues as the authentication agent. */ if (D_flag || d_flag) { log_init(__progname, d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 1); format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, SSH_AUTHSOCKET_ENV_NAME); printf("echo Agent pid %ld;\n", (long)parent_pid); fflush(stdout); goto skip; } pid = fork(); if (pid == -1) { perror("fork"); cleanup_exit(1); } if (pid != 0) { /* Parent - execute the given command. */ close(sock); snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid); if (ac == 0) { format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, SSH_AUTHSOCKET_ENV_NAME); printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, SSH_AGENTPID_ENV_NAME); printf("echo Agent pid %ld;\n", (long)pid); exit(0); } if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 || setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) { perror("setenv"); exit(1); } execvp(av[0], av); perror(av[0]); exit(1); }
(然後子程序繼續執行其餘程式碼)
例如,這允許您殺死代理而不會對您要執行的命令產生太大影響。