简体   繁体   English

从 PHP 调用外部 shell 脚本并获取其进程 ID

[英]Invoke external shell script from PHP and get its process ID

如何从 PHP 本身调用外部 shell 脚本(或者外部 PHP 脚本)并在同一脚本中获取其进程 ID?

$command =  'yourcommand' . ' > /dev/null 2>&1 & echo $!; ';

$pid = exec($command, $output);

var_dump($pid);

If you want to do this strictly using tools PHP gives you, rather than Unix-specific wizardry , you can do so with proc_open and proc_get_status , although the need to pass a descriptor spec into proc_open makes it unpleasantly verbose to use:如果您想严格使用 PHP 提供的工具而不是特定Unix 的proc_open来执行此操作, proc_open可以使用proc_openproc_get_status来执行此proc_get_status ,尽管需要将描述符规范传递给proc_open使其使用起来令人不快:

<?php

$descriptorspec = [
    0 => ['pipe', 'r'],
    1 => ['pipe', 'w'],
    2 => ['pipe', 'w']
];
$proc = proc_open('yourcommand', $descriptorspec, $pipes);
$proc_details = proc_get_status($proc);
$pid = $proc_details['pid'];

echo $pid;

For a cross-platform solution, check out symfony/process .对于跨平台解决方案,请查看symfony/process

use Symfony\Component\Process\Process;
$process = new Process('sleep 100');
$process->start();
var_dump($process->getPid());

After you install symfony/process with composer ( composer require symfony/process ), you may need to update autoloading info with composer dump-autoload and then require the autoload with require __DIR__ . '/vendor/autoload.php';使用 composer 安装symfony/process后( composer require symfony/process ),您可能需要使用composer dump-autoload更新自动加载信息,然后使用require __DIR__ . '/vendor/autoload.php';要求自动加载require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/vendor/autoload.php'; . .

Notice also that you can get PID of a running process only.另请注意,您只能获取正在运行的进程的 PID。 Refer to the documentation for API details.有关 API 详细信息,请参阅文档

What ended up working for me is using pgrep to get the PID of the command (or process name) executed after calling exec() in PHP.最终对我pgrep是使用pgrep来获取在 PHP 中调用exec()后执行的命令(或进程名称)的 PI​​D。

exec($command);
$pid = exec("pgrep $command");

This will work for launching background processes too.这也适用于启动后台进程。 However, you must remember to pipe the program's output to /dev/null or else PHP will hang.但是,您必须记住将程序的输出通过管道传送到/dev/null否则 PHP 将挂起。 Also, when calling pgrep you can't include the pipe portion of the command:此外,在调用pgrep您不能包含命令的管道部分:

$command = "bg_process -o someOption";
exec($command + " > /dev/null &"); //Separate the pipe and '&' from the command
$pid = exec("pgrep $command");

Note that if the system has multiple processes launched with the same exact command, it will return the PIDs of all processes which match the command given to pgrep .请注意,如果系统使用相同的确切命令启动了多个进程,它将返回与提供给pgrep的命令匹配的所有进程的 PID。 If you only pass in a process name, it will return all PIDs with that process name.如果您只传入进程名称,它将返回具有该进程名称的所有 PID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM