每当我尝试通过 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 是否有任何其他安全措施可能导致此问题?
最佳答案
exec()
和 system()
PHP 中的命令通过 shell 传递。 shell 解析命令行并删除引号。然而,它将整个字符串保留为一个参数,并将其铲到实际的 execve()
。系统调用等
应用程序将接收单引号中的字符串作为一个参数。然而,ps
工具可能只是按原样列出它们。
然而,lftp
工具可能会自己进行一些解析(-e
标志听起来像这样)。在这种情况下,两级引号可能会有所帮助:
exec("lftp -e '\'multiple; commands; for the lftp thingy\''");
关于PHP exec、system 或 passthru 都删除单引号或双引号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8527817/