I have a PHP file with shell commands running through a screen, the commands run fine but I was wondering if there was a way to get this to output to PHP without writing to another file and reading it on PHP's end.
PHP - trace() is just a fancy print_r()
$cmd = 'ls -h /';
trace(shell_exec('screen -S output -p 0 -X stuff "`echo '.$cmd.'\'\r\n\'`"'));
Web output
NULL
Screen output
www-data#:/home/ubuntu$ ls -h /
bin build etc initrd.img lib media opt root selinux sys usr vmlinuz
boot dev home initrd.img.old lost+found mnt proc sbin srv tmp var vmlinuz.old
Any suggestions?
--Edit--
Certain commands aren't outputting directly, one of the reasons I'm using screen
PHP
$cmd = 's3ls';
trace(shell_exec('screen -S output -p 0 -X stuff "`echo '.$cmd.'\'\r\n\'`"'));
trace(shell_exec($cmd));
Web output
trace:NULL
trace:NULL
Screen
www-data#:/home/ubuntu$ s3ls
+---------------+--------------------------+
| Name | CreationDate |
+---------------+--------------------------+
| bucket | 2012-05-31T13:08:51.000Z |
| bucket | 2012-01-17T16:51:58.000Z |
| bucket | 2012-03-31T11:19:54.000Z |
+---------------+--------------------------+
void passthru ( string $command [, int &$return_var ] )
The passthru() function is similar to the exec() function in that it
executes a command. This function should be used in place of exec() or
system() when the output from the Unix command is binary data which
needs to be passed directly back to the browser. A common use for this
is to execute something like the pbmplus utilities that can output an
image stream directly. By setting the Content-type to image/gif and
then calling a pbmplus program to output a gif, you can create PHP
scripts that output images directly.
Though apparently it may be a bit flaky.
Related
Prokka is a tool used to annotate bacterial genomes and can be installed and access using the command line in the local system or server.
So, I have downloaded Prokka using Git clone (git clone https://github.com/tseemann/prokka.git) and complied it on the CentOS (7) server along with all the dependencies with the latest version (NCBI-BLAST 2.10.1, hmmer 3.3, gnu Parallel).
In order to make a prediction server, I have created a webpage using PHP, and in that PHP file, I'm taking input from the user and passing that input to a shell file, and trying to execute that shell file using the shell_exec() function.
Here $fileName and $fn are the input from taken from the webpage.
$output = shell_exec("./path/to/shell/file/invoke.sh $script_path/$fileName $fn");
echo "<pre>$output</pre>";
invoke.sh file:
input_genome="$1";
prefix_genome="$2";
/path/to/prokka/bin/prokka $input_genome --outdir ./results/"$prefix_genome" --prefix $prefix_genome --locustag $prefix_genome --cpus 8 --kingdom Bacteria
Now, if I'm invoking Prokka (/path/to/prokka/bin/prokka) directly from the command line it's working fine and create all the files which ideally it should create. Moreover, if I'm running the shell script (invoke.sh) to invoke the Prokka (/path/to/prokka/bin/prokka) it's again working fine and generate all the files.
Expected and actual output files:
seq.faa
seq.err
seq.fna
seq.txt
seq.ffn
seq.gff
seq.tsv
seq.fsa
seq.gbk
seq.tbl
seq.log
seq.sqn
But the problem is while I'm running the PHP file from the web-browser as mentioned above to run the shell file (invoke.sh) it is running, but the Prokka command is not running properly inside the shell file and therefore not generating all of the output files.
I checked the error_log it showed me this:
[23:43:57] Will use blast to search against /home/group01/html/csspred/prokka/db/kingdom/Bacteria/sprot with 8 CPUs
[23:43:57] Running: cat \/home\/group01\/html\/csspred\/results\/01\-Nov\-23_43_779958414\/seq\/seq\.sprot\.tmp\.18401\.faa | parallel --gnu --plain -j 8 --block 3279 --recstart '>' --pipe blastp -query - -db /home/group01/html/csspred/prokka/db/kingdom/Bacteria/sprot -evalue 1e-09 -qcov_hsp_perc 80 -num_threads 1 -num_descriptions 1 -num_alignments 1 -seg no > \/home\/group01\/html\/csspred\/results\/01\-Nov\-23_43_779958414\/seq\/seq\.sprot\.tmp\.18401\.blast 2> /dev/null
[23:44:00] Could not run command: cat \/home\/group01\/html\/csspred\/results\/01\-Nov\-23_43_779958414\/seq\/seq\.sprot\.tmp\.18401\.faa | parallel --gnu --plain -j 8 --block 3279 --recstart '>' --pipe blastp -query - -db /home/group01/html/csspred/prokka/db/kingdom/Bacteria/sprot -evalue 1e-09 -qcov_hsp_perc 80 -num_threads 1 -num_descriptions 1 -num_alignments 1 -seg no > \/home\/group01\/html\/csspred\/results\/01\-Nov\-23_43_779958414\/seq\/seq\.sprot\.tmp\.18401\.blast 2> /dev/null
and generated only four files :
seq.HAMAP.hmm.tmp.12617.faa
seq.HAMAP.hmm.tmp.12617.hmmer3
seq.fna
seq.log
I even used a C file to invoke the execute a shell file which ultimately invokes the Prokka command but again the problem remained the same.
PHP: $output = shell_exec("./invoke.out $script_path/$fileName $fn");
C:
`int main(int argc, char *argv[])
{
char command[1000];
sprintf(command, "%s %s %s", "sh /home/group01/html/csspred/scripts/CSS_pred_new_additions/prokka_test.sh", argv[1], argv[2]);
system(command);
}`
What is the problem and how to solve this? I just wanted to execute my invoke.sh or invoke.out so that at the backend my Prokka command will be able to run correctly and gives me all expected output files.
Hi i have a Linux command what uses a pipe to obtain its result. It basically search a pdf for a string and returns the page numbers of all of the occurrences.
pdftotext /var/www/html/custom/test.pdf - | awk -vRS=$'\\f' -vNAME='06/1133/13' \ 'index($0,NAME){printf \"%d,\", NR}'
The result of this on the command line looks like this:
8,9,10,11,
Trying to run this in php with this code
$command = "pdftotext /var/www/html/custom/test.pdf - | awk -vRS=$'\\f' -vNAME='06/1133/13' \ 'index($0,NAME){printf \"%d,\", NR}'";
echo shell_exec($command);
i get the following output
1,
I have used the php script to print out the command variable to make sure the formatting is correct. I can run the output command on the terminal and this works with out issue.
What is needed within the PHP script to allow this to run?
I wrote a very convoluted, very hackjob PHP-cli script that receives and parses JSON of changeable structure, depth and content. For that reason at that time I found it easiest to do the parsing using PHP's shell_exec() and cat | jq | grep.
Sometimes, rarely, on certain input it gives me the message Error: writing output failed: Broken pipe, which is the last message I see in cli output before the script dies. However, even when it does do that, the data is still parsed out correctly, for all the little good it does me.
I isolated the problematic piece of code to:
$jq1='cat '.$randfile.' | jq \'.\' | grep "\[" -m 1 | grep -Po --color=none "\w{3,15}"';
$jq1=trim(shell_exec($jq1));
And tried to debug it by seeing what it executes. The first line is the shell_exec argument, echoed before execution, the second line is the result of shell_exec.
Command: cat 5ca15f21.json | jq '.' | grep "\[" -m 1 | grep -Po --color=none "\w{3,15}";
Result: standalone
Command: cat 5ca59379.json | jq '.' | grep "\[" -m 1 | grep -Po --color=none "\w{3,15}";
Result: season
Error: writing output failed: Broken pipe
Command: cat 5ca7d271.json | jq '.' | grep "\[" -m 1 | grep -Po --color=none "\w{3,15}";
Result: extended
Command: cat 5ca7d7a8.json | jq '.' | grep "\[" -m 1 | grep -Po --color=none "\w{3,15}";
Result: season
(I have seen the error of my lazy ways and will be rewriting that whole section, but back then I was young and inexperienced and impatient. I'd still like to understand what's going wrong where why.)
What would make it do that sometimes? The input is always jq's pretty-printed JSON, of varying structure.
Even if it does get the broken pipe message, the necessary value is still parsed out and stored in the variable. What causes it to die then? I would like to know for the future if there's a way to make PHP disregard the [non-fatal] error and go on executing.
Why does the shell command that produces the broken pipe error message in shell_exec behave no differently when invoked manually in bash? Where is the broken pipe and what makes it so broken?
Edit:
The cat command could be eliminated if this is a bash command to be executed. I would write it like this.
$jq1=grep -Po --color=none "\w{3,15}"|"\[" -m 1 file.txt | jq \'.\';
$jq1=trim(shell_exec($jq1));
I combined your redundant grep commands and added file to the grep command and only piped the jq command.
I'm developping a PHP-FPM driven module in which in upload videos, then transcode them into several HTML5 formats in the background with ffmpeg. This PHP-FPM script runs under a specific, non-root UID, called tv25.
There is a variant in which I record a webcam stream through a Streaming Server (Wowza), which runs under the root UID, and launches the conversion through Java-written module.
In order to know the status of the processes I make a GET request to a script which runs the following function :
function is_conversion_running($base_file_name) {
$command = "sudo ps aux | grep {$base_file_name} | grep -v grep | wc -l";
$lignes = shell_exec($command);
return (bool) $lignes;
}
When I call this function through AJAX, it works for the PHP-FPM variant (the UID is the same, returns true while the conversion is running), but not with the Wowza variant (return false everytime).
The strange thing is that if I run the command in a shell, with the non-root UID, it works like a charm, since the ps command as been allowed to be run by this UID.
The problem seems similar to the one in shell_exec returns empty string, but the solution listed there doesn't work for me.
My /etc/sudoers line is like this :
tv25 ALL = (root) NOPASSWD: /bin/ps
Really can't figure out what is the deal...
What does the command return: 0 or NULL? In the second case the command probably failed alltogether. You can check with the exec function whether you get a non-zero exit code. Make sure to prefix your command with /bin/sh -c in that case.
PS: Do you really need the sudo for running ps? Normally you get all processes even without sudo.
Well I found another way to sikve my problem : since I want to know if the process is still running, I delegated the command in a shell script :
#!/bin/bash
BASE_NAME=`basename $0`
LIGNES=$(/usr/bin/sudo /bin/ps aux | grep "$1" | grep -v grep | grep -v $BASE_NAME | wc -l)
[ $LIGNES -eq "0" ] && exit 1
exit 0
And then I call it with passthru. Its return value parameter is then converted to boolean, negated, and returned by the function.
~
I have again another trouble with using exec in php
my os is suse linux and I am using php 5.1.2
Somehow my output is being trimmed when i use exec()
in linux
~ -> ps -ef | grep java
root 3548 1 0 Aug05 ? 00:00:01 /usr/java/jdk1.5.0_13//bin/java -server -Djava.awt.headless=true -Xms512m -Xmx512m -XX:NewSize=224m -XX:MaxNewSize=256m -XX:SurvivorRatio=8 -XX:+UseParallelGC -jar /jfe-server.jar start
psinl 14811 1 0 09:12 ? 00:00:01 /usr/java/jdk1.5.0_13//bin/java -server -Djava.awt.headless=true -Xms512m -Xmx512m -XX:NewSize=224m -XX:MaxNewSize=256m -XX:SurvivorRatio=8 -XX:+UseParallelGC -jar jfe-server.jar start
psinl 18164 18080 0 16:20 pts/1 00:00:00 grep java
but when output to web via
<div>Checking whether JFEServer has been started</div>
<div><pre><?php exec('ps -ef | grep java',$output,$result);
print_r($output); ?></pre>
</div>
</br>
And my output on the web
Checking whether JFEServer has been started
Array
(
[0] => root 3548 1 0 Aug05 ? 00:00:01 /usr/java/jdk1.5.0_13//bin/java
[1] => psinl 14811 1 0 09:13 ? 00:00:01 /usr/java/jdk1.5.0_13//bin/java
[2] => psinl 18069 14271 0 16:20 ? 00:00:00 sh -c ps -ef | grep java
[3] => psinl 18071 18069 0 16:20 ? 00:00:00 grep java
)
Why is that php has automatically trimmed off my output even I didnt want it to?
This is because PHP just doesn't can't allocate a large enough buffer for you to use with exec. Your best bet is to add a step in between: pipe the output to a temporary file in your exec() call
example: exec('ps -ef | grep java > /tmp/mytmpfilename.txt')
...then dump that out to the screen with a call to file_get_contents()
example: var_dump(file_get_contents('/tmp/mytmpfilename.txt'));
edit: Alternatively, you can use file() if there is a LOT data to output, like several thousand lines worth.
You could use passthru, which passes the output of a command directly to the clients browser.
<div>Checking whether JFEServer has been started</div>
<div><pre><?php passthru( 'ps -ef | grep java', $result ); ?></pre></div>
<br />
If that doesn't help, you should look into the documentation of ps, if it tests the standard output terminal type (e.g. file/pipe/terminal). If it does so, it could be trimming it to some default width if it can't determine the actual terminal width. On my debian based server it does. The correct command on my machine is:
<div>Checking whether JFEServer has been started</div>
<div><pre><?php passthru( 'ps -efww | grep java', $result ); ?></pre></div>
<br />
I had to add the -w flag to double my ps output on Centos 6.2. Of course, this only is necessary sometimes, specifically in a session run from a script.
In a TTY session, ps will not trim the output, but in other circumstances (depending on the TERM variable, it will. You can also explicitly set it to unlimited by adding -ww.
ps man pages were the key for me on this one.
php did not trim you output, the browser did. check the original output by Right click -> View Page Source on browser.