如何获取在 Perl 脚本中执行的程序的 PID
How to get the PID of a program executed within a Perl script
This answer 解释了在使用 Perl 的 exec()
时如何获取新进程的 pid。 pid 甚至没有改变,所以您需要做的就是获取原始脚本的 pid。但如果我将输出重定向到一个文件作为命令的一部分,它就不起作用,这是我需要做的。
say "my pid is $$";
exec("childscript.pl"); # same pid
但是如果我将输出重定向为命令的一部分:
say "my pid is $$";
exec("childscript.pl > log.txt"); # different pid, usually old pid + 1
exec("childscript.pl > log.txt 2>&1 &"); # same
那么新的pid比旧的pid大一(这可能只是因为它们是连续产生的,不可靠)。我通过查看输出和将 sleep 30
插入 "childscript.pl" 来测试它,这样我就可以用 ps -e
.
看到它
我的猜测是重定向输出会导致新进程进行写入。但是我需要程序的 pid,除了我可以执行它之外,我无法控制程序。 (它也需要在后台 运行。)
当你用一个参数调用 exec
时(那个参数包含 shell 个元字符),perl 会自动为你运行 sh -c ARG
。在你的情况下:
exec("childscript.pl > log.txt");
# really means:
exec("/bin/sh", "-c", "childscript.pl > log.txt");
即您的脚本将 sh
加载到当前 运行 进程中,并保留其 PID。 shell 执行输出重定向,然后运行 childscript.pl
作为子进程(使用新的 PID)。
有两种方法可以解决这个问题:
在 Perl 中进行输出重定向并且不生成 shell:
open STDOUT, ">", "log.txt" or die "[=11=]: log.txt: $!\n";
exec "childscript.pl";
die "[=11=]: childscript.pl: $!\n";
告诉 shell 也使用 exec
而不是生成子进程:
exec "exec childscript.pl > log.txt";
die "[=12=]: childscript.pl: $!\n";
This answer 解释了在使用 Perl 的 exec()
时如何获取新进程的 pid。 pid 甚至没有改变,所以您需要做的就是获取原始脚本的 pid。但如果我将输出重定向到一个文件作为命令的一部分,它就不起作用,这是我需要做的。
say "my pid is $$";
exec("childscript.pl"); # same pid
但是如果我将输出重定向为命令的一部分:
say "my pid is $$";
exec("childscript.pl > log.txt"); # different pid, usually old pid + 1
exec("childscript.pl > log.txt 2>&1 &"); # same
那么新的pid比旧的pid大一(这可能只是因为它们是连续产生的,不可靠)。我通过查看输出和将 sleep 30
插入 "childscript.pl" 来测试它,这样我就可以用 ps -e
.
我的猜测是重定向输出会导致新进程进行写入。但是我需要程序的 pid,除了我可以执行它之外,我无法控制程序。 (它也需要在后台 运行。)
当你用一个参数调用 exec
时(那个参数包含 shell 个元字符),perl 会自动为你运行 sh -c ARG
。在你的情况下:
exec("childscript.pl > log.txt");
# really means:
exec("/bin/sh", "-c", "childscript.pl > log.txt");
即您的脚本将 sh
加载到当前 运行 进程中,并保留其 PID。 shell 执行输出重定向,然后运行 childscript.pl
作为子进程(使用新的 PID)。
有两种方法可以解决这个问题:
在 Perl 中进行输出重定向并且不生成 shell:
open STDOUT, ">", "log.txt" or die "[=11=]: log.txt: $!\n"; exec "childscript.pl"; die "[=11=]: childscript.pl: $!\n";
告诉 shell 也使用
exec
而不是生成子进程:exec "exec childscript.pl > log.txt"; die "[=12=]: childscript.pl: $!\n";