PHP同时运行多个脚本

Lim*_* SY 5 php shell foreach exec shell-exec

我有一个像这样的对象服务器的数组:

Array
(
    [0](
                (
                    [id] => 1
                    [version] => 1
                    [server_addr] => 192.168.5.210
                    [server_name] => server1
                )
        )
    [1](
                (
                    [id] => 2
                    [server_addr] => 192.168.5.211
                    [server_name] => server2
                )
        )
)
Run Code Online (Sandbox Code Playgroud)

通过运行下面的代码,我能够获得所需的输出

foreach ($model as $server) {
        $cpu_usage = shell_exec('sudo path/to/total_cpu_usage.sh '.$server->server_addr);
        $memory_usage = shell_exec('sudo path/to/total_memory_usage.sh '.$server->server_addr);
        $disk_space = shell_exec('sudo path/to/disk_space.sh '.$server->server_addr);
        $inode_space = shell_exec('sudo path/to/inode_space.sh '.$server->server_addr);
        $network = shell_exec('sudo path/to/network.sh '.$server->server_addr);
        exec('sudo path/to/process.sh '.$server->server_addr, $processString);
        $processArray = array();
        foreach ($processString as $i) {
          $row = explode(" ", preg_replace('/\s+/', ' ', $i));
          array_push($processArray,$row);
        }
        $datetime = shell_exec('sudo path/to/datetime.sh '.$server->server_addr);
        echo $cpu_usage;
        echo $mem_usage;
        echo $disk_space;
        ......
}
Run Code Online (Sandbox Code Playgroud)

我的脚本类似于:

#!/bin/bash
if [ "$1" == "" ]
then
        echo "To start monitor, please provide the server ip:"
        read IP
else
        IP=$1
fi

ssh root@$IP "date"
Run Code Online (Sandbox Code Playgroud)

但是对于5台服务器而言,整个过程花费了10秒,而不到2秒则为1台服务器.这是为什么?反正有减少时间吗?我的猜测是,在进入下一个循环之前,exec命令正在等待输出分配给变量?我尝试谷歌一点点,但大多数答案是没有返回任何输出...我需要输出虽然

Rei*_*Rei 9

您可以同时运行脚本,popen()稍后使用获取输出fread().

//execute
foreach ($model as $server) {
    $server->handles = [
        popen('sudo path/to/total_cpu_usage.sh '.$server->server_addr, 'r'),
        popen('sudo path/to/total_memory_usage.sh '.$server->server_addr, 'r'),
        popen('sudo path/to/disk_space.sh '.$server->server_addr, 'r'),
        popen('sudo path/to/inode_space.sh '.$server->server_addr, 'r'),
        popen('sudo path/to/network.sh '.$server->server_addr, 'r'),
    ];
}

//grab and store the output, then close the handles
foreach ($model as $server) {
    $server->cpu_usage = fread($server->handles[0], 4096);
    $server->mem_usage = fread($server->handles[1], 4096);
    $server->disk_space = fread($server->handles[2], 4096);
    $server->inode_space = fread($server->handles[3], 4096);
    $server->network = fread($server->handles[4], 4096);

    foreach($server->handles as $h) pclose($h);
}

//print everything
print_r($model);
Run Code Online (Sandbox Code Playgroud)

我测试了一个类似的代码,执行5个脚本,睡眠时间为2秒,整个过程只用了2.12秒而不是10.49秒shell_exec().

更新1:非常感谢Markus AO指出优化潜力.

更新2:修改代码以消除覆盖的可能性.结果现在在里面$model.

这也可以显示哪个服务器拒绝连接,以防sshd问题影响到你.