如何用自解壓腳本打包軟件和數(shù)據(jù)
譯文【51CTO.com快譯】有時(shí),您需要一種快速可靠的方式向用戶分發(fā)數(shù)據(jù)或軟件,無(wú)需使用包管理器(比如說(shuō),最終用戶可能沒有安裝應(yīng)用程序的root訪問權(quán)限)。
這個(gè)問題可以通過使用容器和Podman或Docker來(lái)解決,但如果它們?cè)谀繕?biāo)系統(tǒng)上沒有,怎么辦?如果要求之一是應(yīng)用程序在裸機(jī)環(huán)境中正常工作,又怎么辦?
您可以將Python與pip一起使用(您可能知道也可以打包非Python工件),但是那樣可能面臨一些安裝上的限制(虛擬環(huán)境或--user選項(xiàng)),更不用說(shuō)需要樣板代碼來(lái)打包Python代碼了。
我在本文中演示了一種非常小巧但有效的技術(shù)來(lái)編寫不需要提升權(quán)限的自解壓腳本。
設(shè)置您的數(shù)據(jù)
Damiaan Zwietering有一個(gè)很酷的關(guān)于新冠病毒的Git代碼存儲(chǔ)庫(kù),帶有數(shù)據(jù)和可視化(Jupyter書籍和Excel電子表格),但沒有安裝程序。假設(shè)您想將其提供給自己的用戶,但他們無(wú)權(quán)訪問Git。您就可以為用戶創(chuàng)建自解壓安裝程序。
在實(shí)際情況下,您已經(jīng)擁有想要分發(fā)的數(shù)據(jù)。但是您有一些示例數(shù)據(jù)要處理,首先將該存儲(chǔ)庫(kù)克隆到主目錄:
- $ git clone https://gitlab.com/dzwietering/corona.git
現(xiàn)在有很多數(shù)據(jù)和不那么淺的目錄結(jié)構(gòu),但是您可以使用git archive命令創(chuàng)建一個(gè).tar文件:
- $ cd $HOME / corona
- $ git archive --verbose --output $tempdir/corona.tar.gz HEAD
對(duì)于本示例,該打包文件是您想要與用戶共享的文件。
自解壓腳本的結(jié)構(gòu)
自解壓腳本分為以下幾個(gè)部分:
1. 幫助用戶提取數(shù)據(jù)的代碼(“有效載荷”)
2. 從腳本中分離數(shù)據(jù)(要提取)的錨點(diǎn)
3. 提取其后數(shù)據(jù)的錨點(diǎn)位置
事實(shí)證明,Bash非常擅長(zhǎng)以這種方式來(lái)定義腳本。
創(chuàng)建有效載荷
這里有個(gè)想法:假設(shè)您需要分發(fā)的數(shù)據(jù)是一個(gè)含有許多腳本和數(shù)據(jù)的目錄。您希望保持權(quán)限和結(jié)構(gòu)完好無(wú)缺,您希望用戶將其“解壓縮”到主目錄中。
這聽起來(lái)像是tar命令的工作。但是假設(shè)您的用戶不知道如何使用tar,或者他們?cè)诎惭btarball文件時(shí)想要特殊選項(xiàng)(比如僅提取特定文件)。
另一個(gè)問題是您的.tar存檔是一個(gè)二進(jìn)制文件。如果您要通過電子郵件發(fā)送,必須使用Uuencode或Base64對(duì)其進(jìn)行正確編碼,以便安全傳輸。
該怎么辦?不要扔掉.tar文件。相反,準(zhǔn)備好它,以便您可以將其附加到Bash腳本(您將很快編寫):
- $ base64 $tempdir/corona.tar.gz > $tempdir/corona_payload
- $ file $tempdir/corona_payload
- /tmp/tmp.8QNdzdKEkG/corona_payload: ASCII text
從.tar文件提取數(shù)據(jù)
您可以將所有內(nèi)容倒到新目錄中:
- $ newbase=$HOME/coronadata
- $ test ! -d $newbase && /bin/mkdir --parents --verbose $newbase
- $ tar --directory $newbase \
- --file corona.tar.gz --extract --gzip --verbose
也可以僅提取其中的一部分,比如措施、試驗(yàn)和測(cè)試目錄。
- $ newbase=$HOME/coronadata
- $ test ! -d $newbase && /bin/mkdir --parents --verbose $newbase
- $ tar --directory $newbase --file corona.tar.gz \
- --extract --gzip --verbose measures experiment test
針對(duì)這次演練,將全部?jī)?nèi)容提取到基本目錄(比如$HOME),因此結(jié)果如下:
- $HOME/$COVIDUSERDIR
剖析自解壓腳本
以下是我的自解壓腳本的代碼。您可以將腳本保存在自己的Git存儲(chǔ)庫(kù)中,并重復(fù)用于其他部署環(huán)境。要注意的事項(xiàng)如下:
- SCRIPT_END是有效載荷在腳本里面開始的位置。
- 它凈化用戶輸入。
- 一旦您搞清楚了元數(shù)據(jù)的位置,從腳本中提取($0),重新解碼成二進(jìn)制代碼,然后拆包。
- #!/usr/bin/env bash
- # Author: Jose Vicente Nunez
- SCRIPT_END=$(/bin/grep --max-count 2 --line-number ___END_OF_SHELL_SCRIPT___ "$0"| /bin/cut --field 1 --delimiter :| /bin/tail -1)|| exit 100
- ((SCRIPT_END+=1))
- basedir=
- while test -z "$basedir"; do
- read -r -p "Where do you want to extract the COVID-19 data, relative to $HOME? (example: mydata -> $HOME/mydata. Press CTRL-C to abort):" basedir
- done
- :<<DOC
- Sanitize the user input. This is quite restrictive, so it depends of the real application requirements.
- DOC
- CLEAN=${basedir//_/}
- CLEAN=${CLEAN// /_}
- CLEAN=${CLEAN//[^a-zA-Z0-9_]/}
- if [ ! -d "$HOME/$CLEAN" ]; then
- echo "[INFO]: Will try to create the directory $HOME/$CLEAN"
- if ! /bin/mkdir --parent --verbose "$HOME/$CLEAN"; then
- echo "[ERROR]: Failed to create $HOME/$CLEAN"
- exit 100
- fi
- fi
- /bin/tail --lines +"$SCRIPT_END" "$0"| /bin/base64 -d| /bin/tar --file - --extract --gzip --directory "$HOME/$CLEAN"
- exit 0
- # Here's the end of the script followed by the embedded file
- ___END_OF_SHELL_SCRIPT___
那么您如何將有效載荷添加到腳本?只要用一點(diǎn)cat粘合劑將兩部分組合起來(lái):
- $ cat covid_extract.sh \
- $tempdir/corona_payload > covid_final_installer.sh
使它變成可執(zhí)行:
- $ chmod u+x covid_final_installer.sh
您可以看到安裝程序如何與有效載荷結(jié)合起來(lái)。由于含有有效載荷,它很龐大。
運(yùn)行安裝程序
這管用嗎?不妨親自試一下:
- $ ./covid_final_installer.sh
- Where do you want to extract the COVID-19 data, relative to /home/josevnz? (example: mydata -> /home/josevnz/mydata. Press CTRL-C to abort):COVIDDATA
- [INFO]: Will try to create the directory /home/josevnz/COVIDDATA
- /bin/mkdir: created directory '/home/josevnz/COVIDDATA'
- $ tree /home/josevnz/COVIDDATA
- /home/josevnz/COVIDDATA
- ├── acaps_covid19_government_measures_dataset_0.xlsx
- ├── acaps_covid19_government_measures_dataset.xlsx
- ├── COVID-19-geographic-disbtribution-worldwide.xlsx
- ├── EUCDC.ipynb
- ├── experiment
- ...
自解壓安裝程序很有用
我覺得自解壓安裝程序很有用,原因多多。
首先,您可以隨意將它們做成很復(fù)雜或很簡(jiǎn)單。最復(fù)雜的部分在于規(guī)定腳本應(yīng)從哪里提取有效載荷。
知道這種方法很實(shí)用,因?yàn)閻阂廛浖惭b程序也使用這種方法?,F(xiàn)在您有了更充分的準(zhǔn)備可以在腳本中發(fā)現(xiàn)這樣的代碼。同樣重要的是,現(xiàn)在您知道如何通過在自己的自解壓腳本中驗(yàn)證用戶輸入來(lái)阻止外殼注入濫用現(xiàn)象。
原文標(biāo)題:Package software and data with self-compressed scripts,作者:Jose Vicente Nunez
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】