我有一个像这样的 makefile,它会杀死一个正在运行的进程,
test: client server
pgrep myserver && killall myserver
/build/bin/myserver --background
/build/bin/myclient --server 127.0.0.1
如果我myserver
之前已经开始,它就会起作用。如果不是,pgrep myserver
则会以非零状态失败,并且 Makefile 将其视为错误,例如
pgrep myserver && killall myserver
make: *** [test] Error 1
有什么建议么?
答案1
不要killall
与结合pgrep
。它们不使用相同的匹配规则,因此pgrep
显示的内容可能并不killall
致命。使用pkill
,与 完全相同,pgrep
只是它会杀死匹配的进程而不是显示其 PID。请注意,如果同时调用pgrep
和pkill
,则会出现竞争条件:在运行时pkill
, 所示的某些进程pgrep
可能已终止,而一些新进程可能已启动。除非您关心进程 ID,否则调用pgrep
;是没有意义的。你可以直接打电话pkill
。
pkill
如果没有找到任何要终止的进程,则返回状态 1。要么-
在命令的开头添加,告诉 make 忽略此错误,要么将命令更改为pkill myserver || true
执行完全相同的操作pkill myserver
但始终返回成功状态。
test: client server
pkill myserver || true
/build/bin/myserver --background
/build/bin/myclient --server 127.0.0.1
答案2
您需要||true
确保第一个命令始终返回成功。
pgrep
您可以通过丢弃 stderr 来避免这种需要;例如
test: client server
killall myserver 2>/dev/null || true
myserver --background
myclient --server 127.0.0.1
答案3
如果您需要忽略命令的结果制作,你应该-
像这样使用运算符:
test: client server
-pkill -f myserver
myserver --background
myclient --server 127.0.0.1
这边走制作会知道你不在乎是否pkill
失败,并且不必使用||
不必要的东西。
您还可以避免打印命令和输出,如下@-
所示:
test: client server
@-pkill -f myserver
myserver --background
myclient --server 127.0.0.1