判断ssh远程命令是否执行结束
bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html
注:这是一个没什么鸟用的功能。不过也算是一种拓展。
通常在那些"一键化部署"的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进程中的每一个?绝大多数时候都能使用的方式是直接从$!的结果加1来判断ssh的进程号。但是极少数情况下,fork出来的进程号不一定会是加1的。如果想要无比精确的判断,我个人没有想到好方法,只能通过比较愚笨的方式来实现判断:将每个后台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
......................................
判断ssh远程命令是否执行结束的更多相关文章
- java ssh远程服务器并执行多条shell命令
java ssh远程服务器并执行多条命令 import java.io.BufferedReader; import java.io.IOException; import java.io.Input ...
- shell脚本中判断上一个命令是否执行成功
shell脚本中判断上一个命令是否执行成功 shell中使用符号“$?”来显示上一条命令执行的返回值,如果为0则代表执行成功,其他表示失败.结合if-else语句实现判断上一个命令是否执行成功. 示例 ...
- [shell]上一个命令执行完成,才执行下一个操作 | shell脚本中判断上一个命令是否执行成功
shell脚本中判断上一个命令是否执行成功 shell中使用符号“$?”来显示上一条命令执行的返回值,如果为0则代表执行成功,其他表示失败.结合if-else语句实现判断上一个命令是否执行成功. 场 ...
- Pikachu-RCE(远程命令/代码执行漏洞)
RCE(remote command/code execute)概述 RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统. 远程系统命令执行一般出现这种漏洞,是因为 ...
- 15 [网络编程]-ssh远程命令
1.执行命令os.system('ls') os.system 返回1 or 0 ,不能当做数据发送 # windows # dir 查看某个文件夹下子自文件名与子文件夹名 # ipconfig 查 ...
- ssh 远程命令
远程拷贝文件,scp -r 的常用方法: 1.使用该命令的前提条件要求目标主机已经成功安装openssh-server 如没有安装使用 sudo apt-get install openssh-ser ...
- Apache Solr 远程命令+XXE执行漏洞(CVE-2017-12629)
Apache Solr 最近有出了个漏洞预警,先复习一下之前的漏洞 命令执行 先创建一个listener,其中设置exe的值为我们想执行的命令,args的值是命令参数 POST /solr/demo/ ...
- ssh 远程执行命令 nohup 无效问题
昨夜1:00多准备睡觉了,突然一哥们咨询了我一个问题. 他A机器上远程执行B机器(ssh user@ip "command")上的脚本,B上的服务并没有起来. 看了下截图,脚本确实 ...
- linux time命令参数--执行命令并计时
[命令]time — 执行命令并计时 [格式]time [-p] command [arguments...] [说明] 执行命令行"command [arguments...]" ...
随机推荐
- Spring配置文件中如何使用外部配置文件配置数据库连接
直接在spring的配置文件中applicationContext.xml文件中配置数据库连接也可以,但是有个问题,需要在url后带着使用编码集和指定编码集,出现了如下问题,&这个符号报错-- ...
- 从源码浅析Java中的Lock和AbstractQueuedSynchronizer
在之前的文章中我也曾经介绍过Lock,像ReentrantLock(可重入锁)和ReentrantReadWriteLock(可重入读写锁),这些所我们在说的时候并没有详细的说明它们的原理,仅仅说明了 ...
- 详细分析SQL语句逻辑执行过程和相关语法
本文目录: 1.SQL语句的逻辑处理顺序 1.2 各数据库系统的语句逻辑处理顺序 1.2.1 SQL Server和Oracle的逻辑执行顺序 1.2.2 MariaDB的逻辑执行顺序 1.2.3 M ...
- NOIP2017划水崩盘记
Before-Day1 自信心爆棚,老子一定能拿省一.一天啥也没干,一顿乱奶.敬等明日切T1写暴力. Day 1 哈哈哈,T1是数论,闭眼睛切啊!! ...然后就Gg了,写的 ...
- 利用CSS3制作网页动画
如何在网页中实现动画效果动态图片 flashjavascriptcss3变形是一些效果的集合如平移 旋转 缩放 倾斜效果每个效果都可以称为变形(transfrom) 它们可以分别操控元素发生平移.旋转 ...
- OC实现单选和多选按钮
本代码库暂时有OC封装,改天有空在补一个Swift封装的,主要是因为swift不是那么熟,怕出错,半天找不到问题多尴尬呀! 先附上demo下载地址CSDN:http://download.csdn.n ...
- linux scp 命令
scp 命令 scp 命令 意思是 secure copy 即安全拷贝,可以把它看做是 cp 命令的高级版,可以跨主机拷贝. 经常用来在局域网内不同主机之间分享文件,或者在本机与远程主机中分享文件. ...
- Java基础学习笔记十九 IO
File IO概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了.那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再 ...
- JavaScript(第八天)【时间与日期】
ECMAScript提供了Date类型来处理时间和日期.Date类型内置一系列获取和设置日期时间信息的方法. 一.Date类型 ECMAScript中的Date类型是在早期Java中java.util ...
- alpha冲刺第四天
一.合照 二.项目燃尽图 三.项目进展 今天实现了登录界面和服务器的连接了,牵手成功. 一些具体的界面细化实现,一些button的响应实现 四.明日规划 登录界面和服务器的连接实现耗费了太多时间,接下 ...