open a terminal session from php - php

i'm trying to write a php page that
call for a server program like
gdb
the problem is if i did
<?php
exec(" gdb code", $out);
?>
the PHP call for the command and exist
BUT what i want to do is like open a "terminal" session
where the user enter commands in that program like
gdb code
..
break main
..
run
and after each command i give him the output and he give me the next command
and it won't work if i did it like this
<?php
exec(" gdb code", $out);
exec(" break", $out);
exec(" run", $out);
?>
and the PHP can be run from a browser
and i tried it with pro_open
<?php
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "/var/www/err.log", "a")
);
$cwd = '/var/www';
$env = array('some_option' => 'aeiou');
$StdErr='';
$process = proc_open('/bin/bash', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
fwrite($pipes[0], "gcc code ");
fwrite($pipes[0], " break main");
fflush($pipes[0]);
fclose($pipes[0]);
while(!feof($pipes[1])) {
echo fgets($pipes[1], 1024);
}
echo $StdErr;
fclose($pipes[1]);
$return_value = proc_close($process);
echo "command returned : $return_value\n";
}
and thank you .

Edit just saw you do try it from a browser. There is absolutely no simple way to do this. If you want an interactive session from the browser, you must run a separate daemon process and forward commands to it from PHP (and return output).
This is not simple at all; so if you still feel like doing this.. I would recommend starting with how to create a deamon; and then write a tcp socket server (or other IPC).
Excuse the crappy grammar

Related

Hide output from proc_open command

I habe a question. Maybe it is a beginner one, but actually I can't find a solution to my problem and I haven't worked before with this command. Maybe someone can give me a hint.
I'm using php proc_open command to run pdflatex.exe to produce a PDF file from a tex file.
The code looks like this:
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "D:/Freigabe/error.txt", "a")
);
$cwd = str_replace("\\", "/", __DIR__) .'/Tex/Working';
$env = null;
$this->execute = '"' .str_replace('/','\\',env('PDFLATEXENGINE', 'C:/Program Files (x86)/MiKTeX 2.9/miktex/bin/pdflatex.exe')) .'" -jobname="' .str_replace('.pdf','',$this->publicPdfFile) .'" -output-directory="' .str_replace("\\", "/", $this->pdfTargetPath) .'" "' .str_replace("\\", "/", str_replace(".tex","",$this->workingFilePath));
$process = proc_open('"' .$this->execute .'"', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value = proc_close($process);
}
One example of a command is this one:
$this->execute = '"D:\Program Files\TeXLive\texlive\2019\bin\win32\pdflatex.exe" -jobname="Rechnung_000036-19" -output-directory="D:/Files/Company/Tool/app/Classes/Rechnung/LaTex/Output/" "D:/Files/Company/Tool/app/Classes/Rechnung/LaTex/Output/Rechnung_FUmtC1P7lknTzvDfstMM_000036-19"';
This works fine, but the command itself produces some output when it generates the PDF file. With this code above, the output of the command is printed to my webpage and it looks like this:
I also know, why this is being printed. It is just because of this code line:
fwrite($pipes[0], '<?php print_r($_ENV); ?>');
But when I comment out the print_r() command the PDF file is no longer being produced.
I checked for a solution to supress the output of the command window. I only found > /dev/null, but this I also get not to work.
Has anyone a solution or a hint for my problem?
Many thanks in advance!
If any information is missing, please let me know. I will update the original post then.
I've found the answer. I can suppress the console output with simply adding >nul to the command. So this is my solution:
$process = proc_open('"' .$this->execute .'" >nul', $descriptorspec, $pipes, $cwd, $env);

Asynchronous call to shell_exec() php

I am running a command using shell_exec()
Let's say I have 400 directories and I can not wait for the command to run completely.
Is there a way, I can get the output Asynchronous?
$output = shell_exec('ls');
echo "<pre>$output</pre>";
$cmd = $command;
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo "<pre>";
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
flush();
}
}
echo "</pre>";
The Code above Worked perfectly for me, This is copied from another answer I can no longer find. If you put a ping 127.0.0.1 in the $command it works exactly like it does in a terminal.
Check this: Is there a way to use shell_exec without waiting for the command to complete?
And instead of redirecting to /dev/null you could redirect to a tmp file that you read later.

