shellcheck 是一款實用的 shell腳本靜態檢查工具。html
首先,能夠幫助你提早發現並修復簡單的語法錯誤,節約時間。每次都須要運行才發現寫錯了一個小地方,確實很是浪費時間。
其次,能夠針對你當前不夠完善不夠健壯的寫法,提供建議,幫助你提早繞開一些坑,避免等問題真的發生了纔去調試處理。git
在其介紹中,目標是針對全部用戶的,從初學者到高手,都用得上github
很是簡單,在網頁 https://www.shellcheck.net 上,貼入你的腳本,運行檢查便可正則表達式
下載後,在命令行中調用 shellcheck yourscript 便可shell
推薦將shellcheck直接集成到平常編輯器中,這樣就能夠直接在編輯器中查看ShellCheck建議,以最快速度發現並修復問題。express
在大多數發行版的包管理中,已經有shellcheck了,如在基於debian的機器上數組
apt-get install shellcheck
其餘系統的具體安裝方式,能夠查閱 shellcheck 的github首頁介紹bash
固然,也能夠選擇自行從源碼安裝。app
那麼shellcheck具體會檢查一些什麼問題呢,如下給出一個不完整的問題檢查列表。
能夠看下,你是否都能意識到這樣的寫法時有錯誤或隱患的。
若是發現有本身不知道的或本身容易錯漏的,那麼也許你也應該花點時間,裝上shellcheck。less
echo $1 # Unquoted variables #變量未加引號 find . -name *.ogg # Unquoted find/grep patterns #find/grep 的匹配模式未加引號 rm "~/my file.txt" # Quoted tilde expansion #引號中的波浪符擴展 v='--verbose="true"'; cmd $v # Literal quotes in variables # 變量中的字面引號 for f in "*.ogg" # Incorrectly quoted 'for' loops # 錯誤的for循環 touch $@ # Unquoted $@ # $@未加引號 echo 'Don't forget to restart!' # Singlequote closed by apostrophe # 單引號被撇號意外關閉了 echo 'Don\'t try this at home' # Attempting to escape ' in '' #試圖在單引號括起來的部分中加上一個單引號 echo 'Path is $PATH' # Variables in single quotes # 將變量用單引號括起來 trap "echo Took ${SECONDS}s" 0 # Prematurely expanded trap #過早擴展陷阱
ShellCheck 能夠識別大多數不正確的條件判斷語句
[[ n != 0 ]] # Constant test expressions # 常量測試表達式 [[ -e *.mpg ]] # Existence checks of globs # 對文件是否存在進行檢查時,使用通配符 [[ $foo==0 ]] # Always true due to missing spaces #因爲缺少空格,結果老是爲真 [[ -n "$foo " ]] # Always true due to literals #因爲字面值存在,結果老是爲真 [[ $foo =~ "fo+" ]] # Quoted regex in =~ # 在 =~ 中使用正則表達式 [ foo =~ re ] # Unsupported [ ] operators # 不支持的[]運算符 [ $1 -eq "shellcheck" ] # Numerical comparison of strings # 比較數字和字符串 [ $n && $m ] # && in [ .. ] # 在[]中使用&&運算符 [ grep -q foo file ] # Command without $(..) #命令缺乏了$(..) [[ "$$file" == *.jpg ]] # Comparisons that can't succeed #沒法成功的比較 (( 1 -lt 2 )) # Using test operators in ((..)) #在((..))中使用比較
ShellCheck 能夠識別對一些命令的錯誤使用
grep '*foo*' file # Globs in regex contexts #在grep的正則表達式中先後使用通配符 find . -exec foo {} && bar {} \; # Prematurely terminated find -exec # 使find -exec 過早結束 sudo echo 'Var=42' > /etc/profile # Redirecting sudo # 重定向sudo time --format=%s sleep 10 # Passing time(1) flags to time builtin # 將time(1)的標誌傳遞給內建的time while read h; do ssh "$h" uptime # Commands eating while loop input # 一個獲取輸入的while循環中,使用一樣會獲取輸入的命令 alias archive='mv $1 /backup' # Defining aliases with arguments # 定義使用參數的alias tr -cd '[a-zA-Z0-9]' # [] around ranges in tr # 在tr的參數範圍外使用[] exec foo; echo "Done!" # Misused 'exec' # 錯誤地使用exec find -name \*.bak -o -name \*~ -delete # Implicit precedence in find # 在find中的隱式優先級 # find . -exec foo > bar \; # Redirections in find #find中的重定向 f() { whoami; }; sudo f # External use of internal functions #在外部使用內部函數
ShellCheck 識別不少初學者的語法錯誤
var = 42 # Spaces around = in assignments #等號兩邊的空格 $foo=42 # $ in assignments # 對變量賦值時使用了$ for $var in *; do ... # $ in for loop variables # 在循環變量處使用$ var$n="Hello" # Wrong indirect assignment #錯誤的變量 echo ${var$n} # Wrong indirect reference #錯誤的引用 var=(1, 2, 3) # Comma separated arrays #逗號分割數組 array=( [index] = value ) # Incorrect index initialization #錯誤的索引初始化 echo $var[14] # Missing {} in array references #引用數組缺乏{} echo "Argument 10 is $10" # Positional parameter misreference #錯誤的位置參數引用 if $(myfunction); then ..; fi # Wrapping commands in $() #在命令外加上$() else if othercondition; then .. # Using 'else if' #使用else if f; f() { echo "hello world; } # Using function before definition 在函數定義以前使用函數 [ false ] # 'false' being true # 此處false爲true if ( -f file ) # Using (..) instead of test #使用()取代測試條件
ShellCheck 能夠提出一些風格改進建議
[[ -z $(find /tmp | grep mpg) ]] # Use grep -q instead #改爲使用grep -q a >> log; b >> log; c >> log # Use a redirection block instead #改爲使用重定向塊 echo "The time is `date`" # Use $() instead #改爲使用$() cd dir; process *; cd ..; # Use subshells instead #改爲使用subshell echo $[1+2] # Use standard $((..)) instead of old $[] #改爲使用標準的$((..)) echo $(($RANDOM % 6)) # Don't use $ on variables in $((..)) #在$((..))中不要使用$ echo "$(date)" # Useless use of echo # 不必的echo cat file | grep foo # Useless use of cat #不必的cat
ShellCheck 能夠識別一些數據和拼寫錯誤
args="$@" # Assigning arrays to strings # 將數組賦值給字符串 files=(foo bar); echo "$files" # Referencing arrays as strings # 把數字當成字符串引用 declare -A arr=(foo bar) # Associative arrays without index # 不帶索引組合數組 printf "%s\n" "Arguments: $@." # Concatenating strings and arrays # 鏈接字符串和數組 [[ $# > 2 ]] # Comparing numbers as strings # 把數字當成字符串比較 var=World; echo "Hello " var # Unused lowercase variables # 未使用的小寫變量 echo "Hello $name" # Unassigned lowercase variables # 未賦值的小寫變量 cmd | read bar; echo $bar # Assignments in subshells # 在subshells中進行賦值 cat foo | cp bar # Piping to commands that don't read # 經過管道傳遞數據給一個不會作讀取的程序 printf '%s: %s\n' foo # Mismatches in printf argument count # pirintf參數數量不匹配
ShellCheck能夠作出一些加強腳本魯棒性的建議
rm -rf "$STEAMROOT/"* # Catastrophic rm # 可能致使災難性後果的rm touch ./-l; ls * # Globs that could become options # 使用了可能變成選項的通配符 find . -exec sh -c 'a && b {}' \; # Find -exec shell injection # Find -exec shell注入 printf "Hello $name" # Variables in printf format # 在printf的格式化參數中使用變量 for f in $(ls *.txt); do # Iterating over ls output # 在ls的輸出上進行迭代 export MYVAR=$(cmd) # Masked exit codes # 使退出碼模糊 case $version in 2.*) :;; 2.6.*) # Shadowed case branches # 隱蔽的case分支
ShellCheck 警告你使用了 shebang 不支持的特性.。
好比,當你設置 shebang 爲 #!/bin/sh
是, ShellCheck 對相似 checkbashisms
的可移植性問題發出警告。
echo {1..$n} # Works in ksh, but not bash/dash/sh #在 ksh 中可用,在 bash/dash/sh 中不可用 echo {1..10} # Works in ksh and bash, but not dash/sh #在 ksh 中可用,在 bash/dash/sh 中不可用 echo -n 42 # Works in ksh, bash and dash, undefined in sh #在 ksh/bash/dash 中可用,在 sh 中不可用 trap 'exit 42' sigint # Unportable signal spec # 不具備可移植性的信號細節 cmd &> file # Unportable redirection operator # 不具備可移植性的重定向操做 read foo < /dev/tcp/host/22 # Unportable intercepted files # 不具備可移植性的截獲的文件 foo-bar() { ..; } # Undefined/unsupported function name # 未定義/不支持的函數名 [ $UID = 0 ] # Variable undefined in dash/sh # dash/sh 中未定義的變量 local var=value # local is undefined in sh # sh 中未定義local time sleep 1 | sleep 5 # Undefined uses of 'time' # 使用了time未定義的用法
ShellCheck 能夠識別到一些其餘問題
PS1='\e[0;32m\$\e[0m ' # PS1 colors not in \[..\] # PS1 的顏色不在\[..\] 中 PATH="$PATH:~/bin" # Literal tilde in $PATH # $PATH中的波浪號 rm 「file」 # Unicode quotes #Unicode 引號 echo "Hello world" # Carriage return / DOS line endings # 傳輸返回DOS行結束符/ echo hello \ # Trailing spaces after \ # \後面的行尾空格 var=42 echo $var # Expansion of inlined environment # 展開內聯環境變量 #!/bin/bash -x -e # Common shebang errors # shebang 命令錯誤 echo $((n/180*100)) # Unnecessary loss of precision # 沒必要要的精度丟失 ls *[:digit:].txt # Bad character class globs # 很差的通配符 sed 's/foo/bar/' file > file # Redirecting to input # 重定向到輸入 while getopts "a" f; do case $f in "b") # Unhandled getopts flags # 未處理的getopts標誌
以上就是shellcheck的介紹了,主要來自其github 的readme ,源碼在 github https://github.comf/koalaman/shellcheck
簡單實用,只要配置好了,就能夠持續爲你提供幫助。並且這個是建議性的,能夠本身根據實際狀況決定是否採納。即用即棄的臨時腳本,那兼容性等就不用太care。長期使用的,就仍是完善一下比較穩妥。
本文地址 https://www.cnblogs.com/zqb-all/p/10054594.html