script 嵌入 binary 檔案
下載的一些工具安裝檔案, 有時候是一個檔案頗大的 shell script. 這麼大的原因是 script 有塞入 binary file 的關係. 而這樣的好處應該就是可以把檔案集中成一個. 之外我覺得就是省去記檔案名稱吧 XDD. 此文章紀錄如何實作封裝與安裝的 script.
實作
這邊分兩個部分, 一個是負責封裝 install template script 與 binary 檔案的 pack script. 另一個則是 install template script. 這的 binary file 以 tar 檔案為例子.
Pack script
pack script 的流程主要是以 install template script 為樣板, 產生一個 install script. 接著在後面加入類似標籤的字串. 並在”下一行“塞入 tar 檔案.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #!/bin/sh read -p "Input a tar file path: " file # is file exsted > if [ ! -f ${file} ] then echo "no such file" exit 1 fi # check file extension extension=$(basename ${file} | tr "[:upper:]" "[:lower:]" | tr '.' '\n' | tail -n 1) if [ ${extension} != "tar" ] then echo "only support tar file" exit 1 fi # append install.sh first echo "packing...." cat install_script.sh > install.sh echo "PAYLOAD:" >> install.sh # append tar file cat ${file} >> install.sh echo "done...." |
line 2 取得想要塞入 script 的 tar 檔案路徑. line 5-9 判斷輸入的檔案是否存在. line 12-17 判斷輸入的檔案是否為 tar 檔案. 擷取副檔名的部分由 line 12 得到. 接下來就是 install script 與 tar 檔案的部分. line 20-21 透過 cat 指令把 install template script 內容輸出到 install.sh, 接著 line 22 塞入 PAYLOAD: 標籤. 最後透過 cat 指令, 把 tar 檔案附加於 script 後面.
Install template script
主要是負責安裝的部分, 會去尋找 install script 裡面的標籤 PAYLOAD:. 把下一行的部分都視為 tar 來做處理.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #!/bin/sh unpack() { file=$1 match=$(($(grep --text --line-number -m1 '^PAYLOAD:$' ${file} | cut -d ':' -f 1) + 1)) echo "extract payload after line ${match}" echo "create destination folder \"unpack\"" mkdir unpack echo "extracting...." tail -n +${match} $0 | tar -xvf - -C unpack } read -p "install ? (y/n) " ans result=`echo ${ans} | tr "[:upper:]" "[:lower:]"` # exit installation if [ ${result} != "y" ] then echo "exit installation" exit 0 fi # start to install unpack $0 exit 0 |
主要解說 unpack 函數. line 3-12 unpack 函數負責解壓以及安裝. line 6 在尋找 script 內的標籤 "PAYLOAD:". 利用 grep 指令去尋找開頭 PAYLOAD: 和 PAYLOAD: 結尾字串. -m1 表示搜尋到之後就可以停止搜尋了. line 9-11 則是把檔案解壓縮到所建立的 unpack 目錄底下.
執行
hayashiyoshihitoshis-MacBook-Pro:temp yijyun$ ls folder.tar install_script.sh pack.sh hayashiyoshihitoshis-MacBook-Pro:temp yijyun$ sh pack.sh Input a tar file path: folder.tar packing.... done.... hayashiyoshihitoshis-MacBook-Pro:temp yijyun$ ls folder.tar install.sh install_script.sh pack.sh
這邊有三個檔案, 分別為 tar 檔案, 負責封裝的 pack.sh 以及負責安裝 install_script.sh 樣板. 先使用 pack.sh 來封裝 install_script.sh 與 tar 檔案來成為一個 install.sh 檔案
hayashiyoshihitoshis-MacBook-Pro:temp yijyun$ sh install.sh install ? (y/n) y extract payload after line 29 create destination folder "unpack" extracting.... x dir/ x dir/temp.2 x dir/temp.3 x dir/temp.1 hayashiyoshihitoshis-MacBook-Pro:temp yijyun$ ls . unpack/* .: folder.tar install_script.sh unpack install.sh pack.sh unpack/dir: temp.1 temp.2 temp.3
這邊執行 install.sh 來進行安裝. 這邊會先建立一個 unpack 目錄. 接著把 script 內的 tar 檔案解壓縮於 unpack 目錄裡.
留言
張貼留言