问题
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?
回答1:
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\''");
回答2:
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.
回答3:
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
回答4:
There is a self-explaining UNIX SHELL Quote Tutorial, give it a try!
回答5:
1) Write the args to a tmp
file (this preserves the single quotes).
2)exec("/usr/bin/lftp<tmp");
来源:https://stackoverflow.com/questions/8527817/php-exec-system-or-passthru-all-remove-single-or-double-quotes