php shell_exec() interpolation - php

I have a php script that builds a dynamic command string (calls a perl script), then executes the command, like this:
$cmd_string = "perl $pushFile";
foreach($cmd_args AS $argName => $arg){
$cmd_string .= ' --' . $argName . '="' . $arg . '"';
}
$output = shell_exec('export PERL5LIB=/mnt/path/to/custom:$PERL5LIB && ' . $cmd_string . ' 2>&1');
I am getting failures that I think are being caused by interpolation of some of the arguments. For example is one of the arguments is '246+8GT>-', it gets turned into '246 8GT ' and an error that the string is unterminated. But, if I print_r $cmd_string to the screen and execute it via command line, or copy/paste it into the $cmd_string variable, it executes properly. I am stumped. How can I make sure these arguments are being passed properly? I tried this:
$output = shell_exec('export PERL5LIB=/mnt/path/to/custom:$PERL5LIB && ' . escapeshellcmd($cmd_string) . ' 2>&1');
but get the same result. Help?

You are escaping the comamand string, after it has been built.
Try this:
$cmd_string = "perl $pushFile";
foreach($cmd_args AS $argName => $arg){
$cmd_string .= ' --' . $argName . '="' . escapeshellarg($arg) . '"';
}
$output = shell_exec('export PERL5LIB=/mnt/path/to/custom:$PERL5LIB && ' . $cmd_string . ' 2>&1');

Related

Exec Command is not working in sql server

I am working on database migration. I have written a code for executing the command that retrieves the data from database and pushes into a csv file. This Works fine in MySQL but when I try to do the same in SQL Server it does not work. Infact when I copy paste the same command into command prompt it works fine. I double checked everything. I do not understand why its not working. It returns blank output. I have already tried many of the solutions provided before. None works. Any help on this is most appreciated.
Here is the code I am using:
//$sqlsrv is used to determine the database server type
$str_query = voc_get_query_string($query);
$output_uri = 'temporary://' . user_password();
$file_path = drupal_realpath($output_uri . '.csv');
if($sqlsrv){
$exec_path = drupal_realpath('private://Binn\sqlcmd');
}else{
$exec_path = drupal_realpath('private://mysql');
}
$sql_uri = 'temporary://' . user_password();
$sql_path = drupal_realpath($sql_uri);
$fp = fopen($sql_path, 'w');
fputs($fp, $str_query);
fclose($fp);
global $databases;
if ($sqlsrv) {
$cmd = ($exec_path .
' -S ' . $databases['default']['default']['host'] .
' -d ' . $databases['default']['default']['database'] .
' -U ' . $databases['default']['default']['username'] .
' -P ' . $databases['default']['default']['password'] .
' -i ' . $sql_path . '>>'. $file_path .
' -s '. '"," -W -m10 -r1');
}
else {
$cmd = ($exec_path . ' ' . $databases['default']['default']
['database'] .
' -h ' . $databases['default']['default']['host'] .
' -u ' . $databases['default']['default']['username'] .
' -p ' . $databases['default']['default']['password'] . ' < '
. $sql_path .
' > ' . $file_path);
}
exec($cmd);
watchdog('cmd', var_export($cmd, TRUE));

Concatenate a string after variable in PHP

I want to concatenate string after variable in PHP. dot operator is not working.
foreach ($get_cont as $line)
{
#var_dump($line);
if (strpos($line, "a href"))
{
#echo "$line";
$get_core++;
if ($get_core == 3)
{
#echo $line;
break 1;
}
}
}
#echo $line;
$array = explode(' ', $line);
$core = $array[count($array) - 1];
$core = substr_replace($core, "", -1);
$cmd = "cmd /c curl http://" . $server["server_name"] . ":" . $server["port"] . "/solr" . "/" . $core . "/admin/registry.jsp";
var_dump($cmd);
The output should be like:
cmd /c curl http://server_name:8080/solr/"value of variable core"/admin/registry.jsp.
Please suggest. "." operator is not working.
$cmd = "cmd /c curl http://" . $server["server_name"] . ":" . $server["port"] . "/solr" . "/" . $core . "/admin/registry.jsp";
You've used double quotes for array keys in your variables and to identify your text string. You can see in the syntax highlighting that it is parsing those parts as strings rather than keys as part of your variable/array. You should either use single quotes or use curly braces to declare the variable.
Try
$cmd = "cmd /c curl http://{$server['server_name']}:{$server['port']}/solr/{$core}/admin/registry.jsp";
OR
$cmd = "cmd /c curl http://" . $server['server_name'] . ":" . $server['port'] . "/solr/" . $core . "/admin/registry.jsp";
You can't access super global variable $_SERVER with $server, For this you have to use $_SERVER, For accessing server name you should use $_SERVER["SERVER_NAME"] and for accessing server port you should use $_SERVER["SERVER_PORT"]
Change this to:
$cmd = "cmd /c curl http://" . $server["server_name"] . ":" . $server["port"] . "/solr" . "/" . $core . "/admin/registry.jsp";
This:
$cmd = "cmd /c curl http://" . $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . "/solr/" . $core . "/admin/registry.jsp";
Try this:
<?php
$get_cont=array("<a href='www.google.com'>");
foreach ($get_cont as $line)
{
#var_dump($line);
if (strpos($line, "a href"))
{
#echo "$line";
$get_core++;
if ($get_core == 3)
{
#echo $line;
break 1;
}
}
}
;
$array = explode(' ', $line);
$core = $array[count($array) - 1];
$core = substr_replace($core, "", -1);
echo $cmd = "cmd /c curl http://" . $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . "/solr/" . $core . "/admin/registry.jsp";
Below worked for me. I handled the values as string instead of storing it in array:
#echo $line;
$core="";
$core_temp="";
$core_temp=strip_tags($line);
$core=substr($core_temp, strpos($core_temp, " ") + 1);
#$array=explode(' ', $line);
#$core = $array[count($array)-1];
#$core=substr_replace($core, "", -1);
#var_dump($core);
#echo "$core";

