Задача
Необходимо включить в командную строку внешние данные, например передать в программу пользовательский ввод в качестве аргумента, но для предотвращения всяких неожиданностей требуется преобразовать специальные символы в escape-последовательности.
Решение
Обработка аргументов выполняется посредством функции escapeshellarg():
system('ls -al '.escapeshellarg($directory));
А функция escapeshellcmd() применяется для обработки имен программ:
system(escapeshellcmd($ls_program).' -al');
Обсуждение
Рискованно помещать в командную строку символы, не преобразованные в escape-последовательности. Никогда не передавайте непреобразованный пользовательский ввод ни в одну из функций PHP, работающих с командной средой. Всегда преобразуйте в escape-последовательности соответствующие символы в команде и в аргументах. Это оченьважно. Не принято выполнять командные строки, поступившие из веб-форм, и мы даже в шутку не рекомендуем ничего подобного. Однако иногда требуется запустить внешнюю программу, поэтому преобразование команд и аргументов в escape-последовательности полезно.
Функция escapeshellarg() заключает аргументы в одиночные кавычки (и превращает в escape-последовательность каждую стоящую особняком одиночную кавычку). Следующий код позволяет вывести статус определенного процесса:
system('/bin/ps '.escapeshellarg($process_id));
Вызов функции escapeshellarg() гарантирует, что будет отображен соответствующий процесс, даже если он содержит неожиданные символы (например, пробел). Это также предотвращает запуск непредусмотренных команд. Если переменная $process_id содержит:
1; rm -rf /
то:
system("/bin/ps $process_id")
не только показывает статус процесса, равный 1, но также выполняет команду rm -rf /. Однако:
system('/bin/ps '.escapeshellarg($process_id))
выполняет команду /bin/ps 1; rm -rf, которая выдает ошибку, поскольку строка «1-точка с запятой-пробел-rm-пробел-дефис-rf» не является допустимым идентификатором процесса.
Точно так же, escapeshellcmd() предотвращает выполнение непредусмотренных командных строк. Этот код запускает различные программы, в зависимости от значения $which_program:
system("/usr/local/bin/formatter-$which_program");
Например, если значение переменной $which_program равно pdf 12, то сценарий запустит команду /usr/local/bin/formatter-pdf с аргументом 12.
Но если переменная $which_program равна pdf 12; 56, то сценарий запустит /usr/local/ bin/formatter-pdf с аргументом 12, а затем запустит программу 56, что является ошибкой. Чтобы успешно передать аргументы программе formatter-pdf, необходима функция escapeshellcmd():
system(escapeshellcmd("/usr/local/bin/formatter-$which_program"));
Этот код запускает программу /usr/local/bin/formatter-pdf и передает ей два аргумента – 12 и 56.