我的 shell 脚本中的 pgrep:不计算脚本本身?

我的 shell 脚本中的 pgrep:不计算脚本本身?

pgrep这是我的行为自由BSD脚本:

luis@Balanceador:~/Temporal$ cat test.sh
#!/usr/bin/env bash
pgrep -fl "test.sh"

luis@Balanceador:~/Temporal$ ./test.sh
luis@Balanceador:~/Temporal$

无输出。这是:脚本本身是没有检测到作为跑步。就像 的命令行行为一样pgrep。这对我来说很好。

这就是Linux(Ubuntu)案例:

luis@Terminus:~/Temporal$ cat test.sh
#!/usr/bin/env bash
pgrep -fl "test.sh"

luis@Terminus:~/Temporal$ ./test.sh
4514 bash
luis@Terminus:~/Temporal$

可以看出,test.sh脚本本身似乎是检测到作为一个正在运行的进程。

我正在开发一个 shell (Bash)脚本那必须能够停止并等待如果另一个例子它的(同名)被检测到,并且必须在 Linux 和 FreeBSD 上工作,所以我想为此同质化 pgrep 命令。

有什么办法可以让两个人都表现得好相同

grep任何类似或接受的衍生品的答案ps

已测试

-x(确切的)开关来自手册页,但不适用于参数在脚本上(或者我不明白如何使其工作)。在这种情况下,参数对于检测并不重要(它们可以是任何参数);我只需要检测主“.sh”脚本。

进一步说明:

  • 请不要回答“使用文件锁定”之类的问题。其实我想了解一下这个pgrep工具。

答案1

FreeBSDpgrep排除了进程的祖先pgrep,包括运行它的脚本实例。 Linuxpgrep没有相应的功能。

您可以手动排除脚本实例。要排除的进程 ID 位于$$.您确实需要小心一点,避免使用任何子 shell:最简单的方法pgrep … | grep -v "^$$ "可能会列出管道的右侧(如果在调用pgrep之前恰好在进程列表中到达它)grep

instances=$(pgrep -fl "test.sh")
if [[ "$instances" =~ (.*)$'\n'"$$ "[^$'\n']*$'\n'(.*) ]]; then
  instances=${BASH_REMATCH[1]}$'\n'${BASH_REMATCH[2]}
elif [[ "$instances" =~ (^|.*$'\n')"$$ "[^$'\n']*($|$'\n'.*) ]]; then
  instances=${BASH_REMATCH[1]}${BASH_REMATCH[2]}
fi

答案2

只需添加x到标志中:

#!/usr/bin/env bash                                                                                                                                                                                                                            
pgrep -flx "pgrep.sh"

在 Ubuntu 中测试,它不会在输出中打印任何内容(如果这是你想要的!)。

相关内容