当我尝试通过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有没有其他可能导致此问题的安全措施?
答案 0 :(得分:1)
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");