WkHtmlToPdf Passing Variables via shell_exec()

Here is a sample of my script
$clientid = $_POST['clientid'];
$from_day = $_POST['stat_from_day'];
$from_month = $_POST['stat_from_month'];
$from_year = $_POST['stat_from_year'];
$to_day = $_POST['stat_to_day'];
$to_month = $_POST['stat_to_month'];
$to_year = $_POST['stat_to_year'];
$from_date_string = $from_day . ' ' . $from_month . ' ' . $from_year ;
$to_date_string = $to_day . ' ' . $to_month . ' ' . $to_year ;
$baseurl = "http://www.test.com/";
$part1 = "?Search=" . $clientid . " from_day=" . $from_day . " from_month=" . $from_month . " from_year=" . $from_year ;
$part2 = " to_day=" . $to_day . " to_month=" . $to_month . " to_year=" . $to_year ;
$time = mktime();
$formatted_time = date("d_M_Y", $time);
$command = "xvfb-run -a /usr/bin/wkhtmltopdf --ignore-load-errors";
$url = $baseurl . $part1 . $part2 ;
$html = file_get_contents($url);
$output_dir = '/var/www/stats/pdf/';
$output = $clientid . '_Search_Export_' . $formatted_time . rand(10000, 99999) . '.pdf';
$generate = shell_exec($command . ' ' . $url . ' ' . $output_dir . $output) ;
The problem i seem to be having is with the $command, basically when it runs wkHTMLtoPDF it runs it via a Command Line, and &variable= bit causes the script to error as via command line & is another command, my question is how do i get the variables to be passed correctly so that the script this then sends to, will be able to use $_GET variables that i require for the script to then work ?
I have done a bit of looking up and found something along the lines of using $argv1;
Replacing $_GET to make it work from command line
However i cannot seem to find a reference that closely matches my needs.
Change this:
$url = $baseurl . $part1 . $part2 ;
To this:
$url = "\" . $baseurl . $part1 . $part2 . "\";
Actually wkhtmltopdf accepts and passes POST data to the server-side page being printed/exported to pdf.
All you need is --post fieldName value.
xvfb-run -a /usr/bin/wkhtmltopdf --ignore-load-errors --post username blablabla --post bla2 answer2
You can have as many as that in the command to pass as many post parameters as you want

Executing AppleScript with PHP shell_exec() and OSAScript

My goal is to be able to submit a search query from a web form and have an AppleScript execute the search in DEVONagent. The AppleScript works fine in terminal but I get an error when having PHP do a shell_exec().
<?php
$theQuery = $_GET["Query"];
$cmd = "theSearch=\"$theQuery\" osascript -e \"set theSearch to system attribute " . "\\" . "\"theSearch" . "\\" . "\"\" -e \"tell application " . "\\" . "\"DEVONagent" . "\\" . "\"\" -e \"search theSearch using set " . "\\" . "\"Web (Deep Link)" . "\\" . "\"\" -e \"end tell\" 2>&1";
echo "<pre>$cmd</pre><BR><BR>";
$theResponse = shell_exec ( $cmd );
echo "Your search for \"$theQuery\" has started and the results will be emailed to you once complete.";
echo "<pre>$theResponse</pre>";
?>
I end up with the following error from the $theResponse echo:
83:92: syntax error: Expected end of line but found identifier. (-2741)
I'm thinking maybe a permissions thing but I just cannot figure it out.

PHP LFTP data mirror output

