问题
I want to write web SSH console, and i found two problems.
What i want to do. First I want to execute start.php
file which have following code.
$process = proc_open('start', array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "a")
), $pipes);
Second i want to run command.php
file which run command on created process in start.php
file and get results from it.
$pid = 12345;
print_r(process_command('ping google.com', $pid));
I just want to access process (cmd
) created in past, send command to it and get result.
Why this is problem, if i can create new process for each command.php
execution? Because new process is new session, If i login to mysql in past command.php
execution, in next executions i must login to mysql again, because new process not remember i was logged.
Example on windows.
- I create new process (
cmd
) in PHP, my current directory isC:\WebServ\
.
- I write
cd /
command, my current directory isC:\
.
This is just example, i dont want only change directory, this is not problem for me.
Problem is how to create one process and access to it in next PHP file executions - if i want remember mysql
session for example?
- I can create process by
proc_open
function. - I can get PID by
get_process_status
, but how to get process resource created before current PHP file was executed?
And next question, how to write new command to created process, if accessing to created process in past is possible?
I dont want use PHP extensions. But if this is required in this case, each answer will help me.
If access to process created in other PHP executions is not possible, i want use while(1)
to control created process at begin of PHP execution - but i hope this is not required in this case.
Then I hope anyone know, how to write new command to created cmd
process.
If solution for my question is problem, i will accept answer which tell me how to send commands to cmd.exe
process opened by shell_exec
, and how to receive response for each command.
回答1:
proc_open()
returns a resource type. Resources cannot be serialized so you cannot save it for later. They are freed at the end of your script execution with the exception of persistent database connections.
回答2:
What about this very naive* approach:
1) Your start.php
script would poll a file resource, e.g. /tmp/commands.in
for incoming commands. Of course, the script could only do this as long as your PHP setting max_execution_time
permits so be sure to call set_time_limit(0);
to remove the limit. If a command is found in the file, the script would execute it through its process pipe to cmd
or bash
or whatever is being used as the shell and write the output to /tmp/commands.out
.
2) Your command.php
would then write commands to /tmp/commands.in
and read the content of /tmp/commands.out
and display it in the browser.
*) Naive because concurrency, security and probably a lot other issues come obviously with this approach. So these issues must be dealt with by using file locks, ACLs and so on.
回答3:
I think I understand what you are asking now. Try this:
<?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!
Note, you cannot get data from the child until you close its STDIN ($pipes[0]).... Meaning you cannot get the child's output until you finish sending it commands.
来源:https://stackoverflow.com/questions/29088760/get-process-resource-by-pid