<style> .reveal { font-size: 24px; font-family: 'Source serif pro', '源樣明體'; } .reveal pre code { font-size: 20px; } .reveal pre { line-height: 24px; } .reveal h1, .reveal h2, .reveal h3 { font-family: 'Source sans pro', '源樣黑體'; } em { color: #ED8; } </style> # 關於 Shell Script --- ## 殼層 Shell 讓使用者可以享受到 OS 提供的各種服務的介面。 * 命令列介面 (Command-Line Interface, CLI) * 圖形使用者介面 (Graphical User Interface, GUI)。 ![](https://i.imgur.com/rVvwOxs.png) ---- ## Unix Shell 就是在 Unix 系統內可以使用的 Shell。 https://en.wikipedia.org/wiki/Comparison_of_command_shells * sh -- Borne Shell (1979) * <em>bash</em> -- Borne Again Shell (1987) * csh, tcsh -- C Shell (1978) * fish -- Friendly Interactive Shell (2005) * zsh -- Z Shell (1990) 今天的重點是 bash。 ---- ## 腳本語言 Scripting Language 直譯器 (Interpreter) 會按照腳本指令逐行執行。 * 簡單且方便的小工具 ---- ## 內建指令 vs 外部程式 只要不是 Builtin command 的都是外部程式 https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html * 比方說 `cd`, `echo`, `alias` 是內建指令 * 比方說 `ls`, `ps`, `grep` 是外部程式 * 可以用 `which` 這支程式找出外部程式的位置 _為什麼 bash 找得到外部程式?_ ---- ## 環境變數 Environment Variables bash 提供自訂環境變數的功能,如果要存取這些環境變數,可以透過 `$` 符號加上變數名稱。通常 bash 裡面的環境變數名稱是習慣全大寫的。 ```shell $ echo $PATH ``` ---- ## 程式 Program vs 程序 Process 環境變數就是定義在 bash 跑起來這個程序(process)裡面的變數啦。如果把 `$PATH` 改掉了,可能就找不到外部程式了。 ```shell $ PATH='' $ which ls bash: which: No such file or directory ``` ---- ## 列出環境變數 讓我們來執行看看 `printenv` 這支程式,它可以幫我們列出現有的環境變數。 ```shell $ printenv ``` 覺得很難看怎麼辦?讓我們試著寫第一個腳本,把它上色。 --- # Example 1 ------ <font size=200%>Colorize `printenv`</font> ---- ## 簡單實作 `cat` 按照標準輸入的內容直接輸出。 ```bash #!/usr/bin/env bash while read line do echo "$line" done ``` `#!` 被稱為 shebang (或是 hashbang),通常出現在第一行可以讓 bash 知道你要用什麼環境或程式來執行這段腳本。 https://zh.wikipedia.org/wiki/Shebang <!-- .element: class="fragment" data-fragment-index="1" --> ![](https://avatars.githubusercontent.com/u/8587289?s=200&v=4) </div> <!-- .element: class="fragment" data-fragment-index="1" --> ---- ## 加上行號 ```bash= #!/usr/bin/env bash # 除了印出來以外,還加上現在是第幾行。 linenumber = 0 while read line do linenumber += 1 echo "Line $linenumber: $line" done ``` _哪裡出問題了?_ ---- ## 空白很重要 * `linenumber = 0` 的意思是,執行一支叫做 linenumber 的程式,然後傳入兩個參數 `=` 和 `0`。 * `linenumber= 0` 的意思是,設定變數 `linenumber` 是空白,然後執行名為 `0` 的程式。 ```bash= #!/usr/bin/env bash # 除了印出來以外,還加上現在是第幾行。 linenumber=0 while read line do linenumber+=1 echo "Line $linenumber: $line" done ``` _哪裡出問題了?_ ---- ## 用雙括弧代表算術運算 也可以用 `expr` 或是 `let` 指令。 ```bash= #!/usr/bin/env bash # 除了印出來以外,還加上現在是第幾行。 linenumber=0 while read line do ((linenumber += 1)) echo "Line $linenumber: $line" done ``` 或者也可以把 linenumber 宣告為整數。 ```bash=3 declare -i linenumber=0 ``` ---- ## 對輸入的每一行以等號分隔 想法:字串 $\to$ (split) 陣列 $\to$ (join) 把後面的黏起來 ```bash=4 # 用 "=" 當作分隔符號 delimiter 把字串分成好幾節 IFS="=" fields=($line) # 把第二節以後的黏回來 printf -v var "%s=" "${fields[@]:1}" var=${var%?} ``` ---- ## 加上顏色 * https://tforgione.fr/posts/ansi-escape-codes/ * https://askubuntu.com/questions/821157/print-a-256-color-test-pattern-in-the-terminal ![](https://i.imgur.com/okBgrw4.png) ---- ## 加上顏色 ```bash= #!/usr/bin/env bash # 檔案名稱取名為 02-colorize-kv.sh while read line do # 用 "=" 當作分隔符號 delimiter 把字串分成好幾節 IFS="=" fields=($line) # 把第二節以後的黏回來 printf -v var "%s=" "${fields[@]:1}" var=${var%?} # 把第一節加上顏色,加上第二節的資料 echo -e "\x1b[38;5;220m${fields[0]}\x1b[38;5;240m=\x1b[0m$var" done ``` ---- ## 把腳本當作程式執行 (會開啟新環境) ```shell $ printenv | ./02-colorize-kv.sh ``` ---- ## 小結:我們討論了什麼? * 環境變數 * 變數指派 * 變數運算 * $ 展開字元 * 字串切成陣列、IFS 分隔符號環境變數 * echo 和 printf * 文字上色 * | pipe --- # Example 2 ------ <font size=150%>Display Time in Different Time Zone</font> Wicked Cool Shell Scripts #21 ---- ## 時區 Timezone ![](https://i.imgur.com/F6WhNUk.png) https://en.wikipedia.org/wiki/Tz_database 搭配 `TZ="時區檔案名稱" date` 指令服用。 ---- ## 首先載入 Zoneinfo ```bash=9 zonedir="/usr/share/zoneinfo" if [[ ! -d $zonedir ]] ; then echo "No time zone database at $zonedir." >&2 exit 1 fi ``` * https://mywiki.wooledge.org/BashGuide/SpecialCharacters
{"metaMigratedAt":"2023-06-16T11:57:54.652Z","metaMigratedFrom":"YAML","title":"Shell Scripts","breaks":true,"slideOptions":"{\"slideNumber\":true,\"theme\":\"night\",\"transition\":\"convex\"}","contributors":"[{\"id\":\"a5ccd730-ffe0-47d3-a6b2-e31e1fcd4e37\",\"add\":4847,\"del\":584}]"}
    667 views
   Owned this note