Shell exec: примеры (PHP)
shell_exec(string command): string|false|nullФункция shell_exec в PHP выполняет переданную команду через оболочку операционной системы и возвращает весь вывод в виде строки. Она является частью группы функций для выполнения внешних программ.
Функция применяется, когда PHP-скрипту требуется взаимодействовать с системным уровнем: получить информацию о системе, выполнить обработку файлов внешними утилитами, запустить системные команды или скрипты других языков.
Функция принимает один обязательный аргумент:
- $command (string) - строка, содержащая команду для выполнения в оболочке (sh в Unix-like системах или cmd.exe в Windows).
Возвращает строку (string) с полным выводом команды или NULL в случае ошибки или если команда не произвела вывод.
<?php
$output = shell_exec('ls -la');
echo "<pre>$output</pre>";
?>total 24 drwxr-xr-x 1 user group 4096 Feb 10 10:00 . drwxr-xr-x 1 user group 4096 Feb 9 09:00 .. -rw-r--r-- 1 user group 15 Feb 10 10:00 index.php
<?php
$uptime = shell_exec('uptime');
echo $uptime;
?>10:00:00 up 1 day, 2:00, 1 user, load average: 0.05, 0.10, 0.15
<?php
$result = shell_exec('touch new_file.txt');
var_dump($result); // NULL, если файл создан успешно и команда не вывела ничего
?>NULL
- exec() - выполняет команду и возвращает последнюю строку вывода. Полный вывод можно получить в переданный по ссылке массив.
- system() - выполняет команду, выводит результат напрямую в браузер и возвращает последнюю строку.
- passthru() - выполняет команду и передает сырой вывод напрямую в браузер, полезно для бинарных данных.
- proc_open() и popen() - обеспечивают более продвинутый контроль над процессом, позволяя работать с stdin, stdout и stderr отдельно.
shell_exec удобна, когда нужен весь вывод команды в виде строки. exec() предпочтительнее, если требуется разбить вывод на строки или получить код возврата. system() и passthru() используются для немедленного вывода. Для сложных взаимодействий применяют proc_open().
Shell exec в Python
import subprocess
output = subprocess.check_output('ls -la', shell=True, text=True)
print(output)const { exec } = require('child_process');
exec('ls -la', (error, stdout, stderr) => {
console.log(stdout);
});output=$(ls -la)
echo "$output"Основное отличие PHP-функции в простоте — одна строка кода. В Python и Node.js подход более объектно-ориентированный и предоставляет детальный контроль над процессами, но требует больше кода. В bash это встроенная возможность.
<?php
$output = shell_exec('command_that_may_fail');
echo "Результат: " . $output; // Если команда не выполнится, $output будет NULL
?>Результат:
Решение: проверять возвращаемое значение.
<?php
$user_input = $_GET['file'];
// Опасность!
$output = shell_exec('cat ' . $user_input);
?>Это может привести к выполнению произвольных команд. Необходимо экранировать аргументы с помощью escapeshellarg().
<?php
$output = shell_exec('ls non_existent_file 2>&1'); // Перенаправление stderr в stdout
?>В PHP 8.0 не было внесено значительных изменений, касающихся непосредственно функции shell_exec. Однако общие изменения в языке, такие как строгая типизация, могут влиять на код, который использует результат функции.
Начиная с PHP 7.0, функция всегда возвращает строку (string) или NULL. Ранее в некоторых случаях мог возвращаться false. Рекомендуется проверять результат на NULL.
Важно учитывать настройки конфигурации safe_mode (удалена в PHP 5.4) и disable_functions, которые могут запретить использование shell_exec.
<?php
// Запуск длительной команды в фоне
$cmd = 'tar -czf backup.tar.gz /path/to/data > /tmp/log.txt 2>&1 &';
$pid = shell_exec($cmd);
echo "Процесс архивации запущен";
?><?php
// Перенаправление stderr в stdout для захвата всех сообщений
$output = shell_exec('ls non_existent_file 2>&1');
echo "<pre>$output</pre>";
?>ls: cannot access 'non_existent_file': No such file or directory
<?php
// Подсчет количества строк в выводе команды
$output = shell_exec('ps aux | wc -l');
echo "Количество процессов: $output";
?><?php
$filename = 'file; rm -rf /';
// Безопасный вариант
$safe_cmd = 'cat ' . escapeshellarg($filename);
$output = shell_exec($safe_cmd);
?><?php
// Для корректного вывода в Windows-1251
$output = shell_exec('chcp 65001 && dir');
$output = iconv('UTF-8', 'Windows-1251', $output);
echo $output;
?>