記錄一個有關 curl 和 tar 的小問題

這是我今天在工做時遇到的一個有關解壓的問題,先還原下問題html

今天在解壓一個壓縮包時解壓失敗,如下是命令以及失敗提示linux

$ curl -O https://github.com/alibaba/canal/releases/download/canal-1.1.3/canal.deployer-1.1.3.tar.gz
$ tar -zxvf canal.deployer-1.1.3.tar.gz

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now
複製代碼

這裏首先提示,形成這個問題的緣由以及解決方案很簡單,對你頗有可能沒有借鑑意義。不過尋找緣由的過程以及從這個問題上學到的東西仍是有點意思的。git

本文連接 blog.xiange.tech/post/a-prob…程序員

StackOverflow

做爲程序員的兩大利器之一,StackOverflowgithub。第一步就跟蹤到了 StackOverflow,查找到了這個問題,問題描述如出一轍github

How to extract filename.tar.gz fileshell

首先,先使用 file 查看下文件的類型bash

$ file canal.deployer-1.1.3.tar.gz
canal.deployer-1.1.3.tar.gz: HTML document, ASCII text, with very long lines, with no line terminators
複製代碼

若是沒有使用 gzip 壓縮,那須要使用 tar 解壓的時候,去掉 -z 參數。app

無果。curl

這裏安利一個工具,explainshell 能夠以圖文可視化 shell 命令各個參數的意義,當參數較多,命令較長時,很是試用,強烈推薦。工具

explainshell

不過,我從 file 命令中意識到有可能文件有問題,由於它的輸出是 HTML document,且是純文本類型。

從源頭出發

當我意識到文件有問題時,以爲應該從文件源找出問題。文件是經過 curl 下載而來,我添加了 -v 參數用來查看 http 詳細的報文。

$ curl -Ov https://github.com/alibaba/canal/releases/download/canal-1.1.3/canal.deployer-1.1.3.tar.gz
...
> User-Agent: curl/7.29.0
> Host: github.com
> Accept: */*
>
< HTTP/1.1 302 Found
< Date: Fri, 12 Apr 2019 13:20:31 GMT
< Content-Type: text/html; charset=utf-8
...
複製代碼

定位到問題了,地址作了重定向,可是 curl 並無跟蹤重定向後的 Location。所以,剛纔的壓縮包實際上是關於重定向的響應,因此文件類型是 HTML document

爲了驗證一下,我查看了壓縮包的內容。

$ cat canal.deployer-1.1.3.tar.gz
<html><body>You are being <a href="https://github-production-release-asset-2e65be.s3.amazonaws.com/7587038/6df81900-56c6-11e9-8140-7d9ae25b1ca8?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20190412%2Fus-east-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20190412T132310Z&amp;X-Amz-Expires=300&amp;X-Amz-Signature=3cb0943449b8d86bf6292b399409fddfa9fbef1c646c20910f10ae7fe836e53e&amp;X-Amz-SignedHeaders=host&amp;actor_id=0&amp;response-content-disposition=attachment%3B%20filename%3Dcanal.deployer-1.1.3.tar.gz&amp;response-content-type=application%2Foctet-stream">redirected</a>.</body></html>
複製代碼

果真如此,我忽然意識到在剛開始 curl 成功後根據 Received 的大小就能夠定位到問題了。不過我通常自動忽略 curl 的輸出,並且當下載東西的時候,我通常就切窗口了...

# 接收到的文件只有 616 個字節大小
$ curl -O https://github.com/alibaba/canal/releases/download/canal-1.1.3/canal.deployer-1.1.3.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   616    0   616    0     0    444      0 --:--:--  0:00:01 --:--:--   444
複製代碼

找到了問題就很好解決了。

問題解決

找到 curl 追蹤重定向的參數,從新下載問題解決。

# 找到參數爲 -L
$ curl --help | grep -e follow -e redirect
-L, --location      Follow redirects (H)
     --max-redirs NUM  Maximum number of redirects allowed (H)
     --post301       Do not switch to GET after following a 301 redirect (H)
     --post302       Do not switch to GET after following a 302 redirect (H)
     --post303       Do not switch to GET after following a 303 redirect (H)
     --proto-redir PROTOCOLS  Enable/disable specified protocols on redirect
     --stderr FILE   Where to redirect stderr. - means stdout
$ curl -OL https://github.com/alibaba/canal/releases/download/canal-1.1.3/canal.deployer-1.1.3.tar.gz
複製代碼

反思

若是仔細一點,剛開始 curl 時發現 Received 的大小,估計幾秒鐘就能解決問題。不過總的來講仍是略有收穫。

  1. explainshell 解析複雜的 linux 命令
  2. curl -OL <url> 追蹤重定向並下載到本地
  3. file <file> 查看文件類型
  4. 使用 grep 匹配多個關鍵字
    1. grep "PATTERN1\|PATTERN2" FILE
    2. grep -E "PATTERN1|PATTERN2" FILE
    3. grep -e PATTERN1 -e PATTERN2 FILE
    4. egrep "PATTERN1|PATTERN2" FILE

關注公衆號山月行,記錄個人技術成長,歡迎交流

歡迎關注公衆號山月行,記錄個人技術成長,歡迎交流
相關文章
相關標籤/搜索