![Shell 脚本无法帮助终止 tomcat 应用程序](https://linux22.com/image/173404/Shell%20%E8%84%9A%E6%9C%AC%E6%97%A0%E6%B3%95%E5%B8%AE%E5%8A%A9%E7%BB%88%E6%AD%A2%20tomcat%20%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F.png)
我必须复制CTRL+C
使用 shell 脚本关闭 tomcat 应用程序服务器的行为。因此在 Jenkins 管道脚本中编写了以下代码 -
sh '''pgrep -fl catalina | awk '{print $1}' | xargs kill -SIGINT'''
但它不会拒绝申请。但是,如果我从终端执行相同的命令,它会关闭应用程序 -
pgrep -fl catalina | awk '{print $1}' | xargs kill -SIGINT
您能帮助理解 shell 脚本代码有什么问题吗?
答案1
这两个命令并不相同。第一个命令尝试运行一个带有参数的脚本pgrep -fl catalina | awk {print
(} | xargs kill -SIGINT
假设$1
调用 shell 中为空)。它应该给你一个“没有这样的文件或目录”错误。它是由于引用而做到这一点的。
在 shell 中,三重单引号只是一种不方便的开始普通单引号的方式(前两个单引号将是一个空字符串)。而单引号字符串不能包含单引号。这意味着{print $1}
命令中未加引号,因此 shell 会扩展$1
(可能什么都没有),然后在 后的该空格上拆分命令print
。
要使用 运行管道sh
,请使用sh -c
:
sh -c 'sh pgrep -fl catalina | awk "{ print \$1 }" | xargs kill -SIGINT'
或者,只需使用pkill
:
pkill -f -SIGINT catalina
或者,你可以用Tomcat 的脚本shutdown.sh
,或catalina.sh stop
,或service tomcat stop
。
答案2
好吧,首先,你让事情变得不必要的复杂。
看起来您想匹配完整的命令名称“catalina”。如果是这样的话,那么我想你想使用“-x”参数。而且,如果您不使用“-l”,那么您将不会获得需要用“awk”删除的命令名称。
pgrep -x catalina
然后,您可以将“pgrep”命令插入“kill”命令行中。
sh 'kill -SIGINT `pgrep -x catalina` '
更好的是:
killall -SIGINT --exact catalina
至于为什么这在一种情况下有效而在另一种情况下不起作用,尚不清楚。也许您在 Jenkins Pipeline 上下文中以不同(非 root)用户身份运行,而在终端中以正确(或 root)用户身份运行?