简体   繁体   English

是否可以将 CLI 命令 (exec) 的 output 捕获到 PHP 脚本变量?

[英]Is it possible to capture the output of a CLI command (exec) to a PHP script variable?

I have an external library with a bunch of executables (DCMTK).我有一个带有一堆可执行文件(DCMTK)的外部库。 Normally, those can be executed on the CLI, with output sometimes showing in the terminal.通常,这些可以在 CLI 上执行,output 有时会显示在终端中。 I want to use some of those in PHP scripts, and I was able to do that with one.我想在 PHP 脚本中使用其中的一些,我可以用一个来做到这一点。

Essentials are:要点是:

// path to the executables.

private static $dcmtk_path = '/usr/local/opt/dcmtk/bin/';

//method to execute the dcmtk executable.

public static function dcmtk_command($command) {
    //--logfile dcmlogfile.cfg
    echo exec(self::$dcmtk_path . $command); // $outputarray, 2nd arg ?
    }
}

// working example that converts a text file to a dcm worklist file

file_put_contents (self::$MWL_PATH . "samplephp.txt", $template); // text file for MWL.
echo '[{"status":"Sent to PATH"}]';
self::dcmtk_command('dump2dcm ' . self::$MWL_PATH . "samplephp.txt " . self::$MWL_PATH . "samplephp.wl");

I don't know if this is even possible.我不知道这是否可能。 But, I am uploading multiple files via a $_POST and get:但是,我通过 $_POST 上传多个文件并获得:

 $file_tmp = $files['tmp_name'];

That is saved to a path on the server:将其保存到服务器上的路径:

 $success = move_uploaded_file($file_tmp, $upload_path);

and then I want to execute another command:然后我想执行另一个命令:

self::dcmtk_command('dcmdump ' . $upload_path . $file_name );
// dcmdump +P StudyInstanceUID IM-0001-0004.dcm for specific tag

When executed from the CLI that prints out a bunch of text to the terminal (?STDOUT).当从 CLI 执行时,将一堆文本打印到终端 (?STDOUT)。 What I want to do is capture that output in the PHP script so that I can process the output.我想要做的是在 PHP 脚本中捕获 output 以便我可以处理 output。 I have tried a few things, like using an output buffer, the $outputarray from the exec command, etc.我尝试了一些方法,例如使用 output 缓冲区、exec 命令中的 $outputarray 等。

Seems like that should be possible.好像应该是可以的。 The files are getting saved on the server in the path that is configured, so they should be at $upload_path.这些文件将保存在服务器上配置的路径中,因此它们应该位于 $upload_path。 $file_name. $文件名。 And, I do not see any errors in the PHP console / error log.而且,我在 PHP 控制台/错误日志中看不到任何错误。 I actually do not have a good way to check if the command was even successful.我实际上没有很好的方法来检查命令是否成功。

Thanks again.再次感谢。 That does the trick.这就是诀窍。

$proc = proc_open($dcmtk_path . 'dcmdump +P StudyInstanceUID ' . $upload_path,[
1 => ['pipe','w'],
2 => ['pipe','w'],
],$pipes);
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
proc_close($proc);
DatabaseFactory::logVariable( $stdout);  

Can even just get a single tag if I want.如果我愿意,甚至可以只获得一个标签。 It captures that single line in a variable like:它在变量中捕获该单行,例如:

(0020,000d) UI [1.3.76.2.1.1.4.1.2.5310.511614778]      #  34, 1 StudyInstanceUID

Need some sort of function to extract the thing between the brackets:需要某种 function 来提取括号之间的内容:

This almost works:这几乎有效:

$text = '(0020,000d) UI [1.3.76.2.1.1.4.1.2.5310.511614778]      #  34, 1 StudyInstanceUID';
preg_match_all("/\[([^\]]*)\]/", $text, $match);
print_r($match);

Array
(
    [0] => Array
        (
            [0] => [1.3.76.2.1.1.4.1.2.5310.511614778]
        )

    [1] => Array
        (
            [0] => 1.3.76.2.1.1.4.1.2.5310.511614778
        )

)

As a follow up, I want a way to catch an error if the process throws an error.作为后续,我想要一种在进程抛出错误时捕获错误的方法。 I forced one, and it prints this in the output stream (not the error stream):我强迫了一个,它在 output stream 中打印出来(不是错误流):

As a follow up, is it possible catch an error thrown by the command in proc_open.作为后续,是否有可能捕获 proc_open 中的命令引发的错误。 There are cases when that might throw and error:在某些情况下可能会抛出错误:

eg I get what look like warning and errors on the CLI (intentionally made it do that).例如,我在 CLI 上得到了看起来像警告和错误的东西(故意让它这样做)。 I would like a way to catch those?我想要一种方法来抓住那些?

[07-May-2020 12:29:46 America/Cayman] [2020 年 5 月 7 日 12:29:46 美国/开曼]

W: DcmItem: Length of element (5089,474e) is odd
E: DcmElement: Unknown Tag & Data (5089,474e) larger (169478669) than remaining bytes in file
E: dcmdump: I/O suspension or premature end of stream: reading file: /Users/sscotti/Desktop/newtelerad2/dicomtemp/tattoo.dcm

It looks like maybe:看起来可能是:

proc_get_status ( resource $process ) : array can give that with the exit code:

{
    "command": ". . . .",
    "pid": 8245,
    "running": false,
    "signaled": false,
    "stopped": false,
    **"exitcode": 1,**
    "termsig": 0,
    "stopsig": 0
}

Thanks.谢谢。

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

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