Как мне использовать ssh-agent в качестве программы-оболочки?

Существует концепция 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 оболочки.

0
14.03.2019, 02:17
1 ответ

В своем обновлении вы упомянули, что вы начинаете 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);
}

(затем дочерний процесс продолжает выполнение остальной части кода)

Это позволяет вам убить агента без особых последствий, например, для команды, которую вы хотите запустить.

2
28.01.2020, 02:30

Теги

Похожие вопросы