Chinaunix
标题:
关于bash代码传参的问题
[打印本页]
作者:
jiaxinhuayuan
时间:
2016-06-22 14:44
标题:
关于bash代码传参的问题
本帖最后由 jiaxinhuayuan 于 2016-06-22 14:45 编辑
想写一个shell脚本自动杀掉tomcat进程,使用了下面代码:
pid=`ps aux|grep $1|grep -v "grep"|awk '{print $2}'`
kill -9 $pid
其中$1是传入的tomcat进程关键字,发现$1可以传入,但是pid获取有错,求助这样的需求应该如何实现?
需求:tomcat进程名是传入的,不可能写死,根据这个杀掉对应的进程。谢谢各位!
作者:
Shell_HAT
时间:
2016-06-22 15:01
ps aux|grep $1|grep -v "grep"
ps aux|grep $1|grep -v "grep"|awk '{print $2}'
把这两个命令的结果分别发出来,看看是哪一步出问题了。
作者:
hz_oracle
时间:
2016-06-22 15:11
$1是外部传入的?不需要吧,你直接抓tomcat进程,然后取pid不行吗?
作者:
jiaxinhuayuan
时间:
2016-06-22 15:17
脚本是这样写的:
#/bin/bash
echo $1
pid=`ps aux|grep $1|grep -v "grep"|awk '{print $2}'`
echo $pid
kill -9 $pid
命令执行是:bash -x test.sh tomcat
结果是:
+ echo tomcat
tomcat
++ ps aux
++ grep tomcat
++ grep -v grep
++ awk '{print $2}'
+ pid='23180
23069
23181'
+ echo 23180 23069 23181
23180 23069 23181
+ kill -9 23180 23069 23181
Killed: 9
如果换成:ps aux|grep $1|grep -v "grep"的话结果是这样的:
+ echo tomcat
tomcat
++ ps aux
++ grep tomcat
++ grep -v grep
pid='*** 23189 0.0 0.0 2443624 520 s003 S+ 3:14下午 0:00.00 bash -x test.sh tomcat
之类的,后面还有很多。
PS:如果不传参数,直接在终端执行
ps aux |grep "tomcat" |grep -v "grep" |awk '{print $2}'
是可以的。
求解
回复
2#
Shell_HAT
作者:
jiaxinhuayuan
时间:
2016-06-22 15:19
这样的话可能有多个tomcat进程了,会误杀掉别的,我需要只杀掉我想杀的,比如"tomcat-ship"这样就只有一个了
回复
3#
hz_oracle
作者:
jiaxinhuayuan
时间:
2016-06-22 15:20
所以需要外部传入的
回复
3#
hz_oracle
作者:
hz_oracle
时间:
2016-06-22 15:26
回复
5#
jiaxinhuayuan
那是你定位不准确啊。你要杀掉tomcat-ship为啥传参数传的是tomcat?
作者:
jiaxinhuayuan
时间:
2016-06-22 15:27
我是举个例子,实际上我传tomcat这个参数已经唯一确定了
回复
7#
hz_oracle
作者:
jiaxinhuayuan
时间:
2016-06-22 15:28
但有的时候当然不是喽,所以这个地方需要外部传入,保证唯一性
回复
7#
hz_oracle
作者:
hz_oracle
时间:
2016-06-22 15:31
回复
9#
jiaxinhuayuan
不清楚你想表达什么意思。 你要kill掉tomcat-ship 那传入参数就写tomcat-ship啊。。否则你怎么保证抓到的pid唯一性?
作者:
jiaxinhuayuan
时间:
2016-06-22 15:33
你可以按照我写的那个代码试一下,我的意思是即使传入的是tomcat-ship,也是报一样的错误,换句话说我的意思是我传入的参数已经保证唯一pid了,但是执行还是错误
回复
10#
hz_oracle
作者:
hz_oracle
时间:
2016-06-22 15:38
回复
11#
jiaxinhuayuan
这个问题好像我之前遇到过,你不要grep,用其他命令取pid试试
作者:
riet2
时间:
2016-06-22 16:25
话说你到底报的啥错。
作者:
seanking1987
时间:
2016-06-22 16:54
看了帖子的所有回复,LZ描述的不清楚啊。
LZ回复中给的例子pid是grep到了多个造成的执行错误,然而后面又说带入的参数,grep是能够保证唯一性的?
那么现在脚本执行的问题到底是什么?
作者:
jiaxinhuayuan
时间:
2016-06-22 17:52
本帖最后由 jiaxinhuayuan 于 2016-06-22 17:53 编辑
需求比较清晰简单,就是传入参数,这个参数就是进程名,根据这个参数找到对应的进程,然后杀掉,怎么实现?
回复
14#
seanking1987
作者:
seanking1987
时间:
2016-06-23 08:53
本帖最后由 seanking1987 于 2016-06-23 08:56 编辑
回复
15#
jiaxinhuayuan
试了一把shell,知道你的意思,我想LZ应该把出现的问题描述的更清楚一些。
系统只启了一个tomcat进程,shell代码:
#!/bin/bash
proName=$1
pid=`ps aux|grep ${proName}|grep -v "grep"|awk '{print $0}'`
echo "$pid
复制代码
运行结果:
user 27193 0.0 29.8 552492 308864 ? Sl May13 30:27 tomcat/org.apache.catalina.startup.Bootstrap start
user1 30401 0.0 0.1 5204 1060 pts/1 S+ 08:53 0:00 sh test1.sh tomcat
user1 30402 0.0 0.0 5204 464 pts/1 R+ 08:53 0:00 sh test1.sh tomcat
复制代码
全部打印出来就发现问题,3个pid包含了shell运行的pid,那么脚本改造一下:
#!/bin/bash
proName=$1
shellName=$0
pid=`ps aux|grep ${proName}|grep -v "grep"|grep -v "$shellName"|awk '{print $0}'`
echo "$pid"
复制代码
运行结果:
user 27193 0.0 29.8 552492 308864 ? Sl May13 30:27 tomcat/org.apache.catalina.startup.Bootstrap start
复制代码
此时得到的结果是正确的
作者:
251744647
时间:
2016-06-23 10:54
本帖最后由 251744647 于 2016-06-23 10:56 编辑
这样要保证shell文件名最好不要带数字,tomcat等字样.比如你shell file 名字为tomcat这样,grep -v tomcat, 连tomcat的进程都过滤掉了,结果返回为空。名字不用数字的道理是一样的,进程ID嘛。
回复
16#
seanking1987
作者:
seanking1987
时间:
2016-06-23 10:59
回复
17#
251744647
你说的没错。目前属于能解决问题,并非“完美”解决问题。在shell脚本的命名上,仍应注意你说的注意点。
等待大神来给个“完美”的方法吧,我是抛砖引玉~~
作者:
251744647
时间:
2016-06-23 11:07
pidof running program 即可。
man pidof
NAME
pidof -- find the process ID of a running program.
SYNOPSIS
pidof [-s] [-c] [-n] [-x] [-m] [-o omitpid[,omitpid..]] [-o omitpid[,omitpid..]..]
program [program..]
作者:
251744647
时间:
2016-06-23 11:15
another way is using sub-shell
[root@xxx]# cat filehh
#!/bin/bash
pid=(`ps -ef |grep $1|grep -v "grep"|awk '{print $2}'`)
echo "the first parameter is $1, the second parameter is $2"
echo "pid is $pid"
echo "-----------------------------"
ps -ef |grep $1|grep -v "grep"|grep -v $0|awk '{print $2}'
[root@xxx]# ps -ef |grep test11 |grep -v "grep" |awk '{print $2}'
42884
[root@xxx]# bash filehh test11
the first parameter is test11, the second parameter is
pid is 42884
-----------------------------
42884
[root@joey-compute azureuser]#
回复
15#
jiaxinhuayuan
pid=(`ps -ef |grep $1|grep -v "grep"|awk '{print $2}'`)
作者:
woid31846
时间:
2016-06-24 08:51
kill -9 "$pid" 就可以了. 不然你PID匹配到了多个.
要不然就改成
ps aux|grep $1|grep -v "grep"|awk '{print $2}'|xargs kill -9
作者:
ll104567
时间:
2016-06-24 09:17
seanking1987 发表于 2016-06-23 08:53
回复 15# jiaxinhuayuan
结合16楼的想法,用grep过滤的时候排除脚本名字`basename $0`、然后再用kill杀就行了
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2