Существует концепция cwd
, которую отслеживает каждый запущенный процесс.
Или точнее: ядро хранит представление о cwd
каждого процесса.
То, что может быть прочитано с помощью (для системы с / proc):
readlink /proc/$PID_of_PROCESS/cwd
И для запущенной оболочки (для которой ее PID должен быть $$):
$ readlink /proc/$$/cwd
Оболочка отслеживает та же информация (даже если иногда они могут рассинхронизироваться) в переменной $ PWD и в команде pwd
:
$ cd /tmp; echo "Present working directory: $PWD"
Present working directory: /tmp
$ cd /tmp; echo "Current working directory: $(pwd)"
Current working directory: /tmp
Итак, команда pwd
представляет ] cwd
каждого процесса:
Место, где каждый процесс стоит внутри дерева каталогов.
Каждый раз, когда оболочка, сценарий или процесс выполняют cd
, все эти переменные обновляются (кроме некоторых угловых случаев).
Оболочка может изменить свой pwd
, например, выполнив cd / tmp
.
Сценарий может указать оболочке, под которой он работает, изменить pwd
на cd / tmp
.
Или какой-либо другой процесс c
может вызвать ядро для выполнения эквивалента cd / tmp
.
Во всех случаях обновляется ядро cwd
и (если процесс является оболочкой) pwd
оболочки.
В своем обновлении вы упомянули, что вы начинаете xterm
с xbindkeys
, и поскольку вы запускаете
xbindkeys && ssh-agent awesome
bindkeys
не будет иметь среды, связанной с 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);
}
(затем дочерний процесс продолжает выполнение остальной части кода)
Это позволяет вам убить агента без особых последствий, например, для команды, которую вы хотите запустить.