#php #bash #command-line-arguments
#php #bash #аргументы командной строки
Вопрос:
Я пытаюсь заставить PHP-программу, запускаемую веб-отправкой, указывать скрипту bash запускаться с одним параметром командной строки. Я использую анализатор командной строки shflags для bash.
Соответствующая часть PHP-скрипта выглядит следующим образом:
// generate unique filename
$destinationFolder = Mage::getBaseDir('media') . DS . 'webforms' . DS . 'xml';
$filename = $destinationFolder . DS . $result->getId().'.xml';
// create folder
if (!(@is_dir($destinationFolder) || @mkdir($destinationFolder, 0777, true))) {
throw new Exception("Unable to create directory '{$destinationFolder}'.");
}
// export to file
$xmlObject->getNode()->asNiceXml($filename);
// define parameters to pass
exec ( '/opt/bitnami/apache2/htdocs/sfb/scripts/xform.sh --xmlfile'.' '.$filename);
}
}
?>
Скрипт bash (xform.sh) (просто тестовый скрипт) заключается в следующем.
#!/bin/bash
. ./shflags
echo "foo" >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/$$".txt"
echo "foo" >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt
DEFINE_string 'xmlfilename' 'test' 'filename of current x.xml file from webforms' 'Z'
FLAGS "$@" || exit 1
eval set -- "${FLAGS_argv}"
echo "xml file was" ${FLAGS_xmlfilename} >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt
Скрипт bash корректно работает из командной строки, т.е.
$xform.sh --xmlfilename 1.xml
пишет «xml-файл был 1.xml » к foo.txt файл.
Когда PHP-скрипт запускается из Интернета, первая часть работает правильно, т. е. он записывает «foo» в два целевых файла, foo.txt и $$.txt. Однако переменная xmlfilename не отображается, и мне действительно нужно, чтобы это имя файла было передано в командную строку! (Обратите внимание, что мне не нужно использовать escapeshellarg, потому что имя файла генерируется моей PHP-программой, а не пользовательским вводом.)
Я проверил все права доступа к файлам, о которых могу вспомнить. xform.sh и shflags являются членами группы www-data (Apache), принадлежащей Apache, и a x.
Я подозреваю, что проблема связана либо с а) моим синтаксисом PHP exec, либо б) правами доступа к файлам. Все работает как задумано, за исключением бита после xform.sh в этой строке!
exec ( '/opt/bitnami/apache2/htdocs/sfb/scripts/xform.sh --xmlfile'.' '.$filename);
Обновить:
Я еще немного сузил проблему, выделив ее с помощью некоторого тестового кода. С:
$script="echo";
$xmlfilename="$filename";
$target=">> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt";
exec ("$script $xmlfilename $target");
…
PHP правильно записывает $filename в foo.txt таким образом, $script работает, когда значение равно «echo», и $filename тоже работает.
Когда я устанавливаю $script в другую простую форму скрипта xform, который (только) записывает данные в файл, это также работает правильно.
Итак, проблема конкретно в том, что происходит, когда PHP пытается записать $filename в качестве переменной командной строки. Требуется ли скрипту, запускаемому Apache, больше разрешений, чем обычно, если он включает переменную командной строки?
Вздох.
Комментарии:
1. Проверьте, что
$filename
действительно установлено на что-то в PHP. php не будет выделять / скрывать ее только потому, что вы используете ее внутри вызова exec(). Если она неправильно собрана над вызовом exec(), то exec получит «пустой» параметр, заполненный для —xmlfile.2. Я еще немного сузил проблему.
3. Apache имеет разрешения, отличные от тех, которые у вас есть в командной строке (он будет запущен как www-data или что-то еще, а не ваш идентификатор пользователя), и оболочка, запущенная из Apache, также имеет среду, отличную от обычной командной строки.
4. Исправлено! Комбинация тривиальных ошибок. Я, наконец, прибегнул к просмотру журналов ошибок PHP и Magento (следовало сделать это в первую очередь). Ошибка синтаксического анализа PHP, неожиданная T_VARIABLE = ошибка синтаксиса в строке 34 — нет ; после определения переменной $. Затем я забыл изменить путь к ./shflags на абсолютный путь. Теперь все работает как по маслу!
Ответ №1:
В вашем exec()
вызове у вас есть флаг as --xmlfile
, но вы вызываете его из командной строки как --xmlfilename
Комментарии:
1. Хороший глазомер! Однако я это исправил, и это не было проблемой.