cURL: jak ukryć dziwne dane wyjściowe podczas przekierowywania?

60

Próbuję wydrukować tylko pełne sekcje żądania cURL (do których są wysyłane stderr) z powłoki bash.

Ale kiedy przekierowuję w stdoutten sposób:

curl -v http://somehost/somepage > /dev/null

Jakaś tabela wyników pojawia się w środku wyniku, aby stderr:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

Następnie pod koniec:

{ [data not shown]
118   592    0   592    0     0  15714      0 --:--:-- --:--:-- --:--:-- 25739

Co sprawia, że ​​nagłówki odpowiedzi są mniej czytelne.

Nie widzę tego tekstu, gdy nie przekierowuję.


Kolejny sposób, aby zobaczyć efekty:

Tabela nie pojawia się:

curl -v http://somehost/somepage 2>&1

Pojawia się tabela:

curl -v http://somehost/somepage 2>&1 | cat

1) Dlaczego pojawia się to tylko w przypadku niektórych rodzajów przekierowań?

2) Jaki jest najładniejszy sposób na stłumienie tego?

Dziękuję Ci

Ian Mackinnon
źródło

Odpowiedzi:

55

Spróbuj tego:

curl -vs -o /dev/null http://somehost/somepage 2>&1

To powstrzyma wskaźnik postępu, wyśle stdoutdo /dev/nulli przekieruje stderr( -vwyjście) do stdout.

Dennis Williamson
źródło
31
Dzięki, -sbył kluczem!
Ian Mackinnon
6
@IanMackinnon Pamiętaj, że z -sale bez -vciebie nie zobaczysz błędów takich jak brak połączenia. W tym celu należy również dodać -S(lub --show-error) jak w odpowiedzi mhoydisa.
Artyom
ale dlaczego pasek postępu pojawia się tylko w pierwszej kolejności podczas przekierowania? Natknąłem się na ten sam problem podczas przesyłania danych wyjściowych curldo jq. Brak paska postępu bez przesyłania do jq, a następnie podczas przesyłania do jqmuszę wrócić i dodać -s.
sixty4bit
@ sixty4bit: To wybór projektowy dokonany przez programistów. Program może wykryć, kiedy STDOUTnie jest tty. Gdy dane wyjściowe nie są przesyłane potokowo, nie chcesz, aby informacje o postępie były przeplatane z normalnymi danymi wyjściowymi, które możesz zobaczyć i mieć pewne pojęcie o postępie. Gdy dane wyjściowe są przekierowywane lub przesyłane strumieniowo, nie można ich zobaczyć, więc nie ma wskaźnika postępu - chyba że pasek postępu jest włączony.
Dennis Williamson
20
curl --fail --silent --show-error http://www.example.com/ > /dev/null

Spowoduje to pominięcie okna dialogowego statusu, ale w przeciwnym razie spowoduje wyświetlenie błędów w STDERR.

user@host:~# curl http://www.yahoo.com > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  254k    0  254k    0     0   403k      0 --:--:-- --:--:-- --:--:--  424k

Powyższe wyświetla tabelę statusu podczas przekierowywania.

user@host:~# curl --fail --silent --show-error http://www.yahoo.com > /dev/null

Powyższe pomija tabelę statusu podczas przekierowywania, ale błędy nadal będą przechodzić do STDERR.

user@host:~# curl --fail --silent --show-error http://www.errorexample.com > /dev/null
curl: (6) Couldn't resolve host 'www.errorexample.com'

Powyżej jest przykładem błędu STDERR.

user@host:~# curl -v --fail --silent --show-error http://www.errorexample.com > ~/output.txt 2>&1
user@host:~# cat ~/output.txt 
* getaddrinfo(3) failed for www.errorexample.com:80
* Couldn't resolve host 'www.errorexample.com'
* Closing connection #0
curl: (6) Couldn't resolve host 'www.errorexample.com'

Wystarczy dodać 2> i 1 na końcu, aby przekierować STDERR do STDOUT (w tym przypadku do pliku).

Mohoydis
źródło
5

Według man curl:

-s, --silent : Silent or quiet mode. Don't show progress meter or error messages. Makes Curl mute.

Przykładowe użycie:

curl -s 'http://www.google.com'

lub jeśli chcesz przechwycić BODY HTTP do zmiennej w bash

BODY=$( curl -s 'http://www.google.com' )
echo $BODY

Możesz używać -slub --silentzamiennie.

Venkatt Guhesan
źródło
4

W odniesieniu do pytania 1 ( skąd cURL wie, że wyświetla tabelę tylko wtedy, gdy wyjście jest przekierowywane), nie zdawałem sobie sprawy, że program może powiedzieć, że jego wyjścia są kierowane, ale wydaje się, że w systemach POSIX jest funkcja, isattyktóra informuje, czy deskryptor pliku odnosi się do terminala.

Ian Mackinnon
źródło
2
Oto fragment Bash:[[ -p /dev/stdout ]] && echo "stdout is to a pipe"; [[ -t 1 ]] && echo "output to terminal"; [[ ! -t 1 && ! -p /dev/stdout ]] && echo "output redirected"
Dennis Williamson
2

1) Dlaczego pojawia się to tylko w przypadku niektórych rodzajów przekierowań?

ze strony man curl

Jeśli chcesz miernik postępu dla żądań HTTP POST lub PUT, musisz przekierować wyjście odpowiedzi do pliku, używając przekierowania powłoki (>), -o [plik] lub podobnego.

curl musi używać isatty do określenia przekierowania i drukuje wskaźnik postępu po przekierowaniu do pliku lub potoku powłoki.

2) Jaki jest najładniejszy sposób na stłumienie tego?

ze strony man curl

-s, --silent

Tryb cichy lub cichy. Nie pokazuj miernika postępu ani komunikatów o błędach. Wycisza Curl. Nadal wyśle ​​dane, o które prosisz, potencjalnie nawet do terminala / standardowego wyjścia, chyba że je przekierujesz.

Wyrmwood
źródło
1

Aby gdzieś umieścić prawdziwe komunikaty o błędach, należy zapisać strerr w pliku dziennika. Coś w tym stylu:

curl  "http://domain.name/process" --stderr /var/log/curl_err.log > /dev/null
użytkownik1065951
źródło