Как проверить, запущен ли ssh-агент в bash?

У меня есть образец sh script в моей Linux-среде, который в основном запускает ssh-agent для текущей оболочки, добавляет к ней ключ и запускает две команды git:

#!/bin/bash
eval "$(ssh-agent -s)"
ssh-add /home/duvdevan/.ssh/id_rsa

git -C /var/www/duvdevan/ reset --hard origin/master
git -C /var/www/duvdevan/ pull origin master

Script работает нормально, но каждый раз, когда я его запускаю, я получаю новый процесс, поэтому я думаю, что это может стать проблемой производительности, и я могу в конечном итоге иметь бесполезные процессы там.

Пример вывода:

Agent pid 12109
Identity added: /home/duvdevan/.ssh/custom_rsa (rsa w/o comment)

Кроме того, наряду с этим можно найти существующий процесс ssh-agent и добавить в него свои ключи?

Ответ 1

Нет, действительно, как проверить, запущен ли ssh-agent в bash?

Ответы пока не отвечают на исходный вопрос...

Вот что работает для меня:

if ps -p $SSH_AGENT_PID > /dev/null
then
   echo "ssh-agent is already running"
   # Do something knowing the pid exists, i.e. the process with $PID is running
else
eval `ssh-agent -s`
fi

Это было взято из: fooobar.com/questions/17261/...

Ответ 2

Если вы хотите, чтобы он был убит сразу после выхода script, вы можете просто добавить это после строки eval:

trap "kill $SSH_AGENT_PID" exit

Или:

trap "ssh-agent -k" exit

$SSH_AGENT_PID устанавливается в eval из ssh-agent -s.

Вы можете найти выполняемые ssh-агенты путем сканирования через /tmp/ssh-* и восстановить из него переменные SSH_AGENT (SSH_AUTH_SOCK и SSH_AGENT_PID).

Ответ 3

  Кроме того, возможно ли найти существующий процесс ssh-agent и добавить в него мои ключи?

Да. Мы можем сохранить информацию о соединении в файле:

# Ensure agent is running
ssh-add -l &>/dev/null
if [ "$?" == 2 ]; then
    # Could not open a connection to your authentication agent.

    # Load stored agent connection info.
    test -r ~/.ssh-agent && \
        eval "$(<~/.ssh-agent)" >/dev/null

    ssh-add -l &>/dev/null
    if [ "$?" == 2 ]; then
        # Start agent and store agent connection info.
        (umask 066; ssh-agent > ~/.ssh-agent)
        eval "$(<~/.ssh-agent)" >/dev/null
    fi
fi

# Load identities
ssh-add -l &>/dev/null
if [ "$?" == 1 ]; then
    # The agent has no identities.
    # Time to add one.
    ssh-add -t 4h
fi

Этот код взят из ловушек агентов ssh, в котором описываются как ловушки того, что вы в данный момент делаете, этого подхода, так и то, как вы должны использовать ssh-ident для выполнения это для тебя.


Если вы хотите запустить ssh-agent только в том случае, если он не запущен, и ничего не делать иначе:

if [ $(ps ax | grep [s]sh-agent | wc -l) -gt 0 ] ; then
    echo "ssh-agent is already running"
else
    eval $(ssh-agent -s)
    if [ "$(ssh-add -l)" == "The agent has no identities." ] ; then
        ssh-add ~/.ssh/id_rsa
    fi

    # Don't leave extra agents around: kill it on exit. You may not want this part.
    trap "ssh-agent -k" exit
fi

Однако это не гарантирует, что ssh-agent будет доступен (просто потому, что он запущен, не означает, что у нас есть $ SSH_AGENT_PID для подключения ssh-add).

Ответ 4

ps -p $SSH_AGENT_PID > /dev/null || eval "$(ssh-agent -s)"

Однострочная команда. Запуск в первый раз запустит ssh-agent. Запуск во второй раз не запустит ssh-agent. Простой и элегантный помощник !!!

Ответ 5

Принятый ответ не работал у меня под Ubuntu 14.04.

Тест, чтобы проверить, запущен ли ssh-агент, который я должен использовать:

[[ ! -z ${SSH_AGENT_PID+x} ]]

И я запускаю ssh-agent с помощью:

exec ssh-agent bash

В противном случае SSH_AGENT_PID не установлен.

Кажется, что следующее работает под Ubuntu 14.04 и 18.04.

#!/bin/bash
sshkey=id_rsa
# Check ssh-agent
if [[ ! -z ${SSH_AGENT_PID+x} ]]
then
    echo "[OK] ssh-agent is already running with pid: "${SSH_AGENT_PID}
