Управление выводом curl в Debian

Я хотел бы запустить команду curl и иметь содержимое, записанное в stdout только в случае ошибки.

Когда я запускаю команду из терминала, я получаю эту функцию по умолчанию. Когда я запускаю команду из скрипта perl (“), она выводит информацию о прогрессе, но не сообщения об ошибках.

Я могу скрыть информацию о прогрессе, добавив флаг -s ( --silent ), но не могу заставить ошибки отображаться так, как они работают при запуске непосредственно из bash. Флаг -S ( --show-errors ), кажется, не имеет никакого эффекта.

Я также попытался поиграть с redirectм вывода в / etc / null, но это, похоже, вообще не дает ничего выводить.

 my $curl_result = `curl -s -S -X PUT "$url" -H "$h1" -H "$h2" -H "$h3" -d "$data"`; 

Ниже приведен пример ошибки, которую я хотел бы найти. Это вызвано намеренно искаженным IP:

 { "code":"INVALID_RECORDS", "message":"One or more of the given records is invalid", "fields": [{ "code":"INVALID_RECORDS", "message":"Invalid [ipaddress] provided for record data, [test].", "path":"records" }], "name":"ApiError", "errors":["Invalid [ipaddress] provided for record data, [test]."] } 

Вы должны различать ошибки, которые видит curl, и ошибки, которые возвращает ваш http-сервер. Последние не являются ошибками для скручивания. Однако вы можете легко проверить код состояния http, добавив в свой curl параметр

  -w '\n%{http_code}\n' 

Это добавит к stdout заголовок HTTP, который равен 200 для OK. Так что ваш Perl может сделать что-то вроде

 my $curl_result = `curl -s -S -w '\n%{http_code}\n' ... 2>/dev/null`; my @lines = split(/\n/,$curl_result); my $httpcode = $lines[-1]; if($httpcode eq 200){ print "ok\n"; } else{ print "error\n"; } 

Оператор обратного удара Perl вернет (в вашу переменную $ curl_result) STDOUT команды, которую вы запускаете. STDERR из этой команды перейдет к вызывающей программе / терминалу вашего Perl-скрипта – возможно, к вашему экрану, как если бы вы сами вызвали curl .

Для того, чтобы захватить STDERR, вы должны (как вы начали представлять) сбросить STDOUT или смешать их.

Вот пример удаления STDOUT и перенаправления STDERR в STDOUT, чтобы он (вместо «обычного» STDOUT) перехватывался переменной perl:

 my $curl_result = `curl ... 2>&1 1>/dev/null`; 

Кроме того, смешайте два:

 my $curl_result = `curl ... 2>&1`; 

Я опустил середину команды массового curl чтобы было ясно, какую часть я изменил. Первый пример изменяет STDERR так, чтобы он указывал на то, куда в данный момент указывает STDOUT, а затем указывает STDOUT уходить. Во втором примере STDERR указывает на STDOUT, объединяя два.