我正在尝试将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 awesomeset | 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是它运行的命令的子命令。这是为了能够用ssh-agent command代替C20。所以,ssh-agent分叉,和父母execs command。
UPD我的错,我使用xbindkeys启动xterm,而前者恰好在ssh-agent之前启动。就像进去,xbindkeys && ssh-agent awesome。因此,它没有将SSH_*变量传递给xterm。我最可能的解释也是如此。当使用awesome的S内置设施启动xterm时,环境变量就会被传递下来。
发布于 2019-03-13 22:34:01
在您的更新中,您提到您从xterm启动xbindkeys,并且因为您运行了
xbindkeys && ssh-agent awesomebindkeys将不具有与SSH相关的环境,因此,xterm也不会。
为了解决这个问题,我建议
eval "$(ssh-agent)"
xbindkeys && awesome现在,这将为xbindkeys和awesome设置变量(这很可能是您所需要和想要的),但是当您注销时,它不会自动终止ssh-agent进程。
为此,您可以使用(与bash),
eval "$(ssh-agent)"
trap 'eval "$(ssh-agent -k)"' EXIT
xbindkeys && awesome或者类似的东西。这将调用ssh-agent -k,一旦该外壳退出或被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);
}(子进程然后继续执行其余的代码)
例如,这允许您杀死代理,而不会对您想要运行的命令产生多大影响。
https://unix.stackexchange.com/questions/498488
复制相似问题