标签: proc-open

如何获得proc_open()的输出

我试图从proc_openphp中获取方法的输出,但是,当我打印它时,我变空了.

$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("file", "files/temp/error-output.txt", "a")
);

$process = proc_open("time ./a  a.out", $descriptorspec, $pipes, $cwd);

只要我知道,我可以得到输出 stream_get_contents()

echo stream_get_contents($pipes[1]);
fclose($pipes[1]);

但我不能这样做......有什么建议吗?

先谢谢......

php linux proc-open

11
推荐指数
2
解决办法
2万
查看次数

在PHP中正确执行shell

问题

我正在使用一个proc_open()用来调用shell命令的函数.看起来我在做STDIO的方式是错误的,有时导致PHP或目标命令锁定.这是原始代码:

function execute($cmd, $stdin=null){
    $proc=proc_open($cmd,array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w')),$pipes);
    fwrite($pipes[0],$stdin);                fclose($pipes[0]);
    $stdout=stream_get_contents($pipes[1]);  fclose($pipes[1]);
    $stderr=stream_get_contents($pipes[2]);  fclose($pipes[2]);
    return array( 'stdout'=>$stdout, 'stderr'=>$stderr, 'return'=>proc_close($proc) );
}
Run Code Online (Sandbox Code Playgroud)

大部分时间都有效,但这还不够,我想让它始终有效.

stream_get_contents()如果STDIO缓冲区超过4k的数据,则问题在于锁定.

测试用例

function out($data){
    file_put_contents('php://stdout',$data);
}
function err($data){
    file_put_contents('php://stderr',$data);
}
if(isset($argc)){
    // RUN CLI TESTCASE
    out(str_repeat('o',1030);
    err(str_repeat('e',1030);
    out(str_repeat('O',1030);
    err(str_repeat('E',1030);
    die(128); // to test return error code
}else{
    // RUN EXECUTION TEST CASE
    $res=execute('php -f '.escapeshellarg(__FILE__));
}
Run Code Online (Sandbox Code Playgroud)

我们输出一个字符串两次到STDERR和STDOUT,总长度为4120字节(超过4k).这会导致PHP双方都锁定.

显然,stream_select()是要走的路.我有以下代码:

function execute($cmd,$stdin=null,$timeout=20000){
    $proc=proc_open($cmd,array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w')),$pipes);
    $write  = array($pipes[0]);
    $read   = array($pipes[1], $pipes[2]);
    $except = null;
    $stdout …
Run Code Online (Sandbox Code Playgroud)

php proc-open k2f

9
推荐指数
1
解决办法
9523
查看次数

为什么在将4096个字节写入以proc_open开头的进程后,PHP挂起?

对于任何想知道的人来说,在离开它几个小时之后它现在完美无缺.

我正在尝试使用PHP将视频文件传递给VLC作为即将推出的项目提案的概念证明.

我设法通过创建一个<4KB(灰色10秒)文件并测试我的脚本来显示它的工作原理,但我很好奇为什么会发生这种情况的原因.

这是一个示例脚本,看看我的意思:

$filepath = 'Path/to/your/video';
$vlcpath = 'Path/to/your/VLC executable';

$descriptorspec = array(
    0 => array("pipe", "r"),  // stdin
    1 => array("pipe", "w"),  // stdout
    2 => array("pipe", "w")   // stderr
);

$vlc = proc_open($vlcpath . ' -', $descriptorspec, $pipes, null, null, ['bypass_shell' => true]);

$file = fopen($filepath, 'r');
stream_copy_to_stream($file, $pipes[0]);
fclose($file);
proc_close($vlc);
Run Code Online (Sandbox Code Playgroud)

我在Windows 10上使用PHP 5.5.31.我在PHP网站上看到了一些有关此类事情的错误报告,但他们建议最新版本修复它.我不太了解阻塞流的概念,但我已经尝试过PHP v7.0.3无济于事.

我正在使用命令行运行此脚本: php file.php

php stdin vlc proc-open

9
推荐指数
1
解决办法
367
查看次数

PHP proc_open多次打开

我有一个实用程序函数用于通过CLI(cmd,bash等)执行程序.它返回的3项的数组:STDOUT,STDERREXIT CODE.

到目前为止,它一直很好地没有问题.事实上,我遇到的问题并没有真正阻碍它的功能,但我关注的是性能.

问题是在某些情况下,PHP会多次运行相同的命令(在我的情况下是3次),即使它只应该执行一次.

/**
 * Executes a program and waits for it to finish, taking pipes into account.
 * @param string $cmd Command line to execute, including any arguments.
 * @param string $input Data for standard input.
 * @param boolean $log Whether to log execution failures or not (defaults to true).
 * @return array Array of "stdout", "stderr" and "return".
 */
public static function execute($cmd,$stdin=null,$log=true){
    //static $once=true; if(!$once)die; $once=false;
    $proc=proc_open($cmd, array(
        0=>array('pipe','r'),
        1=>array('pipe','w'), …
Run Code Online (Sandbox Code Playgroud)

php windows proc-open command-line-interface k2f

8
推荐指数
1
解决办法
1369
查看次数

fclose():18不是有效的流资源

我正在尝试使用proc_open执行一个进程.管道处理过程的I/O !!

$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("pipe", "w")
);
Run Code Online (Sandbox Code Playgroud)

现在,实际上,我打开的"c程序"有时会卡住,我添加了一个max_time_limit检查,强制关闭进程.我已经添加了回调函数 - 即onExit - (使用"call_user_function"),以便以有效方式或强制方式处理"进程退出"时的信息.

在"退出"功能中,我正在关闭i/o管道

 foreach ($pipes as $pipe) {
    fclose($pipe);
 }
Run Code Online (Sandbox Code Playgroud)

如果进程有一个有效的退出,上面的工作完全正常.但是,在我强行杀死我的进程的情况下,我调用proc_terminate来执行此操作.我知道进程的终止也会继续并关闭所有I/O管道,但问题是由于回调,我的"onExit"函数进程总是被调用(这就是我希望它的方式.. .as我需要做更多的处理).现在,在这种情况下,当我尝试关闭管道时,我收到以下错误:

fclose(): 18 is not a valid stream resource 
Run Code Online (Sandbox Code Playgroud)

我尝试使用"ftell"来检查管道是否有效,但是这也是错误的.如何检查管道是否已经关闭?

php proc-open kill-process fclose

7
推荐指数
1
解决办法
1万
查看次数

使用proc_open时从STDIN管道读取

我正在尝试创建一个人们可以在线编译和运行代码的网站,因此我们需要找到一种用户发送指令的交互方式.

实际上,首先想到的是exec()或者system(),但是当用户想要输入时,这种方式将不起作用.所以我们必须使用proc_open().

例如,以下代码

int main()
{
    int a;
    printf("please input a integer\n");
    scanf("%d", &a);
    printf("Hello World %d!\n", a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我使用时proc_open(),就像这样

$descriptorspec = array(      
0 => array( 'pipe' , 'r' ) ,  
    1 => array( 'pipe' , 'w' ) ,  
    2 => array( 'file' , 'errors' , 'w' ) 
);  
$run_string = "cd ".$addr_base."; ./a.out 2>&1";
$process = proc_open($run_string, $descriptorspec, $pipes);
if (is_resource($process)) {
    //echo fgets($pipes[1])."<br/>";
    fwrite($pipes[0], '12');
    fclose($pipes[0]);
    while (!feof($pipes[1])) …
Run Code Online (Sandbox Code Playgroud)

php proc-open

7
推荐指数
1
解决办法
5995
查看次数

如何使用PHP生成并发进程?

I'm trying to spawn multiple processes at once in PHP with proc_open, but the second call won't start until the first process has ended. Here's the code I'm using:

for ($i = 0; $i < 2; $i++)
{
    $cmdline = "sleep 5";
    print $cmdline . "\n";
    $descriptors = array(0 => array('file', '/dev/null', 'r'), 
                         1 => array('file', '/dev/null', 'w'), 
                         2 => array('file', '/dev/null', 'w'));
    $proc = proc_open($cmdline, $descriptors, $pipes);
    print "opened\n";
}
Run Code Online (Sandbox Code Playgroud)

php proc-open

6
推荐指数
1
解决办法
2157
查看次数

PHP proc_open将无法正常工作 - 给我"数组中缺少句柄限定符"

警告:proc_open():在第102行的C:\ ...\updatedots.php中缺少数组中的句柄限定符

我试图打开记事本,关闭它2秒后.这是我的代码:

$descriptorspec = array(
    0 => array("pipe" => "r"),
    1 => array("pipe" => "w"),
    2 => array("file" => "logs/errors.txt")
);

// Create child and start process
$child = array("process" => null, "pipes" => array());
$child["process"] = proc_open("notepad.exe > nul 2>&1", $descriptorspec, $child["pipes"]);
Run Code Online (Sandbox Code Playgroud)

知道这个错误意味着什么,是什么原因引起的?

php windows xampp proc-open

6
推荐指数
1
解决办法
2453
查看次数

使用PHP的proc_open + bypass_shell在后台运行可执行文件并检索正确的PID?

因此,在PHP在Windows上:是否有可能都在后台运行的可执行文件检索它的PID?我已经推断出可以单独完成这两项任务,但不能同时完成.

背景过程

要对通过SHELL启动的进程进行后台处理,'start /B "bg" myprog.exe'必须使用该命令,并且必须立即关闭SHELL进程.

要做到这一点,许多人都这样使用pclose( popen( ... ) ),pclose( popen( 'start /B "bg" myprog.exe', 'r') );但据我所知,pid使用popen时无法检索.

因为pid使用popen 是不可能的,所以我们必须看看proc_open.

获得PID

使用proc_open我们可以检索exe的pid当且仅当if bypass_shell设置为true.

如果bypass_shell设置为false(默认值),Windows将返回pidSHELL的内容.有关详细信息,请参阅:https://bugs.php.net/bug.php?id = 41052

问题解释

start /B传递给proc_open时,当命令失败bypass_shell = true,因为它跳过了SHELL和发送命令行参数直接MYPROG.EXE不知道他们做什么.

相反,如果bypass_shell = false(默认)和proc_close用于立即关闭SHELL,myprog.exe在后台运行就像使用pclose( popen( ... ) )BUT 时返回错误 pid(我们得到pid了SHELL).

那么,背景+正确的pid检索是否可行? …

php windows background pid proc-open

6
推荐指数
1
解决办法
3326
查看次数

proc_open:扩展文件描述符编号以启用Perl脚本的"状态"反馈

PHP的proc_open手册说明:

文件描述符编号不限于0,1和2 - 您可以指定任何有效的文件描述符编号,并将其传递给子进程.这允许您的脚本与作为"协同进程"运行的其他脚本进行互操作.特别是,这对于以更安全的方式将密码短语传递给PGP,GPG和openssl等程序非常有用.它对于读取这些程序在辅助文件描述符上提供的状态信息也很有用.

发生了什么: 我在基于PHP的Web应用程序中调用Perl脚本并在调用中传递参数.我将来不需要将数据发送到脚本.通过stdout [1]我收到了我在PHP应用程序中使用的Perl脚本json_encoded数据.

我想补充的内容: Perl脚本正在通过网站收集信息,具体取决于其初始调用中传递的参数.我想将一个文本字符串发送回PHP应用程序,我可以将其用作一种进度条显示.

我认为我应该这样做:我希望(每1-2秒)轮询一次为"进展"更新设置的频道.我会使用Javascript/jQuery写入一个html div容器供用户查看.我不认为我应该将"进度"通道与更关键的"json_encode(数据)"通道混合,因为我需要解密stdout流.(这个想法合乎逻辑,实用吗?)

我的主要问题: 你如何使用额外的"文件描述符?" 我想将其他通道的设置想象得很简单,比如下面的3 => ...:

$tunnels = array(   
   0 => array('pipe', 'r'),     
   1 => array('pipe', 'w'),    
   2 => array('pipe', 'w'),    
   3 => array('pipe', 'w')        
);

$io = array();
$resource = proc_open("perl file/tomy/perl/code.pl $param1 $param2 $param3", $tunnels, $io);

if(!is_resource($resource)) {
    $error = "No Resource";
}

fclose($io[0]);

$perlOutput = stream_get_contents($io[1]);
$output = json_decode($perlOutput);

$errors = stream_get_contents($io[2]);
print "$errors<p>";

fclose($io[1]);
fclose($io[2]);

$result = …
Run Code Online (Sandbox Code Playgroud)

php perl proc-open

6
推荐指数
1
解决办法
849
查看次数