Comment grep la sortie de cURL?

70

Je dois récupérer la date d'expiration d'un certificat SSL. L' curlapplication fournit cette information:

$ 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

Cependant, lorsque vous dirigez la sortie via greple résultat, vous obtenez non pas moins d' informations à l'écran, mais beaucoup plus :

$ 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

Je soupçonne que cela curldétecte qu’il n’imprime pas sur un terminal et donne donc une sortie différente, qui n’est pas tous reconnue grepcomme étant en cours stdoutet est donc transmise au terminal. Cependant, la chose la plus proche de ce que je pourrais trouver dans man curl (ne jamais google pour ça!) Est la suivante:

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.

Comment puis-je obtenir juste la expiryligne de la curlsortie? De plus, que devrais-je lire pour mieux comprendre la situation?

Cela semble être un bon cas d’utilisation pour un descripteur de fichier "stdmeta" .

dotancohen
la source
@EladKarako: Merci. C'est une bonne réponse, mais cela ne s'applique pas à cette situation. Peut-être que le shell Windows n'a pas de concept de gestionnaires de fichiers de sortie distincts, mais il s'agit d'un cas différent dans les shells Linux.
dotancohen
1
Je me sens obligé de jeter la prudence au vent et Google man curl. Je suis certain que cela va forcément donner des résultats intéressants.
JeremyCanfield le

Réponses:

105

curl écrit le résultat sur stderr, redirigez-le et supprimez également la progression:

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

La raison pour laquelle curlles informations sont écrites sur stderr, c’est pour que vous puissiez le faire:
curl <url> | someprgramsans ces informations qui entravent la saisie desomeprogram

Anthon
la source
2
-v fait le tour du verbose .. merci
astroanu
2
pas besoin de -vtexte, beaucoup de texte .. surtout sur la redirection multiple, les poignée de main SSL et l'échange de certificats !! vous devez utiliser soit --includesimplement pour ajouter les en-têtes au corps de la réponse, soit, mieux encore --head, vous devez également supprimer \rles éléments finaux si vous envisagez de stocker la valeur dans une variable ou même de l'envoyer ultérieurement en sortie (voir mon commentaire ci-dessus avec Content-Lengthexemple)
19

Il est possible d'utiliser --stderr -comme paramètre pour rediriger la sortie de stderr (par défaut) vers stdout. Avec cette option, vous devriez également utiliser --silentpour supprimer la barre de progression.

$ curl -v --silent https://google.com/ --stderr - | grep expire
*    expire date: 2015-09-01 00:00:00 GMT
Alexandre
la source