I'm calling a Ruby script from PHP with system('ruby show.rb filename').
The show.rb looks like this:
require 'erubis'
f = ARGV[0]
puts f
input = File.read(f)
eruby = Erubis::Eruby.new(input)
puts eruby.result(binding())
When executing the command ruby show.rb filename in the console everything is printed out, but when calling it from PHP it's only printing the filename, but the template is not rendered. To see errors I piped stderr -> stdout in the PHP call and I got this
/Library/Ruby/Gems/2.3.0/gems/erubis-2.7.0/lib/erubis/converter.rb:132:in 'scan': invalid byte sequence in US-ASCII (ArgumentError) from /Library/Ruby/Gems/2.3.0/gems/erubis-2.7.0/lib/erubis/converter.rb:132:in 'convert_input' from /Library/Ruby/Gems/2.3.0/gems/erubis-2.7.0/lib/erubis/converter.rb:36:in 'convert' from /Library/Ruby/Gems/2.3.0/gems/erubis-2.7.0/lib/erubis/engine.rb:30:in 'initialize' from show.rb:5:in 'new' from show.rb:5:in temp/Newsletter.rb'
I'm new to Ruby. Are there maybe any option parameters to fix this? What is PHP doing differently there, that the error can occur?
I don't know why, but when opening a erubis template file inside show.rb called by PHP it must be opened as a binary file. So I only had to change show.rb to:
require 'erubis'
f = ARGV[0]
handle = File.open(f, "rb") # "rb" fixed the issue.
input = handle.read()
handle.close()
eruby = Erubis::Eruby.new(input)
puts eruby.result(binding())
Related
So first off, sorry if this question has already been answered elsewhere, but I couldn't find the answer myself.
I've got a LAMP server running in Ubuntu 16.04 and I'm trying to use Python 2.7.12 to write to a text file from PHP.
I've got the following two files (note, these two files are in the same directory):
index.php
<?php
$command = escapeshellcmd('python test.py a b c');
$output = shell_exec($command);
echo $output;
?>
test.py
import sys
print "argv1: ", sys.argv[1]
print "argv2: ", sys.argv[2]
print "argv3: ", sys.argv[3]
f = open("test-" + sys.argv[1] + ".txt","w+")
f.write("test")
f.close()
print "Text added."
When I navigate to the index.php file in my browser, I get the following output:
argv1: a argv2: b argv3: c
However, when I execute this code in the terminal the file test-a.txt is created and I get the following output:
layer8#alpha:/var/www/html/$ python test.py a b c
argv1: a
argv2: b
argv3: c
Text added.
I can't seem to understand and work out why the Python file isn't executing any code past the third print argv3 statement?
I've done a lot of research into this and I've been unable to find a solution. If you need any further information from me, please do not hesitate to ask; any responses are appreciated.
Thanks.
shell_exec will only return what get's printed to stdout. If an exception arises in the Python script, the whole exception message and traceback are printed on stderr, so they won't be part of the output. Note that theoretically, shell_exec should return NULL if an error happens but well, this is PHP so it wouldn't be much fun if the builtin funcs behaved as documented...
Anyway: the problem is very probably with opening the file, and is very probably a permission issue.
First, you're using a relative path, and relative path are resolved against the current working directory, not against the directory where your script is located, so if you expect a sane and predictable behaviour always use an absolute path (either pass it as argument or build it against the script's current location).
Also your Apache server may not (this is an understatement) run with the same env and user as you so it might just not be allowed to open a file for wrting in whatever-his-own-current-working-directory is at that time.
And finally, even it's PYTHONPATH might be different than yours so it might even be executing another (leftover) test.py OR a stale test.pyc file.
To make a long story short: it's impossible to tell for sure what's wrong without having access to your system, but at least now you know where to start debugging.
The first thing I'd personnaly do would be to make sure any error in the python script is printed to stdout:
import sys
print "argv1: ", sys.argv[1]
print "argv2: ", sys.argv[2]
print "argv3: ", sys.argv[3]
try:
fname = "test-%s.txt" % sys.argv[1]
with open(fname,"w+") as f:
f.write("test")
print "Text added."
except Exception as e:
print "oops : got %s" % e
raise
actual I finished writing my program. Because it is only a plugin and it runs on a external server I still want to see if I get some errors or something else in the console.
I wrote every console input with echo ...;. My question now is if it is possible to get the text of the console?
Because then I could easily safe it in a .txt file and could get access to it from the web :) - Or is there another way to get the console text?
I could probably just say fwrite(...) instand of echo ...;. But this will cost a lot of time...
Greetings and Thank You!
An alternative that could be usefull on windows would be to save all the output buffer to a txt, first check your php configuration for the console app implicit_flush must be off then
<?php
ob_start(); //before any echo
/** YOUR CODE HERE **/
$output = ob_get_contents(); //this variable has all the echoes
file_put_contents('c:\whatever.txt',$output);
ob_flush(); //shows the echoes on console
?>
If your goal is to create a text file to access, then you should create a text file directly.
(do this instead of echoing to console)
$output = $consoleData . "\n";
$output .= $moreConsoleData . "\n";
(Once you've completed that, just create the file:)
$file = fopen('output.txt', 'a');
fwrite($file, $output);
fclose($file);
Of course, this is sparse - you should also check that the file exists, create it if necessary, etc.
For console (commando line interface) you can redirect the output of your script:
php yourscript.php > path-of-your-file.txt
If you haven't access to a command line interface or to edit the cronjob line, you can duplicate the starndar output at the begining of the script:
$fdout = fopen('path-to-your-script.txt', 'wb');
eio_dup2($fdout, STDOUT);
eio_event_loop();
fclose($fdout);
(eio is an pecl extension)
If you are running the script using the console (i.e. php yourscript.php), you can easily save the output my modifying your command to:
php yourscript.php > path/to/log.txt
The above command will capture all output by the script and save it to log.txt. Change the paths for your script / log as required.
I have a classic ASP page that needs to access a file generated via a PHP script. Is it possible to call the PHP script somehow, from within VBScript?
And before anyone asks, I do not have the time to port either script. They are both very complex and I only need a short term solution at this time.
Now the below is not generating errors, but the file is not being generated. I'm ready to give up.
str = "D:\TTnav_Alpha\Alpha\Framework\EnvMgr\generate_jira_list.php"
Set objShell = CreateObject("WScript.Shell")
'response.write(str)
objShell.Run """C:\Program Files (x86)\PHP\php.exe"" " & str ,3,true
Set objShell = Nothing
My .vbs code successfully calls a script in .php file.
In my .vbs file I have this:
set wshell = CreateObject("WScript.Shell")
wshell.Run "C:\xampp\php\php.exe -f C:\Temp\test2.php"
set wshell = nothing
Double quotes must enclose the path if there are spaces within the path, e.g.:
set wshell = CreateObject("WScript.Shell")
wshell.Run """C:\my xampp dir\php\php.exe"" " & "-f C:\Temp\test2.php"
set wshell = nothing
Just invoke WScript.Shell as explained at How do I execute a DOS command / batch file / exe from ASP?
<%
' Untested
set wshell = CreateObject("WScript.Shell")
wshell.run "c:\dos\php c:\site\script.php"
set wshell = nothing
%>
Edit: You are now trying to execute this:
C:\Program Files (x86)\PHP\php.exeD:\TTnav_Alpha\Alpha\Framework\EnvMgr\generate_jira_list.php
This is an invalid command (if you copy it to a command prompt, it won't run). You need to quote the paths with spaces and separate the command from the argument:
"C:\Program Files (x86)\PHP\php.exe" D:\TTnav_Alpha\Alpha\Framework\EnvMgr\generate_jira_list.php
In VBScript you escape quotes doubling them so you want:
objShell.Run """C:\Program Files (x86)\PHP\php.exe"" " & str,3,false
By the way, that 3 means Activates the window and displays it as a maximized window. Don't forget to remove it before going live.
Ref: Run Method (Windows Script Host)
I have a script which when compiled from the terminal passing the parameters something like this "php compile.php arg1 arg2 arg3 arg4" on the terminal starts displaying the output result which is something like 1)file created 2) file inclusion. etc.
Now I am trying to use system(php compile.php arg1 arg2 arg3 arg4) from another php file, but it will not execute the php file or will not show an output.
For example i even tried to create hello.php------
and tried using system(php hello.php); but it did not output anything on the browser.
Can anyone please help me out, I am new to php. Thanks.
make sure you react on errors from the system call. Your actual code might also help. The following example works without problems on my box.
<?php
$file = fopen('/tmp/written.php', 'w');
fwrite($file, '<?php echo "Hello from written.php\n"; ?>');
fclose($file);
echo "calling written.php\n";
if (!system('php /tmp/written.php'))
die("something wrong\n");
else
exit("all good\n");
?>
I am trying to make a PHP program triggered by a web submit tell a bash script to run with a single command line parameter. I am using the shflags command line parser for bash.
The pertinent part of the PHP script is as follows:
// generate unique filename
$destinationFolder = Mage::getBaseDir('media') . DS . 'webforms' . DS . 'xml';
$filename = $destinationFolder . DS . $result->getId().'.xml';
// create folder
if (!(#is_dir($destinationFolder) || #mkdir($destinationFolder, 0777, true))) {
throw new Exception("Unable to create directory '{$destinationFolder}'.");
}
// export to file
$xmlObject->getNode()->asNiceXml($filename);
// define parameters to pass
exec ( '/opt/bitnami/apache2/htdocs/sfb/scripts/xform.sh --xmlfile'.' '.$filename);
}
}
?>
The bash script (xform.sh) (just a test script) is as follows.
#!/bin/bash
. ./shflags
echo "foo" >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/$$".txt"
echo "foo" >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt
DEFINE_string 'xmlfilename' 'test' 'filename of current x.xml file from webforms' 'Z'
FLAGS "$#" || exit 1
eval set -- "${FLAGS_argv}"
echo "xml file was" ${FLAGS_xmlfilename} >> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt
The bash script works correctly from the command line, i.e.
$xform.sh --xmlfilename 1.xml
writes "xml file was 1.xml" to the foo.txt file.
When the PHP script is triggered from the web, the first part works correctly, i.e. it writes "foo" to the two target files, foo.txt and $$.txt. However, the xmlfilename variable is not coming along, and I really need that file name to be passed to the command line! (Note I should not need to use escapeshellarg because the file name is generated by my PHP program, not by user input.)
I have checked all the file permissions I can think of. xform.sh and shflags are both members of the www-data (Apache) group, owned by Apache, and a+x.
My suspicions are that the problem is related either to a) my PHP exec syntax or b) file permissions. Everything works as intended except the bit after xform.sh in this line!
exec ( '/opt/bitnami/apache2/htdocs/sfb/scripts/xform.sh --xmlfile'.' '.$filename);
UPDATE:
I've narrowed the problem some more by isolating the problem with some test code. With:
$script="echo";
$xmlfilename="$filename";
$target=">> /opt/bitnami/apache2/htdocs/sfb/scripts/seeds/xform/foo.txt";
exec ("$script $xmlfilename $target");
...
PHP correctly writes the $filename to foo.txt, so $script works when value is "echo" and $filename works too.
When I set $script to a different simple form of the xform script that (only) writes the data to the file, that also works correctly.
So the problem is specifically with something that happen when PHP tries to write the $filename as a command line variable. Does a script run by Apache need more permissions than usual if it includes a command line variable?
Sigh.
In your exec() call you have the flag as --xmlfile but you are calling it from the command line as --xmlfilename