PHP exec,system或passthru都删除单引号或双引号

时间:2011-12-15 22:58:50

标签: php linux exec quote

当我尝试通过php的exec / passthru / system函数对shell执行命令时,它似乎从命令中删除了引号。

$str_file = '1323988284_700.csv';
exec("/usr/bin/lftp -e 'set ftp:passive-mode true; set ftp:ssl-protect-data yes; put /web/files/{$str_file}; bye;' -u user,pass ftp://ftp.site.com/uploaddir/");

以下是检查流程的输出

ps faxxx | grep lftp
4486 ?        S      0:00  |       \_ /usr/bin/lftp -e set ftp:passive-mode true; set ftp:ssl-protect-data yes; put /web/files/1323988284_700.csv; bye; -u user,pass ftp://ftp.site.com/uploaddir/

正如您所看到的那样,它显示了没有单引号的流程。这会导致lftp错误。

现在它只是挂起,直到我杀了它,我相信这是因为如果我将进程列表中显示的内容输入到命令中,它将会出错并将你留在lftp shell。

PHP安全模式关闭

我为报价

尝试了以下内容
\'
\\'
\\\'
\\\\'
''
'''
''''

更新


我想在进一步测试时添加它..如果我创建一个shell脚本(run_ftp.sh)并通过php运行它也会从run_ftp.sh中删除引号..所以这让我认为它不是导致问题的PHP。

SELinux已关闭.. linux / bash有没有其他可能导致此问题的安全措施?

5 个答案:

答案 0 :(得分:1)

PHP中的

exec()system()命令通过shell传递。 shell解析命令行并删除引号。然而,它将整个字符串保留为一个参数,并将其铲除到实际的execve()系统调用等。

应用程序将收到单引号中的字符串作为一个参数。然而,ps工具可能只是按原样列出它们。

然而,lftp工具可能会对其自身进行一些解析(-e标志听起来像这样)。在这种情况下,两级引用可能会有所帮助:

exec("lftp -e '\'multiple; commands; for the lftp thingy\''");

答案 1 :(得分:1)

是否有人阅读过lftp手册页?

在“选项”下说:

-e命令执行给定的命令而不退出

-c命令执行给定的命令并退出

所以你的lftp会挂起,因为你使用的是-e而不是-c。

它与PHP或shell剥离引号无关。 shell总是这样做,它是如何工作的。 PS的输出并不意味着可以复制和粘贴。

答案 2 :(得分:1)

我找到了一个使用PHP函数proc_open的解决方案。它更复杂,但对我来说很好。

$command = "lftp -u $USER,$PASSWORD -e 'get /tmp/backup-2012-08-15.zip; bye' sftp://$HOST";

$io = array();            
$p = proc_open($command,
           array(1 => array('pipe', 'w'),
                 2 => array('pipe', 'w')), $io);

/* Read output sent to stdout. */
while (!feof($io[1])) {
    echo "STDOUT: ".fgets($io[1]);
}
/* Read output sent to stderr. */
while (!feof($io[2])) {
    echo "STDERR: ".fgets($io[2]);
}

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

此代码的灵感来自于PHP SHELL工具。 PDT:对不起我的英文

答案 3 :(得分:0)

有一个自我解释的UNIX SHELL Quote Tutorial,试一试!

答案 4 :(得分:0)

1)将args写入tmp文件中(保留单引号)。
2)exec("/usr/bin/lftp<tmp");