需求:shell 脚本远程登录多台主机并kill 进程
脚本
#!/usr/bin/expect -f
password=6666
path=/app/work/aam/
topath=/app/yytester
while read -r ipline
do
expect <<EOF
spawn ssh app@${ipline}
set timeout 3
expect {
"*yes/no" {send "yes\n"; exp_continue}
"*password" {send "${password}\r"}
}
expect -re ".*\[\$#\]"
#send "whoami\r"
#send "ps -ef|grep java|grep 8406|awk '{print \$2}'|xargs kill -9\r"
#send "ps -ef|grep java|grep -v grep|grep 8406|awk '{print \$2}'|awk '{print \$2}'\r"
send "ps -ef|grep app|grep -v grep|grep 8406|awk '{print \\\$2}'|xargs kill -9\r"
expect -re ".*\[\$#\]"
send "ps -ef|grep app|grep -v grep|grep java\r"
expect -re ".*\[\$#\]"
send "exit\r"
expect eof
EOF
done < passFile
其中会遇到两个错误
问题1: can't read “2”: no such variable
#send "ps -ef|grep java|grep 8406|awk '{print \$2}'|xargs kill -9\r" 这样写会 Error : can't read “2”: no such variable
不知道原因 baidu bing 找到了一篇文章给我提示:
https://blog.csdn.net/weixin_33913332/article/details/92936868 我以转发
原因:
expect 脚本远程 kill 进程,需要对特殊字符进行转义,$2 需要 \ 转义,否则会把 2 是当作一个变量。
解决方法:
send "kill -9 `ps -ef|grep java|grep -v grep|awk '{print \$2}'`\r" 这种也是不对的 我试过还是报错 于是找来到了expect需要转义的符号列表
应该写成{print \\\$2} 这个问题解决了
expect需要转义的符号列表
\ 需转义为 \\\
} 需转义为 \}
[ 需转义为 \[
$ 需转义为 \\\$
` 需转义为 \`
" 需转义为 \\\"
引用连接:https://blog.csdn.net/secondjanuary/article/details/21775953
问题2:找不到进程
yytest>ps -ef|grep java|grep 8406|awk '{print }'|xargs kill -9
kill: can't find process "app"
kill 1: Operation not permitted
kill: can't find process "13:06"
kill: can't find process "?"
不知道原因 baidu bing 找到了一篇文章给我提示:
https://blog.csdn.net/tengdazhang770960436/java/article/details/53906263
我将两篇原文放到下边做个记录
Shell+expect 完成远程切换用户启动服务
expect 脚本:文件名:expect_ssh
bash 脚本:调用 expect 脚本,bash 文件名:bash_ssh.sh
建立 host.list 文件
使用方法:
调试中的错误:
原因:
expect 脚本远程 kill 进程,需要对特殊字符进行转义,$2 需要 \ 转义,否则会把 2 是当作一个变量。
解决方法:
转载于:https://blog.51cto.com/stuart/2089771
linux 远程杀掉进程
倾-尽 2016-12-28 10:29:38 7113 收藏
展开
第一步:获取进程号
pid=$(ssh root@$remote_host "ps -ef | grep ${tomcat_name} | grep -v grep | awk '{print $2}'"| awk '{print $2}')
1
第二步:杀掉进程
ssh root@$remote_host "kill -9 ${pid}"
1
注意:
杀掉远程进程跟杀掉本地进程不一样,杀掉本地进程只需要一句话就可以搞定了:
ps -ef | grep ${tomcat_name} | grep -v grep | awk '{print $2}'|xargs kill -9
1
但是杀掉远程的进程不一样,因为过滤的结果会被整体返回,如果在远程执行这个杀掉进程的命令:
ssh root@$remote_host "ps -ef | grep ${tomcat_name} | grep -v grep | awk '{print $2}' | xargs kill -9"
1
你会得到错误的提示:
kill process java -jar tomcat-8081
kill: can't find process "root"
kill: can't find process "09:42"
kill: can't find process "?"
kill: can't find process "00:00:44"
kill: can't find process "/opt/tools/jdk1.7.0_67/bin/java"
kill: can't find process "-Djava.util.logging.config.file=/opt/tools/tomcat-8081/conf/logging.properties"
kill: can't find process "-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
kill: can't find process "-Ddisconf.env=rd"
kill: can't find process "-Ddisconf.conf_server_host=192.168.100.15:8015"
kill: can't find process "-Ddisconf.app=ync365"
kill: can't find process "-Ddisconf.version=1.0.0"
kill: can't find process "-Ddisconf.user_define_download_dir=./classes"
kill: can't find process "-Ddisconf.enable.remote.conf=true"
kill: can't find process "-Djdk.tls.ephemeralDHKeySize=2048"
kill: can't find process "-Djava.endorsed.dirs=/opt/tools/tomcat-8081/endorsed"
kill: can't find process "-classpath"
kill: can't find process "/opt/tools/tomcat-8081/bin/bootstrap.jar:/opt/tools/tomcat-8081/bin/tomcat-juli.jar"
kill: can't find process "-Dcatalina.base=/opt/tools/tomcat-8081"
kill: can't find process "-Dcatalina.home=/opt/tools/tomcat-8081"
kill: can't find process "-Djava.io.tmpdir=/opt/tools/tomcat-8081/temp"
kill: can't find process "org.apache.catalina.startup.Bootstrap"
kill: can't find process "start"
这是因为你执行的远程命令会返回如下结果:
root 7314 1 7 09:51 pts/0 00:00:17 /opt/tools/jdk1.7.0_67/bin/java -Djava.util.logging.config.file=/opt/tools/apache-tomcat-7.0.70/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=/opt/tools/apache-tomcat-7.0.70/endorsed -classpath /opt/tools/apache-tomcat-7.0.70/bin/bootstrap.jar:/opt/tools/apache-tomcat-7.0.70/bin/tomcat-juli.jar -Dcatalina.base=/opt/tools/apache-tomcat-7.0.70 -Dcatalina.home=/opt/tools/apache-tomcat-7.0.70 -Djava.io.tmpdir=/opt/tools/apache-tomcat-7.0.70/temp org.apache.catalina.startup.Bootstrap start
1
然后 xargs kill -9 会把上面的所有的空格隔开的进程给删除一遍,实际上他们根本不是进程,只是一个进程下面返回的描述而已,我们真正需要的进程号是第二个 7314 这个进程,因此我们需要把返回的字符串再次过滤一遍,这样就能够得到真正的进程号了。
原文链接:https://blog.csdn.net/tengdazhang770960436/java/article/details/53906263