歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 如何用 Bash 創建一個二進制發布包

如何用 Bash 創建一個二進制發布包

日期:2017/2/28 13:57:35   编辑:Linux教程

Linux下安裝JDK的時候,Sun公司為JDK6的linux版本提供了一個shell的安裝包,用起來特別的好用,基本上和在Windows下安裝軟件沒什麼兩樣,shell文件執行之後,幾乎一切都系都設置好了,不用我們自己再動手設置PATH和JAVA_HOME,可是一個shell文件中是如何把二進制代碼包含進來的呢?

再例如淘寶為linux開發的淘寶插件,其實也是一個shell文件,但是執行這個shell文件之後,會安裝很多二進制的東西,同樣的問題,Shell只是文本文件,其中的二進制是怎麼來包含進來的呢?

從文本文件轉換出可執行文件,通過編譯器把源程序編程成可執行程序當然是可以的,但是前面提到的哪兩種情況都不是這樣做的。原因有兩個,第一對於大的項目來說,編譯需要的時間比較長,環境比較復雜;第二,更加重要的是,這樣做其實和從源代碼編譯程序沒什麼兩樣,對於不想讓用戶看到自己的源碼的商業軟件來說,這顯然是不可取的。

我們看看一般的程序是如何發布他們的二進制包的。

一般的程序,無非是把二進制和必要的文檔壓縮到一個壓縮文件中,然後通過README文檔的解釋程序的運行依賴什麼樣的假設,然後,你就可以把程序自行的移動到你想移動的地方去了。

很多時候,我們把程序放到任何地方都是可以運行的,但是程序可以運行,並不是說我們已經完成了程序的安裝,舉個例子來說,如果我們解壓JDK的二進制包之後,直接把程序移動到一個地方,然後把對應的bin目錄添加到PATH中就可以執行JDK提供的一系列工具了。

但是如果我們安裝其他的依賴與JDK的程序的時候,比如TOMCAT,那麼就會有問題。因為我們只是在PATH中加入了JDK的bin目錄而沒有制定JAVA_HOME這個環境變量,所以TOMCAT很可能會不能運行。

再比如我們使用man命令來查看一個程序的手冊,一般情況下二進制包中也會包含man文檔的,但是如果我們只是把解壓的二進制包的路徑添加到了PATH中,還不能在man中找到對應的文檔。

也正是因為這樣的原因吧,所以很多的二進制包的發布是使用deb或者rpm包來發布。安裝的時候少了很多的煩惱。要制做deb或者rpm包當然是需要學習成本的,而且deb和rpm也只能在對應的linux發行版中使用,如果想要為所有的Linux發行版都提供一個安裝文件,那麼使用shell文件來做無疑是最好的辦法。

Shell的學習成本低,而且對linux平台來說有通用,那麼是如何做到的呢?

想想我們在手動安裝的情形,無非是把壓縮的二進制包解壓,移動到特定的目錄下,在PATH變量中添加二進制包的可執行文件的路徑等等工作。首先我們把二進制包壓縮文件和shell文件分開。這樣一來,shell中只要完成解壓,然後把解壓後的目錄移動到指定的目錄中去,設置各種各樣的環境變量然後就完成了工作了。

但是我們在如何把壓縮文件和這個shell解壓之後要執行的命令的shell文件一起放到一個shell文件中呢?

要做到這一點,首先這個shell文件中,要有可以解壓的二進制內容,其次,這個shell要做的工作就是,把二進制內容,解壓,然後把原來手動做的工作在這個shell中用命令完成。再用shell寫個腳本完成一些手動完成的工作,這個任務比較容易,所以制作shell安裝包的難點就是如何在其中包含二進制內容了。

如何在一個文本文件中記錄二進制的內容呢?

這個問題早就被解決了。答案就是使用Base64編碼。在linux下就有base64 這個命令程序就是來做這個工作的。base64可以把文件進行base64的編碼,輸出的標准輸出中去或者把文件中的Base64編碼的內容解碼。命令base64除了可以對文件的內容做Base64的編解碼外,也可以對標准輸入中的數據進行Base64編輯碼。

有了這些預備的知識,那麼我們就可以看看具體的如何來做shell的二進制發布包了。

首先假設我們要發布的文件都放在名為test的當前文檔中。

  1. 把要發布的文件打包

    1. tar zcf test.tar./test
  2. 對打好的二進制包做Base64編碼

    1. base64 ./test.tar> test_base64.txt
  3. 准備安裝文件的shell文件

    1. test_base64="";#test_base64中的所有內容
    2. echo $test_base64|base64 -d >test.tar
    3. tar zxf test.tar
    4. rmtest.tar
    5. #其他的安裝代碼

寫到這裡,我們已經把道理將明白了。但是可不可以寫一個shell程序,專門來生成這樣的發布包軟件呢?當然可以。下面是我寫的這個打包程序的源代碼。

  1. function mkpackage(){
  2. target_dir=$1
  3. felow_install_shell_command_file=$2
  4. echo"tar -zcf ._test_dir.tar.gz $target_dir"
  5. tar-zcf ._test_dir.tar.gz $target_dir
  6. base64 ._test_dir.tar.gz >._base64
  7. rm._test_dir.tar.gz
  8. printf"test_base64=\"">install.sh
  9. while IFS='' read -r line ||[[-n "$line"]];do
  10. printf"$line\\">>install.sh
  11. printf"n">>install.sh
  12. done<./._base64
  13. rm._base64
  14. echo"\"">>install.sh
  15. echo'printf $test_base64|base64 -d >._temp.tar.gz;'>>install.sh
  16. echo'tar zxf ._temp.tar.gz'>> install.sh
  17. echo'rm ._temp.tar.gz'>>install.sh
  18. if[[-e $fellow_install_shell_command_file ]];then
  19. cat $fellow_install_shell_command_file >>install.sh
  20. fi
  21. chmod+x install.sh
  22. }
  23. function usage(){
  24. echo"usage:"
  25. echo" $1 test_dir [the_command.sh]"
  26. }
  27. if[[ $#!=0]]
  28. then
  29. mkpackage $1 $2
  30. else
  31. usage $0
  32. fi

這個程序接受兩個輸入參數,第一個表示要打的程序包目錄,第二個是解壓後,安裝動作的shell腳本文件。最後這個程序生成一個名為 install.sh 的文件。執行 install.sh 之後,會首先得到加壓的程序包內容,然後執行第二個參數指定的 shell 腳本的內容。這樣我們就做了用Shell發布二進制文件的一個打包程序。當然了,在最後發布之前,還需要把這個shell壓縮一下。以便消除因為Base64編碼而帶來的文件長度的變大的影響。

Copyright © Linux教程網 All Rights Reserved