亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Linux Shell > 正文

十三個寫好shell腳本的技巧分享

2020-07-27 18:48:11
字體:
來源:轉載
供稿:網友

前言

產品的最終用戶通常不懂技術,所以不管你怎么折騰產品代碼都無所謂。但腳本代碼不一樣,它們是開發人員寫給開發人員的。

有多少次,你運行./script.sh,然后輸出一些東西,但卻不知道它剛剛都做了些什么。這是一種很糟糕的腳本用戶體驗。我將在這篇文章中介紹如何寫出具有良好開發者體驗的 shell 腳本。

產品的最終用戶通常不懂技術,所以不管你怎么折騰產品代碼都無所謂。但腳本代碼不一樣,它們是開發人員寫給開發人員的。

這樣會導致一些問題:

  • 混亂的腳本――我知道,我們都是工程師,讀得懂代碼,但即使這樣,也請為我們這些對 Shell 腳本不是很熟練的人考慮一下(我們在寫代碼時也會為你們考慮的)。
  • 滿屏的日志和錯誤輸出――就算我們也是工程師,并不代表我們了解你所做的一切。
  • 弄得一團糟卻沒有做好清理工作――是的,我們可以順著你的腳本手動撤銷變更,但你真的會讓那些信任你的腳本的人這么做嗎?

