PHP system() 和 exec() 函数不适用于临时文件 [英] PHP system() and exec() functions not working with temp files

查看:32
本文介绍了PHP system() 和 exec() 函数不适用于临时文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 PHP 中使用 system() 函数来调用我需要使用的 CLI 程序,该程序目前在 PHP 中不可用(下面的代码).我正在使用 xml2brl (liblouisxml) CLI 生成包含盲文 ASCII 文本的输出文件.使用下面的代码,成功创建了两个文件,第一个文件成功写入了输入文本;但是,输出文件(第二个文件)永远不会将翻译后的文本写入其中.

I'm using the system() function in PHP to call a CLI program that I need to use that is not currently available from within PHP (code below). I'm using xml2brl (liblouisxml) CLI to generate an output file that contains braille ASCII text. Using the code below, the two files are successfully created, and the first file has the input text successfully written to it; however, the output file (the second file) never gets the translated text written to it.

不过,这是奇怪的部分.使用传递给 system() 的相同命令和我在 PHP 中创建的相同临时文件,我可以在终端中以我的用户身份成功运行该命令.这个问题可能是由什么引起的?当我通过 system() 运行 whoami 命令时,我得到了我的用户,并且临时文件或 CLI 命令 xml2brl.

Here's the strange part, though. Using the same command that is passed to system() and the same temp files that I create in PHP, I can successfully run the command as my user in Terminal. What could this issue be caused by? When I run whoami command through system(), I get my user, and no special permissions are required for either the temp files or the CLI command xml2brl.

目前,我正在用 PHP 创建两个临时文件:

Currently, I'm creating two temp files in PHP:

//Create the temporary files that will be passed to xml2brl
$_standardText = tempnam("~/tmp", "pll_");
$_translatedText = tempnam("~/tmp", "pll_");

临时文件存储在/private/tmp 中,并带有 pll_ 前缀,以标识 PHP 脚本正在创建的文件.

The temp files are stored in /private/tmp, and have the pll_ prefix to them, to identify the files that the PHP script is creating.

然后,我将传递的文本内容写入临时文件,如下所示:

Then, I'm writing the contents of the passed text to the temp file like this:

//Write the contents of the passed text to the temp file
$handle = fopen($_standardText, "w");
fwrite($handle, $text);
fclose($handle);

现在,位于 /private/tmp/xxxx 中的临时文件中写入了文本(已验证),然后我继续格式化命令:

Now, the temp file located in /private/tmp/xxxx has the text written in it (verified this), and then I go ahead and format the command:

$command = escapeshellcmd("xml2brl -p" . " " . $_standardText . " " .  $_translatedText);

回显 $command 变量时的格式如下:

This has the format like this when echoing the $command variable:

xml2brl -p /private/tmp/pll_MYRy9m /private/tmp/pll_DmiK7E

然后继续运行 exec 命令,它应该处理输入文件并将翻译后的文本写入输出文件,但它没有:

And go ahead and run the exec command, which should process the input file and write the translated text to the output file, but it doesn't:

exec($command);

现在,这是奇怪的部分...当我尝试只执行 ls 时,我可以从我的主目录中获取目录列表,并通过 PHP 脚本将其回显——这表明我应该有权使用 Apache 运行系统和 exec 命令,但是无论何时运行此命令,它都不起作用.但是,当我不删除临时文件,并在 CLI 中使用相同的 PHP 创建的命令(xml2brl -p/private/tmp/pll_MYRy9m/private/tmp/pll_DmiK7E)和临时文件时,我可以在我的用户下运行它们.

Now, here's the strange part... when I try to do just an ls, I can get the directory listing from my home directory and echo that out through the PHP script -- signifying that I should have access to run the system and exec commands with Apache, but whenever this command runs, it doesn't work. However, when I don't delete the temp files, and use the same PHP-created command (xml2brl -p /private/tmp/pll_MYRy9m /private/tmp/pll_DmiK7E)and temp files in the CLI, I can run them under my user.

推荐答案

你应该做的第一件事(在确保你的脚本可以运行诸如 /bin/ls 之类的简单命令之后)是完整的使用 exec() 的参数:

The first thing you should do (after making sure your script can run simple commands such as /bin/ls) is make full use of exec()'s arguments:

exec($command, $out, $code);
if ($code) {
    // an error occurred while running the command
}

其次,确保路径正确.xml2brl 可能在您的路径中,但可能不在您的脚本路径中:

Second, make sure the paths are correct. xml2brl may be in your path, but perhaps not in the path of your script:

$command = '/usr/bin/xml2brl -p ' . escapeshellarg($_standardText);

exec($command, $out, $code);
if ($code) {
    die("An error occurred while attempting torun xml2brl");
} else {
    echo "Output was: ", join("\n", $out);
}

如果还是不行,你可以重定向stderr:

If that still doesn't work, you can redirect stderr:

exec("$command 2>&1", $out, $code);

这篇关于PHP system() 和 exec() 函数不适用于临时文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