I'm trying to find out if Ruby has en equivalent of php's fopen() method currently used like this:
$fd = fopen("php://stdin", "r");
would that be using ARGV variable?
Basically what I plan on doing is forward raw e-mail messages using the .procmailrc file which I already got working in a test php file, but the project requires the use of Ruby. Therefore I'm not 100% sure if using the ARGV variable would work or if somehow I need to capture the e-mail stream by some other means.
Any help would be greatly appreciated. Thanks :)
ARGV and the (standard) input stream are two different things. ARGV contains the parameters passed to an executable, like someapp a b c where a, b and are parameters. stdin is a file handle. You usually have three standard streams. stdin which is read-only, stdout and stderr which are write-only.
In Ruby you can use the predefined constants STDIN, STDOUT and STDERR to access the default streams. There are also the variables $stdin, $stdout, $stderr which are initialized with the same values as STDIN, STDOOUT and STERR but may be re-assigned other values.
You were probably referring to ARGF variable, have a look:
Best practices with STDIN in Ruby?
Related
I want to pass the string from my php like
<?php
str1="string to pass"
#not sure about passthru
?>
And my tcl script
set new [exec $str1]#str1 from php
puts $new
Is this Possible? Please let me know I'm stuck with this
The simplest mechanism is to run the Tcl script as a subprocess that runs a receiving script (that you'd probably put in the same directory as your PHP code, or put in some other location) which decodes the arguments it is passed and which does what you require with them.
So, on the PHP side you might do (note the important use of escapeshellarg here! I advise using strings with spaces in as test cases for whether your code is quoting things right):
<?php
$str1 = "Stack Overflow!!!";
$cmd = "tclsh mycode.tcl " . escapeshellarg($str1);
$output = shell_exec($cmd);
echo $output;
echo $output;
?>
On the Tcl side, arguments (after the script name) are put in a list in the global argv variable. The script can pull them out with any number of list operations. Here's one way, with lindex:
set msg [lindex $argv 0]
# do something with the value from the argument
puts "Hello to '$msg' from a Tcl script running inside PHP."
Another way would be to use lassign:
lassign $argv msg
puts "Hello to '$msg' from a Tcl script running inside PHP."
Note however (if you're using Tcl's exec to call subprograms) that Tcl effectively automatically quotes arguments for you. (Indeed it does that literally on Windows for technical reasons.) Tcl doesn't need anything like escapeshellarg because it takes arguments as a sequence of strings, not a single string, and so knows more about what is going on.
The other options for passing values across are by environment variables, by pipeline, by file contents, and by socket. (Or by something more exotic.) The general topic of inter-process communication can get very complex in both languages and there are a great many trade-offs involved; you need to be very sure about what you're trying to do overall to pick an option wisely.
It is possible.
test.php
<?php
$str1="Stackoverflow!!!";
$cmd = "tclsh mycode.tcl $str1";
$output = shell_exec($cmd);
echo $output;
?>
mycode.tcl
set command_line_arg [lindex $argv 0]
puts $command_line_arg
This is my code for executing a command from PHP:
$execQuery = sprintf("/usr/local/bin/binary -mode M \"%s\" %u %s -pathJson \"/home/ec2/fashion/jsonS/\" -pathJson2 \"/home/ec2/fashion/jsonS2/\"", $path, $pieces, $type);
exec($execQuery, $output, $return);
the $return value is always 0 but $output is empty. The $output should be a JSON.
If I execute the same but removing one letter to binary (for example /usr/local/bin/binar ) I get (correctly) a $return = 127.
If I write other parameters (like -mode R which doesn't exit) I got errors from the console (which are correct as well).
If I run the exact $execQuery (which I printf before to be sure about quotation marks) on the console, it executes correctly. It's only the PHP side where I've got the error.
What can be wrong?
Thank you in advance.
Well, a couple of things might be happening...
This binary you're running write to something else that STDOUT (for instance, STDERR)
The env vars available to the PHP user differ from the env vars available to the user running console (and those vars are required)
PHP User does not have permission to access some files involved.
In order to debug, it might be better to use proc_open instead of exec, and check the STDOUT and STDERR. This might give you additional information regarding what's happening.
Suggestion (and shameless advertising)
I wrote a small utility library for PHP that executes external programs in a safer way and provides aditional debug information. It might help you to, at least pinpoint the issue.
I have a great Python program on my webserver, which I want to use from inside my PHP web app.
Here's an example of the python command, and output as you would see it in terminal:
>>> print MBSP.parse('I ate pizza with a fork.')
I/PRP/I-NP/O/NP-SBJ-1/O/i
ate/VBD/I-VP/O/VP-1/A1/eat
pizza/NN/I-NP/O/NP-OBJ-1/O/pizza
with/IN/I-PP/B-PNP/O/P1/with
a/DT/I-NP/I-PNP/O/P1/a
fork/NN/I-NP/I-PNP/O/P1/fork ././O/O/O/O/.
You might recognize this as a typical POS tagger.
In any case, I'm confused about how to use a PHP-based web app to send this program a string like "I ate pizza with a fork", and somehow get the response back in a way that can be further parsed in PHP.
The idea is to use PHP to pass this text to the Python program, and then grab the response to be parsed by PHP by selecting certain types of words.
It seems like in PHP the usual suspects are popen() and proc_open(), but popen() is only for sending, or receiving information - not both? Is popen() able to give me access to this output (above) that I'm getting from the Python program? Or is there a better method? What about curl?
Here are all my options in terms of functions in PHP:
http://us.php.net/manual/en/function.proc-open.php
I'm lost on this, so thanks for your wise words of wisdom!
I use exec() for this purpose.
exec($command, $output);
print_r($output);
If you want to get a little heavier / fancier... give your python script an http (or xmlrpc) front end, and call that with a GET/POST. Might not be worth all that machinery though!
You could use popen(), and pass the input to your Python script as a command line argument, then read the output from the file descriptor popen gives you, or proc_open() if you want to interact bi-directionally with the Python script.
Example 1 in the proc_open manual: http://us.php.net/manual/en/function.proc-open.php gives an example of this.
If your Python needs it as stdin, you could try popening a command line:
echo "I ate pizza!"|my_python_progam.py
and just read the output. As usual, do proper input validation before sending it to the command-line.
Something like this would work
$command = '/usr/bin/python2.7 /home/a4337/Desktop/script.py'
$pid = popen('$command',r)
........
........
.........
pclose($pid)
I'm trying to test a php file from a C program(...)
Basically I have a filename that I want to check against php -l and store the output for further processing.
A simple solution in that case would be to redirect the output to a file. And then read the file into an array. You then can have your further processing with the array.
Something like this(in C):
system("php -l yourfile.php > myfile");
FILE *f = fopen("myfile", "rb");
fseek(f, 0, SEEK_END);
long pos = ftell(f);
fseek(f, 0, SEEK_SET);
char *array = malloc(pos);
fread(array, pos, 1, f);
fclose(f);
//your processing part here..
free(array); // free allocated memory
Solution #2: Invoke the PHP interpreter, and pipe the output to your program.
Something like the following in the console:
php -l yourfile.php | pathToYourCProgram
In the above case, you will read the output of PHP from stdin. You can read the entire input, and directly store it to an array.
you can use "popen" function. do man popen to understand the usage of popen. 1st argument of popen is the binary which you want to execute (i.e. "php -l" in your case), and 2nd argument is the mode (read/write). in your case file mode will be read. see the following code to understand how popen works, its fairly easy.
http://www.google.com/notebook/public/17135812868734162318/BDSUiDQoQ-ojrzeck
hope that helps.
If executing the php processor from your C program is not mandatory, you might want to consider the following completely different approach:
Make a small program that parses stdin for error messages and do some post processing. Let's call this program check_errors.
On the command line:
php -l thefile.php | check_errors
This catches the output of php and directs it to check_errors.
It's more Unix-like to build little tools that do one thing, and one thing only, but doing it very well. Using pipes and redirects one may sequence those programs, doing amazing and complex operations.
I need to turn HTML into equivalent Markdown-structured text.
OBS.: Quick and clear way of doing this with PHP & Python.
As I am programming in PHP, some people indicates Markdownify to do the job, but unfortunately, the code is not being updated and in fact it is not working. At sourceforge.net/projects/markdownify there is a "NOTE: unsupported - do you want to maintain this project? contact me! Markdownify is a HTML to Markdown converter written in PHP. See it as the successor to html2text.php since it has better design, better performance and less corner cases."
From what I could discover, I have only two good choices:
Python: Aaron Swartz's html2text.py
Ruby: Singpolyma's html2markdown.rb, based on Nokogiri
So, from PHP, I need to pass the HTML code, call the Ruby/Python Script and receive the output back.
(By the way, a folk made a similar question here ("how to call ruby script from php?") but with no practical information to my case).
Following the Tin Man`s tip (bellow), I got to this:
PHP code:
$t='<p><b>Hello</b><i>world!</i></p>';
$scaped=preg_quote($t,"/");
$program='python html2md.py';
//exec($program.' '.$scaped,$n); print_r($n); exit; //Works!!!
$input=$t;
$descriptorspec=array(
array('pipe','r'),//stdin is a pipe that the child will read from
array('pipe','w'),//stdout is a pipe that the child will write to
array('file','./error-output.txt','a')//stderr is a file to write to
);
$process=proc_open($program,$descriptorspec,$pipes);
if(is_resource($process)){
fwrite($pipes[0],$input);
fclose($pipes[0]);
$r=stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value=proc_close($process);
echo "command returned $return_value\n";
print_r($pipes);
print_r($r);
}
Python code:
#! /usr/bin/env python
import html2text
import sys
print html2text.html2text(sys.argv[1])
#print "Hi!" #works!!!
With the above I am geting this:
command returned 1
Array
(
[0] => Resource id #17
1 => Resource id #18
)
And the "error-output.txt" file says:
Traceback (most recent call last):
File "html2md.py", line 5, in
print html2text.html2text(sys.argv1)
IndexError: list index out of range
Any ideas???
Ruby code (still beeing analysed)
#!/usr/bin/env ruby
require_relative 'html2markdown'
puts HTML2Markdown.new("<h1>#{ ARGF.read }</h1>").to_s
Just for the records, I tryed before to use PHP's most simple "exec()" but I got some problemas with some special characters very common to HTML language.
PHP code:
echo exec('./hi.rb');
echo exec('./hi.py');
Ruby code:
#!/usr/bin/ruby
puts "Hello World!"
Python code:
#!usr/bin/python
import sys
print sys.argv[1]
Both working fine. But when the string is a bit more complicated:
$h='<p><b>Hello</b><i>world!</i></p>';
echo exec("python hi.py $h");
It did not work at all.
That's because the html string needed to have its special characters scaped. I got it using this:
$t='<p><b>Hello</b><i>world!</i></p>';
$scaped=preg_quote($t,"/");
Now it works like I said here.
I am runnig:
Fedora 14
ruby 1.8.7
Python 2.7
perl 5.12.2
PHP 5.3.4
nginx 0.8.53
Have PHP open the Ruby or Python script via proc_open, piping the HTML into STDIN in the script. The Ruby/Python script reads and processes the data and returns it via STDOUT back to the PHP script, then exits. This is a common way of doing things via popen-like functionality in Perl, Ruby or Python and is nice because it gives you access to STDERR in case something blows chunks and doesn't require temp files, but it's a bit more complex.
Alternate ways of doing it could be writing the data from PHP to a temporary file, then using system, exec, or something similar to call the Ruby/Python script to open and process it, and print the output using their STDOUT.
EDIT:
See #Jonke's answer for "Best practices with STDIN in Ruby?" for examples of how simple it is to read STDIN and write to STDOUT with Ruby. "How do you read from stdin in python" has some good samples for that language.
This is a simple example showing how to call a Ruby script, passing a string to it via PHP's STDIN pipe, and reading the Ruby script's STDOUT:
Save this as "test.php":
<?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", "./error-output.txt", "a") // stderr is a file to write to
);
$process = proc_open('ruby ./test.rb', $descriptorspec, $pipes);
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 appended to /tmp/error-output.txt
fwrite($pipes[0], 'hello world');
fclose($pipes[0]);
echo 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 "command returned $return_value\n";
}
?>
Save this as "test.rb":
#!/usr/bin/env ruby
puts "<b>#{ ARGF.read }</b>"
Running the PHP script gives:
Greg:Desktop greg$ php test.php
<b>hello world</b>
command returned 0
The PHP script is opening the Ruby interpreter which opens the Ruby script. PHP then sends "hello world" to it. Ruby wraps the received text in bold tags, and outputs it, which is captured by PHP, and then output. There are no temp files, nothing passed on the command-line, you could pass a LOT of data if need-be, and it would be pretty fast. Python or Perl could easily be used instead of Ruby.
EDIT:
If you have:
HTML2Markdown.new('<h1>HTMLcode</h1>').to_s
as sample code, then you could begin developing a Ruby solution with:
#!/usr/bin/env ruby
require_relative 'html2markdown'
puts HTML2Markdown.new("<h1>#{ ARGF.read }</h1>").to_s
assuming you've already downloaded the HTML2Markdown code and have it in the current directory and are running Ruby 1.9.2.
In Python, have PHP pass the var as a command line argument, get it from sys.argv (the list of command line arguments passed to Python), and then have Python print the output, which PHP then echoes. Example:
#!usr/bin/python
import sys
print "Hello ", sys.argv[1] # 2nd element, since the first is the script name
PHP:
<?php
echo exec('python script.py Rafe');
?>
The procedure should be basically the same in Ruby.
Use a variable in the Ruby code, and pass it in as an argument to the Ruby script from the PHP code. Then, have the Ruby script return the processed code into stdout which PHP can read.
I think your question is wrong. Your problem is how to convert from HTML to Markdown. Am I right?
Try this http://milianw.de/projects/markdownify/ I think it could help you =)
Another very weird approach will be like the one i used.
Php file -> output.txt
ruby file -> read from output.txt
Ruby file-> result.txt
Php file -> read from result.txt
simple add exec(rubyfile.rb);
Not recommended but this will work for sure.