我想启动进程(例如 myCommand)并获取其 pid(以便稍后终止它)。
我尝试了 ps 并按名称进行过滤,但无法通过名称区分进程
myCommand
ps ux | awk '/<myCommand>/ {print $2}'
因为进程名称不是唯一的。
我可以通过以下方式运行流程:
myCommand &
我发现我可以通过以下方式获取该 PID:
echo $!
有没有更简单的解决办法?
我很乐意执行myCommand并通过一行命令获取其PID。
答案1
还有什么比这更简单的呢echo $!
?就一行:
myCommand & echo $!
答案2
您可以使用sh -c
和exec
来获取命令的 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 中使用。foo
myCommand
echo $$; 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