Как мне получить вывод curl в переменную в Perl, если я вызываю его с помощью бэктикса?

Я пытаюсь получить ответ на вызов curl в переменной в Perl.

my $foo = `curl yadd yadda`;

print $foo;

не работает. Когда я запускаю это в командной строке, вызов curl правильно печатает все свои выходные данные в терминале, но переменная не заполняется этими данными.

Есть ли способ сделать это без установки и вызова Perl curl lib?


person Yevgeny Simkin    schedule 18.06.2009    source источник


Ответы (9)


Вероятно, он отправляет свои данные в stderr. Пытаться

my $foo = `curl yadd yadda 2>&1`;
person sunny256    schedule 18.06.2009
comment
Это сделало это! спасибо!. Я поставлю вам галочку, если вы добавите пару предложений о том, что на самом деле делает 2›&1 и почему перемещение его из stderr в то, что есть &1, выгружает его в переменную. Большое спасибо! - person Yevgeny Simkin; 19.06.2009
comment
2›foo означает перенаправление stderr в файл foo. &1 означает stdout, т. е. перенаправить stderr на stdout. Вы также можете сделать это по-другому: ›&2, что означает перенаправление stdout на stderr. Чтобы перенаправить как stdout, так и stderr, вы можете использовать ›&, то есть foocommand &›file_with_boththings.txt - person sunny256; 19.06.2009
comment
Обозначение «2›&1» означает, что файловый дескриптор 2 (stderr) отправляется в то же место, куда отправляется файловый дескриптор 1 (stdout). Таким образом, и стандартный вывод, и стандартная ошибка записываются в одно и то же место (стандартный вывод). И обратные кавычки Perl фиксируют стандартный вывод выполняемой команды, следовательно... - person Jonathan Leffler; 19.06.2009
comment
tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3. html и tldp.org/LDP/abs/html/io- redirection.html также содержит полезную информацию об этом. - person sunny256; 19.06.2009

Вы также можете посмотреть на LWP::UserAgent или даже LWP::Simple .

person jiggy    schedule 19.06.2009

Что вы действительно хотите сделать? Использовать curl любой ценой или захватить содержимое веб-страницы?

Более опасный способ сделать это (который не зависит от внешних программ, которые могут быть установлены или не установлены на следующем компьютере, где вам нужно это сделать):

use LWP::Simple;

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

Если вы хотите узнать, почему не удалось выполнить GET, или получить несколько страниц с одного и того же сайта, вам потребуется немного больше механизмов. perldoc lwpcook поможет вам начать.

person dland    schedule 21.06.2009

В оболочке 2> означает перенаправление fileno 2. Fileno 2 всегда является тем, что программа видит как stderr. Точно так же номер файла 0 — это стандартный ввод, а номер файла 1 — стандартный вывод. Итак, когда вы говорите 2>&1, вы говорите оболочке перенаправить stderr (fileno 2) в stdout (fileno 1). Поскольку оператор обратных кавычек использует оболочку для запуска указанной вами команды, вы можете использовать перенаправление оболочки, поэтому

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

указывает curl перенаправить свой вывод в стандартный вывод, и, поскольку оператор обратной кавычки перехватывает стандартный вывод, вы получаете то, что искали.

person Chas. Owens    schedule 18.06.2009
comment
спасибо ... ваше объяснение лучше сформулировано, чем то, которое я выбрал в качестве правильного ответа, поэтому я повышаю его :) - person Yevgeny Simkin; 19.06.2009

Попробуй это:

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

curl отображает информацию о прогрессе в stderr, перенаправляя ее в /dev/null, чтобы было легче увидеть, что происходит.

person brian-brazil    schedule 18.06.2009

Это работает в моей системе:

#!/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"><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

и т. д.

person Sinan Ünür    schedule 18.06.2009
comment
Я думаю, вы можете неправильно интерпретировать печать завитка для оператора печати, который у вас есть. Попробуйте вместо этого напечатать OUTPUT=$output и посмотрите, получите ли вы правильный результат. Я тоже это сделал, и он печатает вывод curl, а затем печатает OUTPT =, потому что он никогда не получал результат в var. Тем не менее, ответ выше правильный. - person Yevgeny Simkin; 19.06.2009
comment
@Dr.Dredel, если я удалю оператор печати, я увижу информацию о ходе выполнения, которая curl печатает в stderr, но не вывод curl. Если я поставлю print OUTPUT=$output, я получу OUTPUT=‹!DOCTYPE... и т. д., поэтому я не уверен, о чем вы говорите. справочная страница curl является явной: по умолчанию он выводит на стандартный вывод, а обратные кавычки в Perl фиксируют этот вывод. - person Sinan Ünür; 19.06.2009
comment
возможно, это какое-то несоответствие платформы. Он определенно не печатает на стандартный вывод для меня, и ответ, который я проверил, решил проблему. - person Yevgeny Simkin; 19.06.2009
comment
curl.haxx.se/docs/manpage.html -o/--output ‹ file› Записывать вывод в ‹file› вместо stdout. Может быть, это связано с тем, что вы не показываете. - person Sinan Ünür; 19.06.2009

Вы можете открыть канал, как если бы это был файл.

$url = "\"http://download.finance.yahoo.com/d/quotes.csv?s=" . 
"$symbol&f=sl1d1t1c1ohgvper&e=.csv\"";

open CURL, "curl -s $url |" or die "single_stock_quote: Can't open curl $!\n";
$line = <CURL>;
close CURL;
person jpenkethman    schedule 22.05.2014

Очень старый пост, но настоящий способ использования curl в обратных апострофах — это использование соответствующего переключателя curl.

Этот ключ -o определяет, куда отправлять выходные данные.

Подробнее с справочной страницы curl:

Указание вывода как «-» (одиночное тире) заставит вывод выполняться на стандартный вывод.

Это также предотвращает возможные ошибки в $foo, которые могут произойти, если вы перенаправите полный STDERR в STDOUT при ошибках:

my $foo = `curl -o - yadd yadda`;
person Jimmy Koerting    schedule 29.08.2020

Возможно, часть выходных данных, которые вы хотите захватить, находится в стандартном err, а не в стандартном выходе. Попробуй это:

my $foo = system "curl http://www.stackoverflow.com";
print $foo;
person pjb3    schedule 18.06.2009
comment
это не делает то, что вы думаете. - person Geo; 19.06.2009