如何获取刚启动的进程的 pid

如何获取刚启动的进程的 pid

我想启动进程(例如 myCommand)并获取其 pid(以便稍后终止它)。

我尝试了 ps 并按名称进行过滤,但无法通过名称区分进程

myCommand
ps ux | awk '/<myCommand>/ {print $2}' 

因为进程名称不是唯一的。

我可以通过以下方式运行流程:

myCommand &

我发现我可以通过以下方式获取该 PID:

echo $!

有没有更简单的解决办法?

我很乐意执行myCommand并通过一行命令获取其PID。

答案1

还有什么比这更简单的呢echo $!?就一行:

myCommand & echo $!

答案2

您可以使用sh -cexec来获取命令的 PID它运行。

要启动myCommand,以便在它开始运行之前打印它的PID,您可以使用:

sh -c 'echo $$; exec myCommand'

怎么运行的:

这将启动一个新的 shell,打印该 shell 的 PID,然后使用exec内置命令代替确保 shell 具有相同的 PID。当您的 shell 使用内置命令运行命令时exec,您的 shell 是实际上变得该命令, 而不是更常见的行为分叉出一个新的副本,该副本有自己独立的 PID,然后成为命令。

&我发现这比涉及异步执行(使用)、作业控制或使用搜索的替代方案要简单得多ps。这些方法很好,但除非您有特定的理由使用它们(例如,命令可能已经在运行,在这种情况下搜索其 PID 或使用作业控制是有意义的),否则我建议首先考虑这种方法。(我当然不会考虑编写复杂的脚本或其他程序来实现这一点)。

这个答案包括此技术的一个例子。


该命令的某些部分有时可以省略,但通常不会。

即使你使用的 shell 是 Bourne 风格的,并因此支持exec具有这些语义的内置命令,你通常也不应该试图避免使用sh -c(或等效的)来创建一个新的,分离shell 进程用于此目的,因为:

  • 一旦 shell 变成myCommand,就没有 shell 等待运行后续命令。在用 替换自身后,sh -c 'echo $$; exec myCommand; foo将无法尝试运行。除非您正在编写一个将此作为最后一条命令运行的脚本,否则您不能在运行其他命令的 shell 中使用。foomyCommandecho $$; exec myCommand
  • 您不能使用子壳为此。(echo $$; exec myCommand)可能在语法上比 更好sh -c 'echo $$; exec myCommand',但当你$$在 中运行时( ),它会给出父 shell 的 PID,而不是子 shell 本身的 PID。但子 shell 的 PID 将成为新命令的 PID。一些 shell 提供了自己的不可移植机制来查找子 shell 的 PID,你可以可以使用此方法。特别是,在 Bash 4 中(echo $BASHPID; exec myCommand)确实有效。

最后,请注意,有些 shell 会执行优化当知道 shell 之后不需要执行任何操作时,它们会像通过一样运行命令exec(即,它们首先放弃分叉)。有些 shell 会在它是最后一个要运行的命令时尝试这样做,而其他 shell 只会在命令前后没有其他命令时才这样做,而其他 shell 则根本不会这样做。结果是,如果你忘记写exec而只是使用,sh -c 'echo $$; myCommand'那么它将有时给你正确的PID一些系统一些shells。我建议不要依赖这种行为,而是始终exec在您需要时包含这些信息。

答案3

将命令包装在一个小脚本中

#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file

答案4

将 pid 注册到文件后,从 bash 脚本中使用 exec:

例子:

假设您有一个名为“forever.sh”的脚本,您想要使用参数 p1、p2、p3 运行它

forever.sh源代码:

#!/bin/sh

while [ 1 -lt 2 ] ; do
    logger "$0 running with parameters \"$@\""
    sleep 5
done

创建一个reaper.sh:

#!/bin/sh

echo $$ > /var/run/$1.pid
exec "$@"

通过reaper.sh运行forever.sh:

./reaper.sh ./forever.sh p1 p2 p3 p4 &

forever.sh 所做的只是每 5 秒向系统日志记录一行

你现在在 /var/run/forever.sh.pid 中有了 pid

cat /var/run/forever.sh.pid 
5780

并且 forever.sh 正在运行。syslog grep:

Nov 24 16:07:17 pinkpony cia: ./forever.sh running with parameters "p1 p2 p3 p4"

您可以在进程表中看到它:

ps axuwww|grep 'forever.sh p1' |grep -v grep
root      5780  0.0  0.0   4148   624 pts/7    S    16:07   0:00 /bin/sh ./forever.sh p1 p2 p3 p4

相关内容