如何检查ssh-agent是否已经在bash中运行?

时间:2016-11-11 13:45:49

标签: linux bash shell ssh

我的Linux环境中有一个示例sh脚本,它基本上运行当前shell的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

脚本实际上运行正常,但每次运行它都会得到一个新进程,所以我认为它可能会成为一个性能问题而且我最终可能会遇到无用的进程。

输出的一个例子:

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

此外,除此之外,是否可以找到现有的ssh-agent进程并将我的密钥添加到其中?

11 个答案:

答案 0 :(得分:24)

不,真的,如何检查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

取自: https://stackoverflow.com/a/15774758

答案 1 :(得分:8)

如果您希望在脚本退出后立即将其删除,您可以在eval行之后添加它:

trap "kill $SSH_AGENT_PID" exit

或者:

trap "ssh-agent -k" exit

$SSH_AGENT_PIDssh-agent -s的评估中设置。

您应该能够通过浏览/tmp/ssh-*找到正在运行的ssh-agents,并从中重新构建SSH_AGENT个变量(SSH_AUTH_SOCKSSH_AGENT_PID)。

答案 2 :(得分:7)

  

此外,除此之外,是否可以找到现有的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

此代码来自pitfalls of ssh agents,它描述了您目前正在做的事情,此方法以及如何使用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连接)。

答案 3 :(得分:2)

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

单行命令。第一次运行将启动ssh-agent。第二次运行不会启动ssh-agent。简单而优雅的伴侣!!!

答案 4 :(得分:2)

在Ubuntu 14.04下,接受的答案对我不起作用。

我必须使用的用于检查ssh-agent是否正在运行的测试是:

[[ ! -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

答案 5 :(得分:1)

使用$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 -lexpect script进行检查将很省钱,如下例所示:

$ 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-agentssh-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

模拟以上脚本中的命令重复。

答案 6 :(得分:1)

我注意到仅运行代理是不够的,因为有时未设置 GridSelectionColumn.class 变量或指向不再存在的套接字文件。

因此,要连接到您机器上已经运行的 SSH_AUTH_SOCK,您可以这样做:

ssh-agent

答案 7 :(得分:0)

您可以将第1行修改为:

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

然后在脚本结束时你可以做到:

kill -9 $PID_SSH_AGENT

答案 8 :(得分:0)

感谢这里的所有答案。这些年来,我已经多次使用此线程来调整我的方法。想要分享我当前在Linux和OSX上适用的ssh-agent.sh检查器/启动器脚本。

以下是我的$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

答案 9 :(得分:0)

我使这个bash函数可以计数并返回正在运行的ssh-agent进程的数量...它使用procfs而不是$ ps -p $SSH_AGENT_PID:cmd或$SSH_AUTH_SOCK:var来搜索ssh-agent进程。 ..(当ssh-agent的进程已被杀死时,如果用$ ssh-agent -k$ $(ssh-agent -k)而不是$ eval $(ssh-agent -k),这些ENV-var。仍可以用旧值设置)

function count_agent_procfs(){
    declare -a agent_list=( ) 
    for folders in $(ls -d /proc/*[[:digit:]] | grep -v /proc/1$);do
        fichier="${folders}/stat"
        pid=${folders/\/proc\//}
        [[ -f ${fichier} ]] && [[ $(cat ${fichier} | cut -d " " -f2) == "(ssh-agent)" ]] && agent_list+=(${pid})
    done
    return ${#agent_list[@]}
}

..然后如果有很多ssh-agent进程正在运行,您将使用此列表获取其PID ... "${agent_list[@]}"

答案 10 :(得分:0)

cat /usr/local/bin/ssh-agent-pro << 'EOF'
#!/usr/bin/env bash
SSH_AUTH_CONST_SOCK="/var/run/ssh-agent.sock"

if [[ x$(wc -w <<< $(pidof ssh-agent)) != x1 ]] || [[ ! -e ${SSH_AUTH_CONST_SOCK} ]]; then
  kill -9 $(pidof ssh-agent) 2>/dev/null
  rm -rf ${SSH_AUTH_CONST_SOCK}
  ssh-agent -s -a ${SSH_AUTH_CONST_SOCK} 1>/dev/null
fi

echo "export SSH_AUTH_SOCK=${SSH_AUTH_CONST_SOCK}"
echo "export SSH_AGENT_PID=$(pidof ssh-agent)"
EOF
echo "eval \$(/usr/local/bin/ssh-agent-pro)" >> /etc/profile
. /etc/profile

然后您可以ssh-add xxxx一次,每次登录时都可以使用ssh-agent。