2021-05-12 14:32:11
如何用 Bash 建立一個二進位制發布包
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的當前文件中。
-
把要發布的檔案打包
tar zcf test.tar./test
-
對打好的二進位制包做Base64編碼
base64 ./test.tar> test_base64.txt
-
準備安裝檔案的shell檔案
test_base64="";#test_base64中的所有內容
echo $test_base64|base64 -d >test.tar
tar zxf test.tar
rmtest.tar
#其他的安裝程式碼
寫到這裡,我們已經把道理將明白了。但是可不可以寫一個shell程式,專門來生成這樣的發布包軟體呢?當然可以。下面是我寫的這個打包程式的原始碼。
function mkpackage(){
target_dir=$1
felow_install_shell_command_file=$2
echo"tar -zcf ._test_dir.tar.gz $target_dir"
tar-zcf ._test_dir.tar.gz $target_dir
base64 ._test_dir.tar.gz >._base64
rm._test_dir.tar.gz
printf"test_base64="">install.sh
while IFS='' read -r line ||[[-n "$line"]];do
printf"$line">>install.sh
printf"n">>install.sh
done<./._base64
rm._base64
echo""">>install.sh
echo'printf $test_base64|base64 -d >._temp.tar.gz;'>>install.sh
echo'tar zxf ._temp.tar.gz'>> install.sh
echo'rm ._temp.tar.gz'>>install.sh
if[[-e $fellow_install_shell_command_file ]];then
cat $fellow_install_shell_command_file >>install.sh
fi
chmod+x install.sh
}
function usage(){
echo"usage:"
echo" $1 test_dir [the_command.sh]"
}
if[[ $#!=0]]
then
mkpackage $1 $2
else
usage $0
fi
這個程式接受兩個輸入引數,第一個表示要打的程式包目錄,第二個是解壓後,安裝動作的shell指令碼檔案。最後這個程式生成一個名為 install.sh 的檔案。執行 install.sh 之後,會首先得到加壓的程式包內容,然後執行第二個引數指定的 shell 指令碼的內容。這樣我們就做了用Shell發布二進位制檔案的一個打包程式。當然了,在最後發布之前,還需要把這個shell壓縮一下。以便消除因為Base64編碼而帶來的檔案長度的變大的影響。
本文永久更新連結地址:http://www.linuxidc.com/Linux/2015-09/123514.htm
相關文章