所以,我們可以通過一些方法來為自己和別人寫出更好的 shell 腳本。這里給出的所有示例都可以使用與 POSIX 標準兼容的 shell 運行(#!/bin/sh),因為它是最常用的。嫌文章太長了可以只看以下總結部分:

  • 提供--help標記
  • 檢查所有命令的可用性
  • 獨立于當前工作目錄
  • 如何讀取輸入:環境變量 vs. 標記
  • 打印對系統執行的所有操作
  • 如果有必要,提供--silent選項
  • 重新開啟顯示
  • 用動畫的方式顯示進度
  • 用顏色編碼輸出
  • 出現錯誤立即退出腳本
  • 自己執行清理工作
  • 在退出時使用不同的錯誤碼
  • 在結束時打印一個新行

有時間的話可以接著往下看具體內容:

提供--help標記

安裝在系統上的二進制文件通常帶有man幫助文檔,但對于腳本來說就不一定了。因此我們通常需要為腳本提供-h或--help標記來打印有關如何使用腳本的信息。如果其他工程師需要修改腳本,這也可以作為腳本的內聯文檔:

#!/bin/shif [ ${#@} -ne 0 ] && [ "${@#"--help"}" = "" ]; then printf -- '...help.../n'; exit 0;fi;

這段腳本先計算參數長度(${#@} -ne 0),只有當參數長度不為零時才會檢查--help標記。下一個條件會檢查參數中是否存在字符串“--help” 。第一個條件是必需的,如果參數長度為零則不需要打印幫助信息。

檢查所有命令的可用性

腳本通常會調用其他腳本或二進制文件。在調用可能不存在的命令時,請先檢查它們是否可用??梢允褂谩癱ommand -v 二進制文件名稱”來執行此操作,看看它的退出代碼是否為零。如果命令不可用,可以告訴用戶應該如何獲得這個二進制文件:

#!/bin/sh_=$(command -v docker);if [ "$?" != "0" ]; then printf -- 'You don/'t seem to have Docker installed./n'; printf -- 'Get it: https://www.docker.com/community-edition/n'; printf -- 'Exiting with code 127.../n'; exit 127;fi;# ...

獨立于當前工作目錄

從不同的目錄執行腳本可能會發生錯誤,這樣的腳本沒有人會喜歡。要解決這個問題,請使用絕對路徑(/path/to/something)和腳本的相對路徑(如下所示)。

可以使用dirname $0引用腳本的當前路徑:

#!/bin/shCURR_DIR="$(dirname $0);"printf -- 'moving application to /opt/app.jar';mv "${CURR_DIR}/application.jar" /opt/app.jar;

如何讀取輸入:環境變量 vs. 標記

腳本通過兩種方式接受輸入:環境變量和選項標記(參數)。根據經驗,對于不影響腳本行為的值,可以使用環境變量,而對于可能觸發腳本不同流程的值,可以使用腳本參數。

不影響腳本行為的變量可能是訪問令牌和 ID 之類的東西:

#!/bin/sh# do thisexport AWS_ACCESS_TOKEN='xxxxxxxxxxxx';./provision-everything# and not./provisiong-everything --token 'xxxxxxxxxxx';

影響腳本行為的變量可能是需要運行實例的數量、是異步還是同步運行、是否在后臺運行等參數:

#!/bin/sh# do this./provision-everything --async --instance-count 400# and notINSTANCE_COUNT=400 ASYNC=true ./provision-everything

打印對系統執行的所有操作

腳本通常會對系統執行有狀態的更改。不過,由于我們不知道用戶何時會向發送SIGINT,也不知道腳本錯誤何時可能導致腳本意外終止,因此很有必要將正在做的事情打印在終端上,這樣用戶就可以在不去查看腳本的情況下回溯這些步驟:

#!/bin/shprintf -- 'Downloading required document to ./downloaded... ';wget -o ./downloaded https://some.site.com/downloaded;printf -- 'Moving ./downloaded to /opt/downloaded...';mv ./downloaded /opt/;printf -- 'Creating symlink to /opt/downloaded...';ln -s /opt/downloaded /usr/bin/downloaded;

在必要時提供--silent選項

有些腳本是為了將其輸出傳給其他腳本。雖說腳本都應該能夠單獨運行,不過有時候也有必要讓它們把輸出結果傳給另一個腳本??梢岳胹tty -echo來實現--silent標記:

#!/bin/shif [ ${#@} -ne 0 ] && [ "${@#"--silent"}" = "" ]; then stty -echo;fi;# ...# before point of intended output:stty +echo && printf -- 'intended output/n';# silence it again till end of scriptstty -echo;# ...stty +echo;exit 0;

重新開啟顯示

在使用stty -echo關閉腳本顯示之后,如果發生致命錯誤,腳本將終止,而且不會恢復終端輸出,這樣對用戶來說是沒有意義的。可以使用trap來捕捉SIGINT和其他操作系統級別的信號,然后使用stty echo打開終端顯示:

#!/bin/sherror_handle() { stty echo;}if [ ${#@} -ne 0 ] && [ "${@#"--silent"}" = "" ]; then stty -echo; trap error_handle INT; trap error_handle TERM; trap error_handle KILL; trap error_handle EXIT;fi;# ...

用動畫的方式顯示進度

有些命令需要運行很長時間,并非所有腳本都提供了進度條。在用戶等待異步任務完成時,可以通過一些方式告訴他們腳本仍在運行。比如在while循環中打印一些信息:

#!/bin/shprintf -- 'Performing asynchronous action..';./trigger-action;DONE=0;while [ $DONE -eq 0 ]; do ./async-checker; if [ "$?" = "0" ]; then DONE=1; fi; printf -- '.'; sleep 1;done;printf -- ' DONE!/n';

或者可以做一些更好玩的小玩意兒,比如 http://mywiki.wooledge.org/BashFAQ/034。

用顏色編碼輸出

在腳本中調用其他二進制文件或腳本時,對它們的輸出進行顏色編碼,這樣就可以知道哪個輸出來自哪個腳本或二進制文件。這樣我們就不需要在滿屏的黑白輸出文本中查找想要的輸出結果。

理想情況下,腳本應該輸出白色(默認的,前臺進程),子進程應該使用灰色(通常不需要,除非出現錯誤),使用綠色表示成功,紅色表示失敗,黃色表示警告。

#!/bin/shprintf -- 'doing something... /n';printf -- '/033[37m someone else's output /033[0m/n';printf -- '/033[32m SUCCESS: yay /033[0m/n';printf -- '/033[33m WARNING: hmm /033[0m/n';printf -- '/033[31m ERROR: fubar /033[0m/n';

可以使用/033[Xm,其中X代表顏色代碼。有些腳本使用/e而不是/033,但要注意/e不適用于所有的 UNIX 系統。

正確示范

可在.sh 中使用的所有顏色和修飾符 https://misc.flogisoft.com/bash/tip_colors_and_formatting。

出現錯誤立即退出腳本

set -e表示從當前位置開始,如果出現任何錯誤都將觸發EXIT。相反,set +e表示不管出現任何錯誤繼續執行腳本。

如果腳本是有狀態的(每個后續步驟都依賴前一個步驟),那么請使用set -e,在腳本出現錯誤時立即退出腳本。如果要求所有命令都要執行完(很少會這樣),那么就使用set +e。

#!/bin/shset +e;./script-1;./script-2; # does not depend on ./script-1./script-3; # does not depend on ./script-2set -e;./script-4;./script-5; # depends on success of ./script-4# ...

自己執行清理工作

大多數腳本在出現錯誤時不會執行清理工作,能夠做好這方面工作的腳本實屬罕見,但這樣做其實很有用,還可以省下不少時間。前面已經給出過示例,讓stty恢復正常,并借助trap命令來執行清理工作:

#!/bin/shhandle_exit_code() { ERROR_CODE="$?"; printf -- "an error occurred. cleaning up now... "; # ... cleanup code ... printf -- "DONE./nExiting with error code ${ERROR_CODE}./n"; exit ${ERROR_CODE};}trap "handle_exit_code" EXIT;# ... actual script...

在退出時使用不同的錯誤碼

在絕大多數 shell 腳本中,exit 0 表示執行成功,exit 1 表示發生錯誤。對錯誤與錯誤碼進行一對一的映射,這樣有助于腳本調試。

#!/bin/sh# ...if [ "$?" != "0" ]; then printf -- 'X happened. Exiting with status code 1./n'; exit 1;fi;# ...if [ "$?" != "0" ]; then printf -- 'Y happened. Exiting with status code 2./n'; exit 2;fi;

這樣做有另一個額外的好處,就是其他腳本在調用你的腳本時,可以根據錯誤碼來判斷發生了什么錯誤。

在結束時打印一個新行

如果你有在遵循腳本的最佳實踐,那么可能會使用printf代替echo(它在不同系統中的行為有所差別)。問題是printf在命令結束后不會自動添加一個新行,導致控制臺看起來是這樣的:

看起來是多么的平淡

這樣一點也不酷,可以通過簡單的方式打印一個新行:

#!/bin/sh# ... your awesome script ...printf -- '/n';exit 0;

這樣就可以得到:

好多了哈

別人會感謝你這么做的。

總結  

這篇文章大致總結了一些簡單易用的技巧,讓 shell 腳本更易于調試和使用。

原文鏈接:https://codeburst.io/13-tips-tricks-for-writing-shell-scripts-with-awesome-ux-19a525ae05ae

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色婷婷av一区二区三区在线观看| 久久人人爽人人爽人人片亚洲| 久久亚洲精品网站| 日韩精品在线观看视频| 日韩欧美一区二区三区久久| 有码中文亚洲精品| 亚洲淫片在线视频| 久久亚洲综合国产精品99麻豆精品福利| 久久精品久久久久久| 欧美日韩成人免费| 日韩欧美在线播放| 日本不卡免费高清视频| 日韩欧美一区视频| 国产激情999| 成人a在线观看| 中文字幕国产日韩| 欧美日韩在线第一页| 欧美在线激情网| 在线看日韩av| 日韩黄色高清视频| 日韩亚洲国产中文字幕| 国产一区玩具在线观看| 91高清免费视频| 精品亚洲精品福利线在观看| 欧洲美女免费图片一区| 最好看的2019的中文字幕视频| 黄色一区二区在线| 国产亚洲精品久久久久久777| 欧美精品制服第一页| 精品亚洲夜色av98在线观看| 毛片精品免费在线观看| 九九热视频这里只有精品| 91久久国产综合久久91精品网站| 中文字幕亚洲欧美日韩2019| 黑人狂躁日本妞一区二区三区| 欧美亚洲激情在线| 欧美最顶级的aⅴ艳星| 中文日韩在线观看| 日本午夜精品理论片a级appf发布| 91丝袜美腿美女视频网站| 欧美精品做受xxx性少妇| 亚洲国产精品嫩草影院久久| 国产一区二区三区在线观看网站| 精品国产一区二区三区久久久| 精品无人国产偷自产在线| 日韩天堂在线视频| 成人黄色av播放免费| 亚洲aⅴ男人的天堂在线观看| 亚洲精品日韩久久久| 国产亚洲欧洲高清| 精品久久久久久中文字幕大豆网| 久久香蕉国产线看观看网| 亚洲一区二区免费| 中文字幕精品—区二区| 性欧美xxxx交| 日韩精品视频中文在线观看| 亚洲成人av片在线观看| 欧美福利视频在线观看| 国产欧美精品xxxx另类| 日韩视频在线免费| 成人淫片在线看| 亚洲日本成人女熟在线观看| 亚洲欧美日韩精品久久亚洲区| 国产精品久久久久久久7电影| 国产日韩欧美一二三区| 国产精品com| 在线看国产精品| 国产免费一区视频观看免费| 成人在线精品视频| 免费91麻豆精品国产自产在线观看| 久久久久久久国产精品| 亚洲精品日韩久久久| 欧美成人免费一级人片100| 欧美精品video| 国模精品视频一区二区三区| 欧美理论电影在线观看| 国产精品白嫩初高中害羞小美女| 国产精品日韩av| 欧美国产日韩二区| 国产精品69久久| 亚洲人成绝费网站色www| 情事1991在线| 国产欧美亚洲视频| 精品视频在线播放| 亚洲激情在线观看视频免费| 国产欧美中文字幕| 亚洲福利视频二区| 日韩av网址在线观看| 日韩欧美在线视频日韩欧美在线视频| 国产精品成人观看视频国产奇米| 国产欧美日韩中文| 最好看的2019的中文字幕视频| 亚洲第一精品夜夜躁人人躁| 性欧美xxxx交| 欧美专区中文字幕| 亚洲人精品午夜在线观看| 国产精品久久久久91| 亚洲天堂免费观看| 91久久久久久久久久久| 日韩高清人体午夜| 久久999免费视频| 中文字幕国产精品| 色综合导航网站| 国产精品亚洲一区二区三区| 久久99久久99精品免观看粉嫩| 欧美午夜精品久久久久久久| 亚洲欧美制服中文字幕| 国产精品久久久999| 精品久久久av| 中文字幕亚洲色图| 国产色视频一区| 亚洲在线观看视频| 国产亚洲aⅴaaaaaa毛片| 国产精品扒开腿爽爽爽视频| 日韩成人av网址| 国产精品普通话| 51色欧美片视频在线观看| 日本久久久久久久| 日韩亚洲在线观看| 欧美成人亚洲成人| 久久成人综合视频| 中文精品99久久国产香蕉| 久久综合伊人77777蜜臀| 91探花福利精品国产自产在线| 黄色精品一区二区| 日韩成人激情视频| 日韩亚洲第一页| 亚洲男人的天堂在线| 美女扒开尿口让男人操亚洲视频网站| 久久精品免费播放| 欧美男插女视频| 日韩精品免费在线视频| 欧美一级淫片丝袜脚交| 欧美国产极速在线| 一区二区欧美激情| 欧美激情2020午夜免费观看| 日韩av免费看网站| 91精品在线观看视频| 91国产精品视频在线| 日本成熟性欧美| 日本成人免费在线| 97国产精品免费视频| 欧美日韩综合视频| 午夜精品久久久久久久99黑人| 亚洲美女久久久| 亚洲电影免费观看| 狠狠色狠狠色综合日日小说| 日韩av中文字幕在线播放| 成人免费黄色网| 亚洲性视频网址| 青青草原成人在线视频| 国产精品白嫩美女在线观看| 成人a在线视频| 在线播放亚洲激情| 亚洲人高潮女人毛茸茸| 久久久噜久噜久久综合| 欧美大片免费观看在线观看网站推荐| 国产一区二区香蕉| 国产欧亚日韩视频| 欧美日韩亚洲视频| 欧美寡妇偷汉性猛交| 欧美专区在线视频| 亚洲午夜久久久久久久| 欧美日韩xxxxx|