Shell_exec giving different outputs with identical input - php

I'm trying to return the content of a folder in a Linux enviroment.
To do this I run the code below:
//this line returns folders and files from current folder
$reg = shell_exec ("ls -A");
//in this line I just try to show the info with the desired structure.
$reg = "stat --printf='%n|%s|%s|%F|%y|%a' ".$reg." | numfmt --to=iec-i --field=2 --delimiter='|' --suffix=B";
//This prints the content of $reg
echo $reg;
//I manually input the string returned by $reg and I receive the correct output
echo shell_exec ("stat --printf='%n|%s|%s|%F|%y|%a' .file1 file2 | numfmt --to=iec-i --field=2 --delimiter='|' --suffix=B");
//This just prints the result of "stat --printf='%n|%s|%s|%F|%y|%a' .file1"
echo shell_exec ($reg);
The problem is that the two last "echo" instructions return different outputs given (in theory) identical inputs.
How can I solve this?

When ls detects that it's being piped into another command it writes one file per line, screwing up your command.
You could either replace them with spaces
$reg= str_replace("\n", " ", shell_exec("ls -A"));
or use ls as a substitution
$reg = "stat --printf='%n|%s|%s|%F|%y|%a' $(ls -A) | numfmt --to=iec-i --field=2 --delimiter='|' --suffix=B";

Related

Assign awk to variables in php

I have the following code in place. It provides the information needed, however I would like to assign the output to variables.
$cmd = "ssh machine 'cat /usr/local/reports/file.dat | awk -F'[[:space:]][[:space:]][[:space:]]*' '{print \"<tr><td>\"$2\"</td><td>\"$3\"</td></tr>\"}'";
system($cmd);
This correctly runs and produces a table with the 2nd and 3rd columns from the file. However, I would now like to assign the columns to variables for each line read in the file.
Any ideas?
system always outputs the command output directly. You could use output buffering to capture it, but you should use shell_exec instead:
$result = shell_exec( $cmd );
Few suggestions:
Use heredoc to make reader friendly
avoid cat /usr/local/reports/file, awk can read file directly, there is no need of using cat command
if you want take care of return status use exec() function.
shell_exec() returns all of the output stream as a string. exec returns the last line of the output by default, but can provide all output as an array specifed as the second parameter.
Here is code snippet
<?php
$cmd =<<<EOF
ssh user#host "awk -F'[[:space:]][[:space:]][[:space:]]*' '{
print \"<tr><td>\" $2 \"</td><td>\" $3 \"</td></tr>\"
}
' /usr/local/reports/file.dat 2>&1"
EOF;
/*
execute command in 1st argument,
save output in array in 2nd argument
store status in 3rd argument
*/
exec($cmd, $out, $return);
if($return==0)
{
print_r($out);
/* your case you can just
echo implode(PHP_EOL, $out);
*/
}else{
/* Failed to execute command
do some error handling */
die( 'Failed to execute command : '. $cmd );
}
?>

How to execute C code through PHP by prompting terminal

I have a C code that I have to execute through PHP,
I have used exec('./sys'), sys is my executable file.
I have also tried system(), passthrough(), shell_exec() and they are not giving output.
When I executed exec('who'); it gives the output.
What can I do to execute sys?
Each of those methods you reference will execute your sys file, but you need to make sure you are executing the correct path. Your working path is determined by what script is actually executing PHP. For example, if you're executing your code through apache or the command line your working directory may be different. Lets assume this file structure:
+ src/
| + script.php
| + sys
I would recommend using PHP's __DIR__ magic variable in your script.php to always reference the current file's directory, and then work from there:
// script.php
exec(__DIR__ . "/sys");
Retrieving output can be done a couple different ways. If you want to store the output of the script in a variable, I would recommend using exec according the the manual:
Parameters ΒΆ
command
The command that will be executed.
output
If the output argument is present, then the specified array will be filled with every line of output from the command. Trailing whitespace, such as \n, is not included in this array. Note that if the array already contains some elements, exec() will append to the end of the array. If you do not want the function to append elements, call unset() on the array before passing it to exec().
return_var
If the return_var argument is present along with the output argument, then the return status of the executed command will be written to this variable.
exec will return the first line of output, but if you want more than that you need to pass a variable by reference:
// script.php
$output = array();
exec(__DIR__ . "/sys", $output);
$output will then contain an array of each line of output from the command. However if you want to run your sys script and directly pass through the output then use passthru(__DIR__ . "/sys"); For example, if you wanted to execute a command that required input on the command line, passthru would be the best option.

