views:

1927

answers:

7

I'm trying to get the response of a curl call into a variable in perl.

my $foo = `curl yadd yadda`;

print $foo;

does not work. When I run this at the command line the curl call prints all its output correctly in the terminal, but the variable is not filled with that data.

Is there a way to do this without installing and calling the Perl curl lib?

+5  A: 

It probably sends its stuff to stderr. Try

my $foo = `curl yadd yadda 2>&1`;
sunny256
No, it does not.
Sinan Ünür
Dr.Dredel
sunny256
Jonathan Leffler
http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html and http://tldp.org/LDP/abs/html/io-redirection.html has some nice info about it also.
sunny256
+1  A: 

Try this:

$var = `curl "http://localhost" 2>/dev/null`; 
print length($var)

curl displays progress information on stderr, redirecting that to /dev/null makes it easier to see what's going on.

A: 

It might be that some of the output you want to capture is in standard err, not standard out. Try this:

my $foo = system "curl http://www.stackoverflow.com";
print $foo;
pjb3
this doesn't do what you think it does.
Geo
A: 

This works on my system:

#!/usr/bin/perl

use strict;
use warnings;

my $output = `curl www.unur.com`;

print $output;

__END__

C:\> z1

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"&gt;&lt;html&gt;
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

etc.

Sinan Ünür
I think you may be misinterpreting the printing of the curl for the print statement you have there. Try print "OUTPUT=$output" instead and see if you get the right result. I did that too and it prints the curl output and then prints "OUTPT=" cause it never got the result into the var. However, the answer above is correct.
Dr.Dredel
@Dr.Dredel if I remove the print statement, I see the progress information which curl prints to stderr, but not the output of curl. If I put print "OUTPUT=$output", I get OUTPUT=<!DOCTYPE ... etc, so I am not sure what you are talking about. curl's man page is explicit: By default, it outputs to stdout and backticks in Perl capture that output.
Sinan Ünür
perhaps it's some sort of platform discrepancy. It definitely does not print to stdout for me, and the answer I checked did fix the issue.
Dr.Dredel
http://curl.haxx.se/docs/manpage.html -o/--output <file>Write output to <file> instead of stdout. Maybe this has to do with the 'yadd yadda' you are not showing.
Sinan Ünür
+1  A: 

In the shell 2> means redirect fileno 2. Fileno 2 is always what a program sees as stderr. Similarly, fileno 0 is stdin and fileno 1 is stdout. So, when you say 2>&1 you are telling the shell to redirect stderr (fileno 2) into stdout (fileno 1). Since the backticks operator uses the the shell to run the command you specify, you can use shell redirection, so

my $foo = `curl yadda yadda 2>&1`;

is telling curl to redirect its output into stdout, and since the backtick operator catches stdout, you get what you were looking for.

Chas. Owens
thanks... your explanation is morely betterlier worded than the one I picked as the right answer, so, I'm giving it an uptick :)
Dr.Dredel
+4  A: 

You also might consider looking at LWP::UserAgent or even LWP::Simple.

jiggy
+1  A: 

What do you really want to do? Use curl at all costs, or grab the contents of a web page?

A more perlish way of doing this (which relies on no external programs that may or may not be installed on the next machine where you need to do this) would be:

use LWP::Simple;

my $content = get("http://stackoverflow.com/questions/1015438/")
   or die "no such luck\n";

If you want to see why the GET failed, or grab multiple pages from the same site, you'll need to use a bit more machinery. perldoc lwpcook will get you started.

dland