轉載請註明出處:http://www.javashuo.com/article/p-sglanarg-bh.htmlhtml
內容提要:java
首先,寫這篇博文的一個出發點是:我沒法在window的cmd命令行下實現日期的加減(還有其餘問題),固然這不是沒有實現的方法,而是實現起來很難維護難度較大,光插件都夠我折騰了,另外window自帶的powershell也能夠實現,不過做爲一個java渣來講真的難了點兒,由於又要熟悉powershell語法從零開始 後來,我換了個思路,想用代碼+第三方開源插件(依賴)實現以上功能;至於,目前我有對Python、java、js、Go、甚至Rust,這些都有或多或少的涉獵,分析了一遍,發現使用半靜態或者腳本語言實現很easy,不過有一個問題:你每部署一臺機器都要安裝語言環境如Python、java,雖然能夠跨平臺,不過太臃腫了部署一個幾兆的應用要安裝一個幾百兆的語言環境,實在太浪費了內存,js呢又太弱,須要本身造輪子,能夠剔除,Rust速度快,不過編寫的難度太大,很難考慮, 最後我選用GO做爲以上工具的語言,固然這裏不得不說一下使用GO的好處:語法簡單、跨平臺、代碼安全、靜態打包:這個很重要,能夠直接打windows下的可執行程序,也能夠打linux可執行程序[交叉編譯],這樣就能夠在部署的時候不用動手又動腳的安裝語言環境,配置環境變量之類的亂七八糟的東西,同時安全度也很複合個人需求,例如打成一個可執行包後就自帶破解難度,更牛掰的是還可使用upx對可執行包進行加殼,加殼有三個好處:幾乎沒法破解、可執行應用體積大大縮小(比個人一個應用打包後有16MB,加殼後只有3MB左右)、易於分發(固然這個是創建在加殼之上在),一切準備就緒,這一篇我就簡單的聊一聊我用GO如何實現這類Tools。
因爲本章只是個人實現的工具分享,因為這些工具備必定的靈活性,(若須要改造或實現)這時就須要您有必定的GO語言基礎。linux
這裏的我主要用到 github.com/pkg/sftp
與 golang.org/x/crypto/ssh
,一個是執行sftp命令,一個是創建ssh鏈接的,由於sftp是創建在安全的ssh鏈接上的
樣例中有我實現實現linux日誌拉取的功能的完整代碼,,這裏就不展現具體實現代碼(參考樣例),就簡單說說實現步驟吧:git
config := &ssh.ClientConfig{...
client, err := ssh.Dial("tcp", "服務器地址:端口", config)
sftp, err := sftp.NewClient(client)
srcFile, err := sftp.Open("/路徑/文件01.log." + time + ".zip")
dstFile, err := os.Create(targetPath + "/文件01.log." + time + ".zip")
srcFile.WriteTo(dstFile)
因爲在解決實際問題的時候面臨的問題比較複雜,光一個壓縮包就有zip、tar、gz還有tar+gz的方式,具體使用的時候用到的依賴有
archive/tar
、compress/gzip
、archive/zip
、path/filepath
及GO自帶的基本依賴等等...github
r, err := zip.OpenReader(fullZipFile)
for _, f := range r.File {...
os.MkdirAll(path, f.Mode())
os.MkdirAll(filepath.Dir(path), f.Mode())
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
_, err = io.Copy(f, rc)
fr, err := os.Open(srcFilePath)
gr, err := gzip.NewReader(fr)
tr := tar.NewReader(gr)
for {...
其實官方給的example中並沒有帶祕密的解壓縮,這個問題困擾了我幾個小時,最終在我碰到有網友寫的這個依賴才得以解決:github.com/yeka/zip"
,再次表示十分
感謝,在此能將example共享出來也算是功德一件哈~golang
這裏的處理其實十分簡單,其實就是在每次循環zip文件的時候判斷一下IsEncrypted()
,在true的時候SetPassword(password)
,後面使用io之後的文件就是
非加密文件了,so easy ~shell
r, err := zip.OpenReader(fullZipFile)
for _, f := range r.File {...
f.SetPassword(password)
func writeFile(filePath string, f *zip.File) error {...
其實這是對前幾個功能對一個綜合,我對目的是下載阿里雲的RDS的物理備份並解壓,當然你須要先參閱官方api文檔,在這裏DescribeBackups
其實一開始我並不知道,全部的備份文件都須要查詢到其下載連結後纔可下載,獲取到下載連結後其餘的事情就循序漸進了~,如下是我實現的思路,可參閱~json
client, err := rds.NewClientWithAccessKey("cn-hangzhou", "您的accessKeyId", "您的accessKeySecret")
request := rds.CreateDescribeBackupsRequest()
respJsonStr, err := client.DescribeBackups(request)
data := &BackupInfo{}
json.Unmarshal(respJsonStr.GetHttpContentBytes(), data)
downloadUrl := data.Items.BackupItem[0].BackupDownloadURL
backupDate := data.Items.BackupItem[0].BackupStartTime[0:10]
err := util.DownloadFile(downloadUrl, filePath)
err2 := util.UnTarGz(filePath, unTarGzFilePath)
一開始我是想將打包好的tools部署後使用命令行調用,這樣會顯得靈活一些,後來覺得這樣使用太過與零碎了,並且window下的執行環境也是個問題,最後才作決定將一組
功能當堵打包,然後使用windows的計畫任務調用,不過既然做為一種可行的方式(linux下比較可行),因此就參閱了個簡單的Demo,讀者能夠根據這個Demo改寫上述功能windows
這裏是結合著命令行實現了個文件下載功能api
args\[0\]
是你打包好的exe可執行程序自己(windows環境下)
main_exec.exe https://www.xxx.com/path/xx.zip D:/tmp
os.Args
獲取到的參數有仨 os.Args[0]:main_exec.exe
,os.Args[1]:https://www.xxx.com/path/xx.zip
,os.Args[2]:D:/tmp
url := os.Args[1]
filename := os.Args[2]
err := util.DownloadFile(url, filename)
本章的內容比較零散,望讀者諒解,另外,以上內容的全部代碼(包括已經打包好的exe程序)我已推送至github rds_backup 這些代碼所有使用GO語言實現,當然以上內容可能並不完整,全黨是拋磚引玉,一個解決問題的方式,若有須要改進或優化的地方請留言哈~