Как получить вывод cURL?

70

Мне нужно получить дату истечения срока действия сертификата SSL. curlПриложение действительно обеспечивает эту информацию:

$ curl -v https://google.com/
* Hostname was NOT found in DNS cache
*   Trying 212.179.180.121...
* Connected to google.com (212.179.180.121) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using ECDHE-ECDSA-AES128-GCM-SHA256
* Server certificate:
*        subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=*.google.com
*        start date: 2014-10-22 13:04:07 GMT
*        expire date: 2015-01-20 00:00:00 GMT
*        subjectAltName: google.com matched
*        issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
*        SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: google.com
> Accept: */*
> 
< HTTP/1.1 302 Found
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Location: https://www.google.co.il/?gfe_rd=cr&ei=HkxbVMzCM-WkiAbU6YCoCg
< Content-Length: 262
< Date: Thu, 06 Nov 2014 10:23:26 GMT
* Server GFE/2.0 is not blacklisted
< Server: GFE/2.0
< 
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="https://www.google.co.il/?gfe_rd=cr&amp;ei=HkxbVMzCM-WkiAbU6YCoCg">here</A>.
</BODY></HTML>
* Connection #0 to host google.com left intact

Однако при передаче результатов через grepрезультат отображается не столько информация на экране, сколько гораздо больше :

$ curl -v https://google.com/ | grep expire
* Hostname was NOT found in DNS cache
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 212.179.180.84...
* Connected to google.com (212.179.180.84) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* SSLv3, TLS handshake, CERT (11):
{ [data not shown]
* SSLv3, TLS handshake, Server key exchange (12):
{ [data not shown]
* SSLv3, TLS handshake, Server finished (14):
{ [data not shown]
* SSLv3, TLS handshake, Client key exchange (16):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Finished (20):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
{ [data not shown]
* SSLv3, TLS handshake, Finished (20):
{ [data not shown]
* SSL connection using ECDHE-ECDSA-AES128-GCM-SHA256
* Server certificate:
*        subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=*.google.com
*        start date: 2014-10-22 13:04:07 GMT
*        expire date: 2015-01-20 00:00:00 GMT
*        subjectAltName: google.com matched
*        issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
*        SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: google.com
> Accept: */*
> 
< HTTP/1.1 302 Found
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Location: https://www.google.co.il/?gfe_rd=cr&ei=IkxbVMy4K4OBbKuDgKgF
< Content-Length: 260
< Date: Thu, 06 Nov 2014 10:23:30 GMT
* Server GFE/2.0 is not blacklisted
< Server: GFE/2.0
< 
{ [data not shown]
100   260  100   260    0     0    714      0 --:--:-- --:--:-- --:--:--   714
* Connection #0 to host google.com left intact

Я подозреваю, что curlобнаруживает, что он не печатает на терминал и, таким образом, дает различный вывод, не все из которых распознаются grepкак являющиеся stdoutи, таким образом, передаются на терминал. Тем не менее, самая близкая вещь к этому, которую я мог найти man curl (никогда не гуглите за это!) , Это:

PROGRESS METER
   curl  normally  displays  a  progress meter during operations, indicating the amount of transferred data, transfer speeds and estimated time
   left, etc.

   curl displays this data to the terminal by default, so if you invoke curl to do an operation and it is about to write data to the  terminal,
   it disables the progress meter as otherwise it would mess up the output mixing progress meter and response data.

   If you want a progress meter for HTTP POST or PUT requests, you need to redirect the response output to a file, using shell redirect (>), -o
   [file] or similar.

   It is not the same case for FTP upload as that operation does not spit out any response data to the terminal.

   If you prefer a progress "bar" instead of the regular meter, -# is your friend.

Как я могу получить только expiryстроку из curlвывода? Кроме того, что я должен читать, чтобы лучше понять ситуацию?

Похоже, это было бы хорошим вариантом использования дескриптора файла "stdmeta" .

dotancohen
источник
@EladKarako: Спасибо. Это хороший ответ, но он не применим к этой ситуации. Возможно, оболочка Windows не имеет концепции отдельных обработчиков выходных файлов, но это другой случай в оболочках Linux.
Dotancohen
1
Я чувствую себя обязанным, чтобы бросить осторожность на ветер и Google Google завиток. Я уверен, что это должно привести к некоторым достойным результатам.
Джереми Кэнфилд

Ответы:

105

curl записывает вывод в stderr, поэтому перенаправьте его, а также подавьте прогресс:

curl -v --silent https://google.com/ 2>&1 | grep expire

Причина, по которой вы curlзаписываете информацию в stderr, заключается в том, что вы можете обойтись:
curl <url> | someprgramбез этой информации, забивающей вводsomeprogram

Энтон
источник
2
-v делает трюк многословно .. спасибо
astroanu
2
нет необходимости в том, чтобы -vвы передавали довольно много текста .. особенно о множественном перенаправлении и SSL-рукопожатиях и обмене сертификатами !! Вы должны использовать либо --includeпросто добавить заголовки в тело ответа, либо, что еще лучше, использовать --headтакже, лучше удалить \rв конце, если вы планируете сохранить значение в переменной, или даже отправить его для вывода позже (см. мой комментарий выше с Content-Lengthпримером)
19

Можно использовать --stderr -как параметр, чтобы перенаправить вывод из stderr (по умолчанию) в stdout. С этой опцией вы также должны использовать, --silentчтобы подавить индикатор выполнения.

$ curl -v --silent https://google.com/ --stderr - | grep expire
*    expire date: 2015-09-01 00:00:00 GMT
Александр
источник