PHP exec, system или passthru удаляют одинарные или двойные кавычки

Когда я когда-либо пытаюсь выполнить команду в оболочке через функции php exec/passthru/system, кажется, что кавычки удаляются из команды.

$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.

Безопасный режим PHP выключен

Я пробовал следующее для цитаты

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

ОБНОВИТЬ


Я хотел бы добавить это при дальнейшем тестировании. Если я создам сценарий оболочки (run_ftp.sh) и запущу его через php, он также удалит кавычки из run_ftp.sh.. так что это заставляет меня думать, что это НЕ php, вызывающий проблема.

SELinux выключен. Существуют ли какие-либо другие меры безопасности в linux/bash, которые могут вызвать это?


person Antivanity    schedule 15.12.2011    source источник
comment
Вы пробовали php.net/escapeshellarg?   -  person Paulo H.    schedule 16.12.2011
comment
Да у меня тоже не получается. Кавычки удаляются, и вместо кавычек остается \.   -  person Antivanity    schedule 16.12.2011


Ответы (5)


exec() и system()< /a> команды в PHP передаются через оболочку. Оболочка анализирует командную строку и удаляет кавычки. Однако он сохраняет всю строку как один параметр и копирует ее в фактический execve() системный вызов и т. д.

Приложение получит вашу строку, заключенную в одинарные кавычки как один параметр. Однако инструмент ps может просто перечислить их как есть.

Однако может случиться так, что инструмент lftp выполняет некоторый собственный синтаксический анализ (флажок -e звучит так). В этом случае могут помочь два уровня котировок:

exec("lftp -e '\'multiple; commands; for the lftp thingy\''");
person mario    schedule 15.12.2011
comment
В PHP нет формы, которая позволяет избежать обработки оболочки? Раковины — такие непостоянные дома для животных. - person ; 16.12.2011
comment
Нет, он вообще не имеет пользовательского ввода. - person Antivanity; 16.12.2011
comment
@pst: не в основных функциях, но я считаю, что pcntl_exec() соответствует реальному системному вызову. (Конечно, другое поведение, заменяющее текущий процесс.) - person mario; 16.12.2011
comment
Я попробовал это только сейчас, и некоторые кавычки все еще удаляются, и у меня остается ... -e \multipule; команды\... - person Antivanity; 16.12.2011
comment
@Antivanity: с этим не могу помочь. Однако это не PHP, который удаляет их. Какой тип $_SERVER["SHELL"] активен на вашем сервере? - person mario; 16.12.2011
comment
@Antivanity: Ваша проблема точно не в кавычках. Это отлично работает с bash. - person mario; 16.12.2011
comment
@mario Я знаю, что проблема не в кавычках. Он отлично работает с bash, если я запускаю его вручную, а не через php. ps faxxx Показывает команду без кавычек. Если я запущу его вручную и проверю ps faxxx, кавычки там, как и должно быть. - person Antivanity; 16.12.2011
comment
@Antivanity: тогда добавьте свою команду в сценарий оболочки (это не поможет, если на самом деле это отсутствие псевдотерминала или что-то в этом роде) или попробуйте вместо этого вышеупомянутый pcntl_exec. - person mario; 16.12.2011
comment
@mario В итоге я настроил его под cronjob, так как он так работает. Это не самый эффективный способ... но он работает. Я попробовал pcntl_exec() с теми же результатами, что и раньше. Спасибо за попытку помочь. - person Antivanity; 16.12.2011
comment
@Antivanity: только что посмотрел /etc/lftp.conf. Он, безусловно, также использует внутреннюю оболочку, которая может нарушить кавычки. Поэтому, пытаясь переопределить другой SHELL=/bin/zsh lftp ..., не уверен, что это может помочь. Но тогда другой вероятной альтернативой может быть использование lftp -f script_file мне кажется. - person mario; 16.12.2011

Кто-нибудь читал справочную страницу lftp?

В разделе "ВАРИАНТЫ" написано:

-e команды выполняет заданные команды и не выходит

-c команды выполняет заданные команды и завершает работу

Итак, ваш lftp зависает, потому что вы используете -e вместо -c.

Это не имеет ничего общего с PHP или оболочкой, удаляющей кавычки. Оболочка всегда так делает, так она работает. Вывод из PS не предназначен для копирования и вставки.

person Wolf Paul    schedule 11.07.2012

Я нашел решение, используя функцию 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: извините за мой английский

person ajaristi    schedule 13.03.2013

Существует самоочевидный учебник по UNIX SHELL Quote, попробуйте!

person Gundars Mēness    schedule 15.12.2011
comment
Я не уверен, что это поможет, так как проблема связана с php. Я могу выполнить команду через командную строку просто отлично. - person Antivanity; 16.12.2011

1) Запишите аргументы в файл tmp (при этом сохраняются одинарные кавычки).
2)exec("/usr/bin/lftp<tmp");

person Johan vdH    schedule 19.11.2018