I'm using a Linux local computer and need to backup/mirror some very large file structures regularly. I only have access to SFTP.
I was after a simple one click solution. I originally tried to write the little script in BASH but I've never used it before and am not up to scratch with the syntax so I resorted to PHP. (I do understand PHP is not designed for this kind of work, but I'm on a tight time scale and don't have the time to get into BASH atm)
<?php
//init
parse_str(implode('&', array_slice($argv, 1)), $_GET);
$error = array();
$lPrefix = '/home/hozza/Sites/';
$archiveLocation = '/home/hozza/Backups/';
$lDir = isset($_GET['l']) ? $_GET['l'] : $error[] = 'Local Directory Required';
$rDir = isset($_GET['r']) ? $_GET['r'] : $error[] = 'Remote Directory Required';
$bookmark = isset($_GET['b']) ? $_GET['b'] : $error[] = 'lftp Bookmark Required';
//Check for args
if(count($error) == 0) {
$archiveName = end(explode('/', $lDir)) . '_' . date('Y-m-d_H-i');
//Validate local dir
if(is_dir($lPrefix . $lDir)) {
//preserve Sublime Text 2 config SFTP files
$ST2_SFTP_conf = false;
if(file_exists($lPrefix . $lDir . '/sftp-config.json')) {
$ST2_SFTP_conf = file_get_contents($lPrefix . $lDir . '/sftp-config.json');
unlink($lPrefix . $lDir . '/sftp-config.json');
}
//Start mirror
$lftOutput = explode("\n", shell_exec('lftp -e "mirror -e -p --parallel=10 --log=' . $archiveLocation . 'logs/' . $archiveName . '.txt ' . $rDir . '/ ' . $lPrefix . $lDir . '/; exit top" ' . $bookmark));
//Tar regardless of lftp error or success
$tarOutput = shell_exec('cd ' . $lPrefix . ' && tar -czf ' . $archiveLocation . $archiveName . '.tar.gz ' . $lDir);
//Output completion or errors
shell_exec('notify-send -i gnome-network-properties -t 0 "Mirror & Archive Complete" "' . $archiveName . '\n\n' . implode('\n', $lftOutput) . $tarOutput . '"');
//put back ST2 SFTP conf
if($ST2_SFTP_conf != false) file_put_contents($lPrefix . $lDir . '/sftp-config.json', $ST2_SFTP_conf);
exit;
}
else shell_exec('notify-send -i error -t 0 "Mirror & Archive Error" "' . date('Y-m-d') . ' ' . date('H-i') . '\n' . $lDir . ' \n Does not exist! D:"');
}
else shell_exec('notify-send -i error -t 0 "Mirror & Archive Error" "' . date('Y-m-d') . ' ' . date('H-i') . '\n' . implode('\n', $error) . '"');
?>
It can be run for many sites via a short-cut like so...
terminator -T "Mirror & Archive" -e "php ~/Programs/mirror.php l=local-dir_path r=./ b=lftp-bookmark-name"
If no password is in the LFTP bookmark (there shouldn’t be as it's stored in plain text) the terminal prompts for a password, after the script has run, a nice notification is given with some info about files/folders/speed etc.
However, when the script is running in a terminal, only the "input password" bit is output to the terminal, I would like all the output displayed in the terminal (normally that would display what file/folder is currently working with etc.)
Anyone know how to do that?
IIRC the reason that you see the password prompt output to the terminal is that it is using stderr. You could try redirecting stdout to stderr for your commands which should show you the 'real-time' progress. Tack this on to the end of the shell_exec() command: 1>&2
ie:
shell_exec('lftp -e "mirror -e -p --parallel=10 --log=' . $archiveLocation . 'logs/' . $archiveName . '.txt ' . $rDir . '/ ' . $lPrefix . $lDir . '/; exit top" ' . $bookmark . ' 1>&2')
However, this will preclude you from having anything returned by shell_exec for logging purposes. What I would suggest is something like:
$log_stem = '/tmp/' . time() . '_'; // ie: /tmp/1357581737_
$lfOutfile = $log_stem . 'lftp.log';
$tarOutfile = $log_stem . 'tar.log';
shell_exec('lftp -blah | tee ' . $lfOutfile ' 1>&2' );
shell_exec('tar -blah | tee ' . $tarOutfile ' 1>&2' );
$lfOut = file_get_contents($lfOutfile);
$tarOut = file_get_contetns(tarOutfile);
// remove tmp files
unlink($lfOutfile);
unlink($tarOutfile);
Which will capture a copy of the output to a file before redirecting the output to stderr so you can watch it live.
However, if you want to run this via cron I would recommend against writing anything to stderr that is not an error, otherwise cron will send a warning email every time it is run.
I think the last answer was close:
Either this:
shell_exec('lftp -blah |& tee ' . $lfOutfile );
shell_exec('tar -blah |& tee ' . $tarOutfile );
Or if that still doesn't work try this:
shell_exec('lftp -blah 2>&1 | tee ' . $lfOutfile );
shell_exec('tar -blah 2>&1 | tee ' . $tarOutfile );

Categories