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

发布于 2024-12-21 14:27:59 字数 956 浏览 5 评论 0 原文

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

When ever I try to execute a command to the shell via php's exec/passthru/system functions it seems to remove quotes from the command.

$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/");

Here is the output from checking the process

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/

As you can see it's showing the process running with out the single quotes. This causes lftp to error.

Now it just hangs untill i kill it, i believe this is because if i type what is shown in the process list into the command like, it will error and leave you at the lftp shell.

PHP Safemode is OFF

I have tried the following for the quote's

\'
\\'
\\\'
\\\\'
''
'''
''''

UPDATE


I'd like to add that upon further testing.. if I create a shell script (run_ftp.sh) and run that via php it also removes the quotes from the run_ftp.sh.. so this makes me think its NOT php causing the issue.

SELinux is off.. Is there any other security measures that linux/bash has in place that could cause this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

美羊羊 2024-12-28 14:27:59

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

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

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

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

exec() and system() commands in PHP are passed over the shell. The shell parses the commandline and removes the quotes. It however keeps the whole string as one parameter, and shovels it to the actual execve() system call etc.

The application will receive your string that was in single quotes as one parameter. The ps tool however might just list them as is.

It might however be that the lftp tool does some parsing of its own (the -e flag sounds like that). In which case two levels of quotes might help:

exec("lftp -e '\'multiple; commands; for the lftp thingy\''");
挥剑断情 2024-12-28 14:27:59

有人读过 lftp 手册页吗?

它在“选项”下说:

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

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

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

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

Has anybody read the lftp man page?

It says under "OPTIONS":

-e commands      executes given commands and doesn't exit

-c commands      executes the given commands and exits

So your lftp hangs because you are using -e instead of -c.

It has nothing to do with PHP or the shell stripping out the quotes. The shell always does this, it's how it works. The output from PS is not meant to be copy-and-paste-able.

浅沫记忆 2024-12-28 14:27:59

我找到了使用 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:抱歉我的英语

I found a solution using the PHP function proc_open. It's more complex, but works fine to me.

$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);

This code was inspired in PHP SHELL tool.
PDT: Sorry by my English

夜未央樱花落 2024-12-28 14:27:59

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

There is a self-explaining UNIX SHELL Quote Tutorial, give it a try!

最终幸福 2024-12-28 14:27:59

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

1) Write the args to a tmp file (this preserves the single quotes).
2)exec("/usr/bin/lftp<tmp");

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文