Получить ресурс процесса по PID
Я хочу написать веб-консоль SSH, и я нашел две проблемы.
Что я хочу сделать. Сначала я хочу выполнить start.php
файл, который имеет следующий код.
$process = proc_open('start', array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "a")
), $pipes);
Во вторых я хочу бежать command.php
файл, который запускает команду для созданного процесса в start.php
файл и получить результаты от него.
$pid = 12345;
print_r(process_command('ping google.com', $pid));
Я просто хочу получить доступ к процессу (cmd
) созданный в прошлом, отправьте ему команду и получите результат.
Почему это проблема, если я могу создать новый процесс для каждого command.php
исполнение? Поскольку новый процесс - новая сессия, Если я войду в MySQL в прошлом command.php
выполнение, в следующих выполнениях я должен войти в MySQL снова, потому что новый процесс не помнит, что я был зарегистрирован.
Пример на windows.
- Я создаю новый процесс (
cmd
) в PHP мой текущий каталогC:\WebServ\
,
- я пишу
cd /
команда, мой текущий каталогC:\
,
Это всего лишь пример, я не хочу только менять каталог, это не проблема для меня.
Проблема в том, как создать один процесс и получить к нему доступ в следующих исполнениях PHP-файла - если я хочу запомнить mysql
сеанс например?
- Я могу создать процесс путем
proc_open
функция. - Я могу получить PID по
get_process_status
, но как получить ресурс процесса, созданный до выполнения текущего файла PHP?
И следующий вопрос, как написать новую команду для созданного процесса, если возможен доступ к созданному процессу в прошлом?
Я не хочу использовать расширения PHP. Но если это требуется в этом случае, каждый ответ поможет мне.
Если доступ к процессу, созданному в других исполнениях PHP, невозможен, я хочу использовать while(1)
контролировать созданный процесс в начале выполнения PHP - но я надеюсь, что это не требуется в этом случае. Тогда я надеюсь, что кто-нибудь знает, как написать новую команду для созданного cmd
процесс.
Если решение моего вопроса - проблема, я приму ответ, который скажет мне, как отправлять команды cmd.exe
процесс открыт shell_exec
и как получить ответ на каждую команду.
3 ответа
Как насчет этого очень наивного * подхода:
1) Ваш start.php
скрипт будет опрашивать файловый ресурс, например /tmp/commands.in
для входящих команд. Конечно, скрипт может делать это только до тех пор, пока ваши настройки PHP max_execution_time
разрешений, поэтому обязательно позвоните set_time_limit(0);
снять лимит. Если команда найдена в файле, сценарий выполнит ее через канал процесса cmd
или же bash
или что-то используется в качестве оболочки и записать вывод /tmp/commands.out
,
2) Ваш command.php
затем будет писать команды /tmp/commands.in
и прочитайте содержание /tmp/commands.out
и отобразить его в браузере.
*) Наивный, потому что параллелизм, безопасность и, вероятно, множество других проблем явно связаны с этим подходом. Таким образом, эти проблемы должны решаться с помощью блокировок файлов, списков ACL и так далее.
proc_open()
возвращает тип ресурса. Ресурсы нельзя сериализовать, поэтому вы не сможете сохранить их на потом. Они освобождаются в конце выполнения вашего скрипта, за исключением постоянных соединений с базой данных.
Я думаю, я понимаю, что вы спрашиваете сейчас. Попробуй это:
<?php
$fd = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("file", "error.txt", "a") // stderr
);
$process = proc_open("cmd.exe", $fd, $pipes);
echo "Welcome to this interactive CMD shell. Please type your commands below\n";
while(is_resource($process) {
$input = readline(); //Get user input
$input .= "\n"; //Need newline to press ENTER on CMD
if($input == "exit\n") {
fwrite($pipes[0], $input);
break; //End BOTH this program AND cmd
}
fwrite($pipes[0], $input);
}
fclose($pipes[0]);
echo file_get_stream($pipes[1]); //print all the output from CMD
//Cleanup
fclose($pipes[2]);
proc_close($process); //Should already be closed!
Обратите внимание, что вы не можете получить данные от дочернего элемента, пока не закроете его STDIN ($pipe [0]).... Это означает, что вы не можете получить выходные данные дочернего элемента, пока не закончите отправлять ему команды.