2

当我尝试通过 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 是否有任何其他可能导致此问题的安全措施?

4

5 回答 5

1

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

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

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

exec("lftp -e '\'multiple; commands; for the lftp thingy\''");
于 2011-12-15T23:16:31.190 回答
1

有人读过 lftp 手册页吗?

它在“选项”下说:

-e commands 执行给定的命令并且不退出

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

因此,您的 lftp 挂起,因为您使用的是 -e 而不是 -c。

它与 PHP 或去掉引号的 shell 无关。外壳总是这样做,它就是这样工作的。PS 的输出并不意味着可以复制和粘贴。

于 2012-07-11T22:44:11.970 回答
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:对不起,我的英语

于 2013-03-13T22:07:51.590 回答
0

有一个不言自明的UNIX SHELL 报价教程,试试吧!

于 2011-12-15T23:09:38.350 回答
0

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

于 2018-11-19T07:43:27.147 回答