在crontab中带有-f标志的pkill不会在semi冒号之后运行命令

时间:2021-03-31 01:08:57

I wanted to kill a process and remove a flag indicating that process is running. cron:

我想要杀死一个进程并移除指示该进程正在运行的标志。cron:

00 22 * * 1-5 pkill -f script.sh >log 2>&1 ; rm lock >log 2>&1

This works perfectly when I run it on terminal. But in crontab rm is not running. All I can think of is that whole line after -f flag is being taken as arguments for pkill. Any reason why this is happening?

当我在终端上运行它时,它就能完美地工作。但是crontab rm没有运行。我所能想到的是,在-f标记之后的整个直线被当作pkill的参数。为什么会这样?

Keeping them as separate cron entries is working. Also pkill without -f flag is running (though it doesn't kill process as I want pattern to be searched in whole command).

保持它们作为单独的cron条目是有效的。另外,没有-f标志的pkill也在运行(尽管它不会杀死进程,因为我希望在整个命令中搜索pattern)。

3 个解决方案

#1


1  

the short answer: it simply killed itself!

简短的回答是:它只是自杀而已!

my answer explained: if you let a command get started by a crond it'll be executed in a subshell. most probably the line you'll find in ps or htop will look like this:

我的回答是:如果让命令由crond启动,它将在子shell中执行。很可能你在ps或htop中找到的线是这样的:

/bin/sh -c pkill -f script.sh >log 2>&1 ; rm lock >log 2>&1

(details may vary. e.g. you might have bash instead of sh)

(细节可能会有所不同。例如:you might have bash而不是sh)

the point is, that the whole line got one PID (process id) and is one of the command lines which pgrep/pkill is parsing when using the '-f' parameter. as stated in the man page:

关键是,整条线只有一个PID(进程id),是pgrep/pkill在使用“-f”参数时解析的命令行之一。如手册页所述:

-f, --full
          The pattern is normally only matched against the process name.  When -f is set, the full command line is used.

now your pkill is looking for any command line in your running process list, which somehow contains the expression 'script.sh' and eventually will find that line at some point. as a result of it's finding, it'll get that PID and terminate it. unfortunately the very same PID holds the rest of you command chain, which just got killed by it self.

现在,pkill正在运行的进程列表中寻找任何命令行,该列表以某种方式包含表达式的脚本。然后最终会在某个点找到这条线。结果是,它会得到PID并终止它。不幸的是,同样的PID控制了其他的命令链,它被它自己杀死了。

so you basically wrote a 'suicide line of commands' ;) btw: i just did the same thing today and thats how i found your question.

顺便说一句:我今天也做了同样的事情,这就是我发现你的问题的原因。

hope this answer helps, even if it comes a little late

希望这个答案能有所帮助,即使它来得有点晚

kind regards

亲切的问候

#2


1  

Ran into this problem today and just wanted to post a working example for those who run into this:

今天遇到这个问题,我想给遇到这个问题的人举个例子:

pkill -f ^'python3 /Scripts/script.py' > /dev/null 2>&1 ; python3 /Scripts/script.py > /tmp/script.log 2>&1

This runs pkill and searches the whole command (-f) that starts with (regex ^) python3 /Scripts/script.py. As such, it'll never kill itself because it does not start with that command (it starts with pkill).

这pkill和搜索整个运行命令(- f)开始(regex ^)python3 /脚本/ script.py。因此,它永远不会自杀,因为它不以该命令开始(它以pkill开始)。

#3


0  

3.141592 and nanananananananananananaBATMAN's answer is correct. I worked around this problem like this.

3.141592和南anananananananananananananabatman的答案是正确的。我解决了这个问题。

00 22 * * 1-5 pkill -f script.[s][h] >log 2>&1 ; rm lock >log 2>&1

00 22 * * 1-5 pkill -f脚本。[s][h]>日志2 > & 1;2 > & 1 rm锁>日志

This works because script.[s][h](string) is not matched with script.[s][h](regex).

这是因为脚本。[s][h](string)与脚本不匹配。[s][h](regex)。

#1


1  

the short answer: it simply killed itself!

简短的回答是:它只是自杀而已!

my answer explained: if you let a command get started by a crond it'll be executed in a subshell. most probably the line you'll find in ps or htop will look like this:

我的回答是:如果让命令由crond启动,它将在子shell中执行。很可能你在ps或htop中找到的线是这样的:

/bin/sh -c pkill -f script.sh >log 2>&1 ; rm lock >log 2>&1

(details may vary. e.g. you might have bash instead of sh)

(细节可能会有所不同。例如:you might have bash而不是sh)

the point is, that the whole line got one PID (process id) and is one of the command lines which pgrep/pkill is parsing when using the '-f' parameter. as stated in the man page:

关键是,整条线只有一个PID(进程id),是pgrep/pkill在使用“-f”参数时解析的命令行之一。如手册页所述:

-f, --full
          The pattern is normally only matched against the process name.  When -f is set, the full command line is used.

now your pkill is looking for any command line in your running process list, which somehow contains the expression 'script.sh' and eventually will find that line at some point. as a result of it's finding, it'll get that PID and terminate it. unfortunately the very same PID holds the rest of you command chain, which just got killed by it self.

现在,pkill正在运行的进程列表中寻找任何命令行,该列表以某种方式包含表达式的脚本。然后最终会在某个点找到这条线。结果是,它会得到PID并终止它。不幸的是,同样的PID控制了其他的命令链,它被它自己杀死了。

so you basically wrote a 'suicide line of commands' ;) btw: i just did the same thing today and thats how i found your question.

顺便说一句:我今天也做了同样的事情,这就是我发现你的问题的原因。

hope this answer helps, even if it comes a little late

希望这个答案能有所帮助,即使它来得有点晚

kind regards

亲切的问候

#2


1  

Ran into this problem today and just wanted to post a working example for those who run into this:

今天遇到这个问题,我想给遇到这个问题的人举个例子:

pkill -f ^'python3 /Scripts/script.py' > /dev/null 2>&1 ; python3 /Scripts/script.py > /tmp/script.log 2>&1

This runs pkill and searches the whole command (-f) that starts with (regex ^) python3 /Scripts/script.py. As such, it'll never kill itself because it does not start with that command (it starts with pkill).

这pkill和搜索整个运行命令(- f)开始(regex ^)python3 /脚本/ script.py。因此,它永远不会自杀,因为它不以该命令开始(它以pkill开始)。

#3


0  

3.141592 and nanananananananananananaBATMAN's answer is correct. I worked around this problem like this.

3.141592和南anananananananananananananabatman的答案是正确的。我解决了这个问题。

00 22 * * 1-5 pkill -f script.[s][h] >log 2>&1 ; rm lock >log 2>&1

00 22 * * 1-5 pkill -f脚本。[s][h]>日志2 > & 1;2 > & 1 rm锁>日志

This works because script.[s][h](string) is not matched with script.[s][h](regex).

这是因为脚本。[s][h](string)与脚本不匹配。[s][h](regex)。