PHP execute Python script: provide input on prompt, read multiple outputs

I have a Python script that prompts the user for inputs.
input = raw_input("Enter input file: ")
model = raw_input("Enter model file: ")
While I can use the following PHP command to execute the script, how can I provide inputs when prompted?
$output = shell_exec("python script.py");
Also, like shell_exec(), I want to return all lines of output, not just the first/last line printed.
Solution that worked:
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open('python files/script.py', $descriptorspec, $pipes, null, null); // run script.py
if (is_resource($process)) {
fwrite($pipes[0], "files/input.txt\n"); // input 1
fwrite($pipes[0], "files/model.txt\n"); // input 2
fclose($pipes[0]); // has to be closed before reading output!
$output = "";
while (!feof($pipes[1])) {
$output .= fgets($pipes[1]);
}
fclose($pipes[1]);
proc_close($process); // stop script.py
echo ($output);
}
Reference: Piping between processes in PHP
I propose to concatenate all output lines with a delimiter character like $ and decompose it on the PHP side using explode function to have an array.

How to select user input from a shell script in PHP?

I've this shell script running from a PHP site.
In the shell script (Audit shell script),
I have 3 options:
1) Process script
2) Display results
3) Exit
Tried the codes below and doesn't seem to work, the PHP site displayed blanks.
<?php
session_start();
exec('/Desktop/test.sh');
exec('1');
$output = exec('2');
echo "<pre>$output</pre>";
?>
Any help will be greatly appreciated.
<?php
session_start();
// This line executes '/Desktop/test.sh' as if it had been called from the
// command line
// exec('/Desktop/test.sh');
// This line attempts to execute a file called '1', which would have to be
// in the same directory as this script
// exec('1');
// This line attempts to execute a file called '2', which would have to be
// in the same directory as this script, and capture the first line of the
// output in $output
// $output = exec('2');
// I think you want to be doing something more like this - this executes the
// shell script, passing "1" and "2" as arguments, and captures the whole
// output as an array in $output
exec('/Desktop/test.sh "1" "2"', $output);
// Loop the output array and echo it to the browser
echo "<pre>";
foreach ($output as $lineno => $line) echo "Line $lineno: $line\n";
echo "</pre>";
?>
It seems to me that you could do with reading the manual page for exec() properly...
Try using proc_open instead of exec; it gives you more control of process input/output. Something like:
<?php
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("file", "/dev/null", "a") // stderr is a file to write to
);
$cwd = '/Desktop';
$env = array();
$process = proc_open('/Desktop/test.sh', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
// $pipes now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
// Any error output will be sent to /dev/null (ie, discarded)
fwrite($pipes[0], "1\n");
fwrite($pipes[0], "2\n");
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
$return_value = proc_close($process);
echo $output;
}
?>
Note: I've lifted this code from the PHP Manual's proc_open page

PHP: How to get the error message of failed shell command?

I execute the following command to make a database backup:
$exec = exec("mysqldump --opt
--user=$database_user
--password=$database_pass
--host=$database_host
$database_name > $output_filename", $out, $status);
To check if mysqldump failed I do:
if ($status == 0) {
// OK
} else {
// Error
// How could I print the error message here ?
}
In case something goes wrong and mysqldump fails, how could I get the error message ?
You can use proc_open (as also suggested by Emil). below is a somewhat more complete example of how to achieve what you want.
$exec_command = "mysqldump --opt
--user=$database_user
--password=$database_pass
--host=$database_host
$database_name"
$descriptorspec = array(
0 => array("pipe", "r"), // stdin pipe
1 => array("file", $output_filename, "w"), // stdout to file
2 => array("pipe", "w") // stderr pipe
);
$proc = proc_open($exec_command, $descriptorspec, $pipes);
fwrite($pipes[0], $input); //writing to std_in
fclose($pipes[0]);
$err_string = stream_get_contents($pipes[2]); //reading from std_err
fclose($pipes[2]);
$return_val = proc_close($proc);
EDIT:
changed output to write to file
You'll need to use proc_open if you want to read stderr. The example in the manual should get you going.
If you are using shell_exec, append 2>&1 to the command, it will redirect STDERR to STDOUT.

Categories