result of php loop not passing to shell script

I have a small foreach loop in php but the results will not pass to a shell script. see below:
$contents = file("$target_dir/$user.temp.txt");
foreach($contents as $line) {
echo $line . "<br />";
exec("sh read.sh $line >> tempfile");
}
the echo statement works just fine and displays the data to screen as it should. however the result of $line does not make it to the shell script, but when I replace $line with a random string it does. here is the shell script:
#!/bin/bash
#test script
echo "test output: $1"
when trying to call the shell script with $line in place, the tempfile will get created but is blank. all my permissions are set to 777 and the group calling the script is the same owner as the folder. I've reviewed other posts about php loops but dont seem to find anything that matches exactly what my issue is.
Thanks in advance for any insight.
Needed to add single quotes to $line.
exec("sh read.sh '$line' >> tempfile");

PHP system() keeps echo even though

So I need to found out if an upload from a user is images/ video and what type. I currently use
"filetype"=>system("file -i -b ".$_FILES['file']['tmp_name'])
which is inserted into my MongoDB collection via this
$s3file='http://'.$bucket.'.s3.amazonaws.com/'.$actual_image_name;
$collection = static::db()->media;
$datetime = time();
$mediaupload = array("owner"=>$_SESSION['user_information'][0]['_id'],"filelink"=>$s3file,"filetype"=>system("file -i -b ".$_FILES['file']['tmp_name']),"filesize"=>$size,"uploadtime"=>$datetime,"ownerid"=>$_SESSION["user_information"][0]['_id']);
$collection->insert($mediaupload);
$media = $collection->findOne($mediaupload);
However what I am noticing is it echos the result out to the PHP page - which is not what I need it to do. i know it is the system function because when I remove that function it does not echo the uploaded file type to the php code.
I am wondering therefor how can i still run that system file -i -b function and get it to include into the MongoDB database but not echo the result into the public php page return.
Try something like (for multi-line output)
exec("file -i -b ".$_FILES['file']['tmp_name'], $output);
array("filetype"=>$output);
It may look a little unorthodox, but exec uses its second input parameter as a way to pass the output information back to you - the output of file will be stored as an array into $output.
From the docs:
If the output argument is present, then the specified array will be
filled with every line of output from the command. Trailing
whitespace, such as \n, is not included in this array. Note that if
the array already contains some elements, exec() will append to the
end of the array. If you do not want the function to append elements,
call unset() on the array before passing it to exec().
If you simply want the first line from the output, use the simpler version:
array("filetype"=>exec("file -i -b ".$_FILES['file']['tmp_name']));
I have switched the system to exec() and that seems to of fixed my issue

system() function in PHP prints variable 2 times

Stupid question, this code:
<?php
$variable = system("cat /home/maxor/test.txt");
echo $variable;
?>
with file test.txt:
blah
prints:
blah
blah
What can I do with system() function to not print nothing so I get 1 "blah"???
system displays whatever the program outputs and returns the last line of output.
exec displays nothing and returns the last line of output.
passthru displays whatever the program outputs and returns nothing.
Use exec instead of system
http://us.php.net/manual/en/function.system.php#94262
According to the manual -- see system() :
system() is just like the C version
of the function in that it executes
the given command and outputs the
result.
Which explains the first blah
And :
Returns the last line of the command
output on success
And you are echoing the returned value -- which explains the second blah.
If you want to execute a command, and get the full output to a variable, you should take a look at exec, or shell_exec.
The first one will get you all the lines of the output to an array (see the second paramater) ; and the second one will get you the full output as a string.
Use exec instead. To get all the output, rather than just the last line do this:
$variable = array();
$lastline = exec("cat /home/maxor/test.txt", $variable);
echo implode("\n", $variable);
system is calling the actual cat program, which is outputting "blah" from test.txt. It also returns the value back to $variable which you're then printing out again.
Use exec or shell_exec instead of system.

Categories