else
    echo "Starting new ssh-agent..."
    'exec ssh-agent bash'
    echo "Started agent with pid: "${SSH_AGENT_PID}
fi
# Check ssh-key
if [[ $(ssh-add -L | grep ${sshkey} | wc -l) -gt 0 ]]
then
    echo "[OK] SSH key already added to ssh-agent"
else
    echo "Need to add SSH key to ssh-agent..."
    # This should prompt for your passphrase
    ssh-add ~/.ssh/${sshkey}
fi

Ответ 6

Использование $SSH_AGENT_PID может только протестировать ssh-agent, но пропустить идентификаторы, когда он еще не добавлен

$ eval 'ssh-agent'
Agent pid 9906
$ echo $SSH_AGENT_PID
9906
$ ssh-add -l
The agent has no identities.

Так что было бы неплохо проверить его с помощью ssh-add -l с помощью сценария ожидания, как в примере ниже:

$ eval 'ssh-agent -k'
Agent pid 9906 killed
$ ssh-add -l
Could not open a connection to your authentication agent.
$ ssh-add -l &>/dev/null
$ [[ "$?" == 2 ]] && eval 'ssh-agent'
Agent pid 9547
$ ssh-add -l &>/dev/null
$ [[ "$?" == 1 ]] && expect $HOME/.ssh/agent
spawn ssh-add /home/user/.ssh/id_rsa
Enter passphrase for /home/user/.ssh/id_rsa: 
Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)
$ ssh-add -l
4096 SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /home/user/.ssh/id_rsa (RSA)

Поэтому, когда ssh-agent и ssh-add -l запускаются для сценария bash:

#!/bin/bash
ssh-add -l &>/dev/null
[[ "$?" == 2 ]] && eval 'ssh-agent'
ssh-add -l &>/dev/null
[[ "$?" == 1 ]] && expect $HOME/.ssh/agent

тогда он всегда будет проверять и проверять, работает ли соединение:

$ ssh-add -l
4096 SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /home/user/.ssh/id_rsa (RSA)

Вы также можете эмулировать повторение команд в приведенном выше сценарии с помощью do while

Ответ 7

Вы можете изменить строку # 1 на:

PID_SSH_AGENT=`eval ssh-agent -s | grep -Po "(?<=pid\ ).*(?=\;)"`

И затем в конце script вы можете сделать:

kill -9 $PID_SSH_AGENT

Ответ 8

Спасибо за все ответы здесь. Я использовал эту тему несколько раз за эти годы, чтобы настроить свой подход. Хотел поделиться своим текущим сценарием проверки/запуска ssh-agent.sh, который работает для меня в Linux и OSX.

Следующий блок - мой $HOME/.bash.d/ssh-agent.sh

function check_ssh_agent() {
  if [ -f $HOME/.ssh-agent ]; then
    source $HOME/.ssh-agent > /dev/null
  else
    # no agent file
    return 1
  fi

  if [[ ${OSTYPE//[0-9.]/} == 'darwin' ]]; then
    ps -p $SSH_AGENT_PID > /dev/null  
    # gotcha: does not verify the PID is actually an ssh-agent
    # just that the PID is running
    return $?
  fi

  if [ -d /proc/$SSH_AGENT_PID/ ]; then
    # verify PID dir is actually an agent
    grep ssh-agent /proc/$SSH_AGENT_PID/cmdline  > /dev/null  2> /dev/null; 
    if [ $? -eq 0 ]; then
      # yep - that is an agent
      return 0
    else
      # nope - that is something else reusing the PID
      return 1
    fi
  else
    # agent PID dir does not exist - dead agent
    return 1
  fi 
}

function launch_ssh_agent() {
  ssh-agent > $HOME/.ssh-agent
  source $HOME/.ssh-agent
  # load up all the pub keys
  for I in $HOME/.ssh/*.pub ; do
    echo adding ${I/.pub/}
    ssh-add ${I/.pub/}
  done
}

check_ssh_agent
if [ $? -eq 1 ];then
  launch_ssh_agent
fi

Я запускаю вышеупомянутое из моего .bashrc, используя:

if [ -d $HOME/.bash.d ]; then
  for I in $HOME/.bash.d/*.sh; do
    source $I  
  done
fi

Надеюсь, что это поможет другим встать и идти быстро.

Создана публичная суть, если вы хотите взломать/улучшить это со мной: https://gist.github.com/dayne/a97a258b487ed4d5e9777b61917f0a72