Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
163 lines (117 sloc) 4.8 KB

看懂源碼基礎 - 批次檔除錯及排版工具

Author: Daniel YC Lin(林原志)
Contact: dlin.tw@gmail.com
Date: 2018-08-11

簡介

  • 批次檔:
    • Unix 系列: Xenix(1989 sh) -> SunOS(tcsh) -> RedHat(sh->bash) -> ArchLinux(2005 zsh)
    • Windows 系列: DOS(command.com) -> Windows(cmd.exe) -> PowerShell
  • 臉書社團:
    • 主持: Manjaro 及 Arch Linux Taiwan - 與時俱進,一邊更新一邊學
    • 主持: Golang Taiwan - 它的 killer application 應該算 Docker 吧!
    • 加入: 網樂通改機俱樂部 - 移植 ArchLinux 套件體系到 sh4 CPU
  • Open Source 社團: Hacking Thursday
  • web site: 派樂靈丹 www.twpda.com - 以 Assembly 修改 ROM
  • 近期學習: docker/golang/julia

緣起

shell script 批次檔, 通常以為簡單但也飽含玄機與陷阱, 自己寫的通常看的懂, 專家寫的那就不一定了, 先看欣賞兩篇小品吧!

小品解析

reflector.sh

reflector.sh 是一個將 Arch Linux download mirrors 網站依存取速度排序的工具

https://www.askapache.com/shellscript/reflector-ranking-mirrors/

  • line 1: https://en.wikipedia.org/wiki/Shebang_(Unix) # 只能代一個參數
  • line 22:
    • function: man bash 再查 Shell Function Definitions
    • {{{1: vim 編輯器 Voom 外掛
  • line 24:
    • if...else...fi: man bash 再查 Compound Commands (用 else 去查找到的)
    • '[[': man bash 再查 Compound Commands (用 [[ 找到)
    • -s: man bash 再查 CONDITIONAL EXPRESSIONS
  • line 25: cat: man cat
  • line 27:
  • line 44: trap: which trap, type trap, man which # SHELL BUILTIN COMMANDS
  • line 49:
    • mktemp: 建立暫存檔 # 最早是用 /tmp/$$.myfile
    • && ||: 查 '&&', 先 '&&' 再 '||'
  • line 50: uname 判斷主機 32 或 64 位元
  • line 58: '{' 和 '(' 不同, 不需要產生 sub-shell
  • line 60-61: 常用小工具 xargs, sort, head, cut, sed, awk
  • line 65: 覺得 exit $? 多寫, 最後的 ; 也是多寫的

全篇最重要技巧, 透過 xargs 同時以 curl 測試各網站連線速度

wait-for

wait-for 是用來等待別的 docker container 啟動的 script

https://github.com/eficode/wait-for/blob/master/wait-for

  • line 1: 用 sh 讓 https://en.wikipedia.org/wiki/BusyBox 也可以跑
  • line 3,4: 好習慣, 常數用全大寫
  • line 6: 函數用短寫法才會相容於 busybox 的 ash
  • line 12:
    • << USAGE: Here Documents
    • >&2: 輸出到 stderr
  • line 14: BUG: cmdname not defined
  • line 23: * for ... in ...; do ... done * `(backquote): 在bash 建議用 $(...) * seq: 是從 1..$TIMEOUT 小技巧
  • line 24: nc
  • line 33: sleep (bash 的 sleep 支援 0.1 秒)
  • line 39:
    • while...do...done
    • $#: 命令列參數個數, 'Special Parameters'
    • -gt: 數字比較, 查 man test
  • line 41: case ... in ... esac
  • line 45: shift 這裡的 1 可省略

全篇重點在使用 busybox 支援的 nc 小工具, 偵測 port 是否開放聽取

排版美化

  • 先用 git 備份舊版

  • shfmt https://github.com/mvdan/sh:

    go get -u mvdan.cc/sh/cmd/shfmt
    
  • .vimrc plugin 以 ":Shfmt" 排版:

    Plug 'z0mbix/vim-shfmt', { 'for': 'sh' }
     let g:shfmt_extra_args = '-s -i 2'
    

防錯

  • set -euo pipefail

  • shellcheck https://www.shellcheck.net/

  • vim plugin, https://github.com/vim-syntastic/syntastic:w 檢查, 以 :Erros 列出訊息列表, .vimrc 參考:

    Plug 'vim-syntastic/syntastic'
    set statusline+=%F\ %l\:%c
    set statusline+=%#warningmsg#
    set statusline+=%{SyntasticStatuslineFlag()}
    set statusline+=%*
    
    let g:syntastic_always_populate_loc_list = 0
    let g:syntastic_auto_loc_list = 0
    let g:syntastic_check_on_open = 0
    let g:syntastic_check_on_wq = 0
    
    " 可用這些指令 :SyntasticInfo :Errors :lnext :lprev
    

除錯

  • PS4='+t $BASH_SOURCE:$LINENO: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
  • read -rp "Enter" ans
  • caller: bash SHELL BUILTIN COMMANDS

未完待續

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.