判断ssh远程命令是否执行结束

注:这是一个没什么鸟用的功能。不过也算是一种拓展。

通常在那些"一键化部署"的shell脚本中,可能需要使用ssh执行远程命令来实现一些简单的自动化,这些远程命令可能需要执行一段时间才能结束(如yum命令)。例如,远程ssh配置yum源,远程ssh安装软件包。

为了让脚本实现"并行"执行,这个远程ssh命令往往还会加上"-f"选项使其进入后台执行。此时,如果后续的远程任务正好要依赖于这个命令已经执行完成,那么我们要判断前面的任务是否执行完成。例如,在配置软件的时候,必须先判断软件是否安装结束。

判断的方式挺简单,只需判断这个ssh进程是否存在就可以了。例如:

[root@node1 ~]# ssh 192.168.100.101 -f 'yum makecache'
[root@node1 ~]# killall -s 0 ssh
[root@node1 ~]# echo $?

这样的方法没错,也能应付绝大多数情况,但如果有多个远程后台命令的ssh进程,就无法知道具体是哪个ssh进程。

于是,可以采用另一种方法,将执行远程命令的ssh进程放进后台,再用$!来获取最近的后台ssh进程。例如:

[root@node1 ~]# ssh 192.168.100.101 -f 'yum makecache' & echo $!
[1] 76115
76115

但这是错误的方法,如果你现在去查看ssh进程,你会发现进程号不是76115。

[root@node1 ~]# pstree -p | grep 'ssh('
           |-ssh(76116)

因为ssh在执行远程后台命令(加上"-f"选项)的时候,它自身会在建立ssh连接后再fork一个后台ssh进程用来执行远程命令。

也就是说,当ssh执行远程后台命令的时候,会有两个ssh进程

  • 第一个ssh进程是初始ssh进程,用于建立连接、发送要执行的命令、fork新的ssh进程等,当这些任务结束后,这个ssh进程会消逝;
  • 第二个ssh进程是第一个ssh进程fork出来的新进程(调试的结果将显示"debug1: forking to background"),用来执行远程命令。它是后台进程,挂靠在init/systemd进程下。当远程命令执行结束时,这个后台ssh进程会消逝。

注意,只有使用了"-f"选项,第一个ssh进程才会fork新的后台ssh进程,因为前台的任务(没有使用"-f")可以直接在第一个ssh进程上执行。

第二个后台ssh进程无法用$!捕捉,$!捕捉到的只是&的后台,而对于ssh ... &中的"&"来说,它是将ssh连接进程(即第一个ssh进程)置于后台,而不是将fork出来的ssh后台进程再放入后台。所以上面的"echo $!"的结果76115比后台ssh进程号76116要小。

那么有什么好方法可以判断多个远程ssh进程中的每一个?没有好方法(我个人还没有想到),只能通过比较愚笨的方式来实现判断:将每个后台ssh进程的pid号保存起来(存放到每个变量中,或数组中)。

例如,有两个执行远程命令的ssh进程:

ssh 192.168.100.101 -f 'sleep 50'
ssh_pid1=`ps x | awk '/ssh.*slee[p]/{print $1}' | tail -1`
ssh 192.168.100.101 -f 'sleep 60'
ssh_pid2=`ps x | awk '/ssh.*slee[p]/{print $1}' | tail -1`

# ssh_pid1 finished?
kill -0 $ssh_pid1
echo $?

# ssh_pid2 finished?
kill -0 $ssh_pid2
echo $?

最后补上ssh连接或执行远程命令时,内部过程的详细信息。这些信息使用ssh -vvv即可获取,此处给出的是筛选后的一小部分。

当ssh建立连接或执行前台远程命令(没有使用"-f"选项)时:

OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 56: Applying options for *
debug2: ssh_connect: needpriv 0
debug1: Connecting to 192.168.100.101 [192.168.100.101] port 22.
debug1: Connection established                          # tcp连接建立
.....................
debug1: Authentication succeeded (publickey).
Authenticated to 192.168.100.101 ([192.168.100.101]:22).  # 用户认证成功
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open                  # ssh连接建立
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.         # ssh连接进程进入交互式模式


[1]+  Stopped                 ssh -vvvv 192.168.100.101

当执行远程后台任务时(加上"-f"选项):

[root@node1 ~]# ssh -vvv 192.168.100.101 -f 'sleep 50' & echo $! 
[1] 65570
65570                 # echo $!得到的上一个后台进程位65570
[root@node1 ~]# OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 56: Applying options for *
debug2: ssh_connect: needpriv 0
debug1: Connecting to 192.168.100.101 [192.168.100.101] port 22.
debug1: Connection established.        # tcp连接建立
....................................
debug1: Authentication succeeded (publickey).     # 用户认证成功
Authenticated to 192.168.100.101 ([192.168.100.101]:22).
debug2: fd 4 setting O_NONBLOCK
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open                 # ssh连接建立
debug1: Requesting no-more-sessions@openssh.com
debug1: forking to background             # 注意此处:fork一个新ssh进程到后台
debug1: Entering interactive session.     # ssh连接进程进入交互式模式
debug2: callback start
......................................

 

http://www.rwi9374.cn/
http://www.gky0942.cn/
http://www.ice7855.cn/
http://www.koi7857.cn/
http://www.dmi4893.cn/
http://www.yxp3496.cn/
http://www.xkk9615.cn/
http://www.ixa0880.cn/
http://www.gfw0394.cn/
http://www.ucl3937.cn/
http://www.eqv5313.cn/
http://www.qyd5295.cn/
http://www.mau6270.cn/
http://www.ecc2991.cn/
http://www.qdj0796.cn/
http://www.sfx6922.cn/
http://www.huh0545.cn/
http://www.kgg2505.cn/
http://www.dhg3119.cn/
http://www.azd6793.cn/
http://www.vuf7734.cn/
http://www.ums9455.cn/
http://www.dli5822.cn/
http://www.rik3314.cn/
http://www.arf0717.cn/
http://www.dsx1888.cn/
http://www.dsd3012.cn/
http://www.pur5137.cn/
http://www.fsj6077.cn/
http://www.tvz4241.cn/
http://www.qndfr.org/
http://www.zcshr.org/
http://www.fnfdf.cc/
http://www.taoshun1688.com/
http://www.unuu6393.cn/
http://www.ebll4793.cn/
http://www.wzxw0148.cn/
http://www.jknp6659.cn/
http://www.eaxv3478.cn/
http://www.enyy1947.cn/
http://www.vcqr8578.cn/
http://www.pbss8753.cn/
http://www.gwvq8861.cn/
http://www.taum0602.cn/
http://www.wuoe3708.cn/
http://www.spyb0748.cn/
http://www.jbxu3084.cn/
http://www.eami4345.cn/
http://www.zzyb6904.cn/
http://www.wead0122.cn/
http://www.iyld2675.cn/
http://www.yeex2195.cn/
http://www.fgro9441.cn/
http://www.kvvz4431.cn/
http://www.uuza3384.cn/
http://www.yyvw5376.cn/
http://www.keej8837.cn/
http://www.izpt4079.cn/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值