「緯育 2026-0417.2」修訂間的差異
出自頂極製作所
(建立內容為「<h3>Linux 殼層 I/O、重導向與基礎 Shell Script 入門</h3> <br> 本次課程聚焦 Unix/Linux 殼層中的輸入輸出資料流與重導向(redirection…」的新頁面) |
|||
| 行 60: | 行 60: | ||
** 比較 >、>>、2>、2>>、&>、&>> 與 tee 的差異;根據需求選擇單純寫檔、追加、合併或同時顯示與保存。 | ** 比較 >、>>、2>、2>>、&>、&>> 與 tee 的差異;根據需求選擇單純寫檔、追加、合併或同時顯示與保存。 | ||
[[檔案:2026-0417-04.png|800px]] | [[檔案:2026-0417-04.png|800px]] | ||
=== Shell條件判斷基礎(if/elif/else與test) === | |||
* if語法結構與顏色分組概念 | |||
** 講義以顏色標示:藍色為必備(if條件+對應分支),紫色為elif(可多組),紅色為else(至多一組、可省略)。強調「藍色一定要」,紫色與紅色為選配。 | |||
** 標準語法示意:if [ 表達式 ]; then … elif [ 表達式 ]; then … else … fi。不同程式員縮排或括號風格不一;單行需以分號分隔,換行可省略分號。 | |||
* test/[] 返回值邏輯 | |||
** 布林結果僅兩種:0(真)與非0(假)。講師口語以「0與非0」對應分支:為真進入then(偶稱「LEN/Land」),為假進入else。 | |||
** 使用test(或[ … ])對數值、字串、檔案性質判斷;示範以-e/-d/-f等檔案測試參數檢查存在與型態(後文範例補充)。 | |||
* 命令區塊與風格 | |||
** then/elif/else區塊可含多行命令;可選單行(以分號分隔)或換行排列。示例引用「SS群」作者寫法:then連在同一行時需多一個分號;願意折行則可不加分號。 | |||
=== 檔案/目錄存在性檢查(範例:CheckSet) === | |||
* 需求與行為 | |||
** 讀取使用者輸入路徑,判斷檔案或目錄是否存在;存在則顯示「存在」,否則顯示「不存在」。示例提及/ETC(口誤示例ETC);若輸入EDC/EDC底下的東西不存在則回應「不存在」。 | |||
* 實作重點 | |||
** 使用read讀入變數(VAR/LAN等名稱示例,重點在存放輸入路徑)。 | |||
** if test -e "$VAR" 判斷存在性;結果0(存在)走then,非0(不存在)走else;echo輸出對應訊息。 | |||
** 目錄與檔案皆屬「檔案」:-e通用;需區分型態時用-d(目錄)或-f(一般檔案)。講師強調「目錄也是檔案」,如需嚴格區分請用對應選項。 | |||
* 實務提示 | |||
** 初學者可先照範例撰寫,反覆練習建立獨立能力。 | |||
** 測試與顯示時注意引號與路徑正確性。 | |||
=== 使用者輸入與防呆(read、Ctrl+C/Ctrl+D) === | |||
* read用法 | |||
** read -p "提示" 變數:帶提示字串讀取輸入並存入變數。 | |||
** read -s 可與 -p 搭配:遮蔽輸入(如密碼),螢幕不顯示,功能相同。 | |||
* 防呆與中斷處理 | |||
** 使用者可能亂按或用Ctrl+C、Ctrl+D中斷;可考慮關閉或捕捉這些中斷(先前課程提過可停用Ctrl+C/Ctrl+D)以避免不當跳出。 | |||
** 程式需考慮輸入超出預期集合(僅測Y/y時,其他字元會進入else,可能被視為Bug);建議擴充驗證、提供預設分支與清楚錯誤訊息。 | |||
=== 旗標判斷範例:Watermelon與包子邏輯 === | |||
* 條件敘事與邏輯重點 | |||
** 故事:下班買10個包子;若看到賣西瓜的就買一個西瓜。示例強調「邏輯」設計重要性:語法正確但條件寫錯仍會出現怪異行為(如只買一個包子,或拿了西瓜卻沒包子)。 | |||
* 實作細節 | |||
** 變數:WatermelonVendor,存放是否遇到賣西瓜(Y/N)。 | |||
** read -p "…按Y或N" WatermelonVendor:提示輸入Y/y或N。 | |||
** if test "$WatermelonVendor" == "Y" || "$WatermelonVendor" == "y":檢測大小寫Y。為真則echo「買10個包子與1個西瓜」;否則echo「買10個包子」。 | |||
* 擴充考量 | |||
** 僅測Y/y時,其他輸入(如N、88)落入else,可能不完善。建議加入輸入驗證、循環重試或錯誤提示。 | |||
** 可設定退出碼(exit/return值);後續程式若檢查上一段退出碼非0(例如9)可採不同行為。 | |||
=== 多條件數值判斷(範例:BunPrice) === | |||
* 需求規則 | |||
** 包子價格決定購買數量:價格≥20不買;15≤價格<20買5個;價格<15買10個。 | |||
* 實作與流程 | |||
** 變數:BunPrice(存放使用者輸入價格)。 | |||
** read -p "today bun price, … | |||
** \r(展示前兆ND轉義差異)" BunPrice:說明未加反斜線時字面中的$ND可能被展開;加反斜線可避免展開,演示輸出差異。 | |||
* if test "$BunPrice" -ge 20:echo「不買」;elif test "$BunPrice" -ge 15:echo「買5個」;else:echo「買10個」。示例輸入90、19、1對應三分支。 | |||
* 檔案/目錄判斷補充 | |||
** 再強調「目錄也是檔案」,但需分型態則用-d/-f等。 | |||
=== 多分支模式匹配(case語法與CheckPass) === | |||
* case語法結構與特點 | |||
** 語法:case "$變數" in pattern1) commands ;; pattern2) commands ;; … ) commands ;; esac。 | |||
** pattern的小括號只在右側;每個分支命令結尾以「;;」,最後以「esac」結束。 | |||
** 可添加多個分支(5、10、20皆可);預設分支用)表示「其他未匹配」。 | |||
** 打字技巧:對保留字(導向字)記憶的幽默口訣(如鍵序C左鍵A左鍵S左鍵E組成「case」),重點在理解而非死背。 | |||
* 範例:CheckPass(密碼對應大門) | |||
** read -p "Enter the password" Pass;需隱藏輸入則用read -sp(或-s -p)。 | |||
** case "$Pass" in | |||
** '12345') echo "Correct, door number 1 is open" ;; | |||
** … 其他密碼對應不同門 … | |||
** ) echo "You cannot enter" ;; | |||
** esac | |||
** 示範:輸入456456落入預設分支顯示不可進入;輸入12345匹配第一分支開門。 | |||
** 工程習慣:格式一致便於複製貼上增列分支;單/雙引號皆可用於字串pattern。 | |||
=== 使用模式集合判斷工作日/假日 === | |||
* 以數字集合判定 | |||
** 規則:星期一至星期五為工作日;星期六、星期日為休假。 | |||
*** case "$day" in | |||
*** [12345]) echo "work day" ;; | |||
*** [67]) echo "holiday" ;; | |||
*** ) … ;; | |||
*** esac | |||
** 說明中括號集合含義:「中括號表示其中任一字元」,非整串;例如day為4,匹配[12345]中的單一字元4。 | |||
* 可替代寫法 | |||
** 使用|分隔的多pattern(如1|2|3|4|5);或以if數值比較(day<=5為工作日,否則休假)。 | |||
** 若輸入域限定1–7,可用通配模式進一步精簡。 | |||
* 英文輸出示例 | |||
** 口語示範曾說"If the date is Thursday then it's a work day"與"If the date is Sunday then it's a work day."(後者口誤,依規則Sunday應為休假),重點在模式匹配方法而非句子本身。 | |||
=== 字元類別分類(大寫/小寫/數字/其他) === | |||
* 類別與用途 | |||
** 將輸入字元分類為upper(大寫字母)、lower(小寫字母)、digit(數字)、other(其他符號),以便依類型處理。 | |||
* 模式寫法 | |||
** 使用case與字元集合、範圍與否定,例如: | |||
*** [A-Z]) …(大寫) | |||
*** [a-z]) …(小寫) | |||
*** [0-9]) …(數字) | |||
*** *) …(其他) | |||
** 講師口語示範「兩個中括號、中括號還有個帽號(^)」等進階寫法,用於否定或複合集合;提醒寫法較「怪」但可直接套用範例。 | |||
* 實務應用 | |||
** 可用於輸入驗證、密碼強度檢查、命令分流等。 | |||
於 2026年4月27日 (一) 01:02 的修訂
Linux 殼層 I/O、重導向與基礎 Shell Script 入門
本次課程聚焦 Unix/Linux 殼層中的輸入輸出資料流與重導向(redirection)、錯誤輸出處理、常見轉向目的地、tee 的雙重導向實務,以及基礎 shell script的入門觀念與腳本閱讀。
內容涵蓋單引號/雙引號/反引號差異、echo 指令與 -n/-e 與跳脫序列的效果、IFS 在切詞與引號保護中的角色、連續指令與條件指令(&&、||)的短路行為、標準輸入/輸出/錯誤輸出(0/1/2)與輸出/輸入轉向(>、>>、<、<<)、錯誤輸出的分流與合併(2>、2>>、&>、&>>、> file 2>&1)、Here-document、多目標轉向(檔案、/dev/null、印表機、終端機),以及以 tee 配合管線在終端顯示同時寫檔的雙重導向。另以 find 結合時間條件與一般使用者權限的綜合練習示範如何同時管理 stdout 與 stderr;補充傳統 mail 指令的歷史與當代限制。課程亦帶領閱讀系統內的服務腳本(如 /etc/init.d 與與 SSH 相關腳本),強調先看懂結構與流程,再逐步補齊每個參數與設計的「為什麼」。
引號、echo 與 IFS
- 引號差異
- 單引號:內容完全字面化,不做變數與命令替換。
- 雙引號:允許變數展開、命令替換與少數跳脫(如 ", $, \、
等),其他文字維持字面性。
- 反引號(...):舊式命令替換,等價 $(...) 但可讀性較差;建議優先使用 $(...)。
- echo 行為
- 預設結尾換行;-n 取消換行;-e 啟用跳脫序列(
、\t、\a、\c 等)。
- \a 需硬體/環境支援才會有嗶聲;\c 可終止輸出後續內容。
- IFS 與切詞
- 預設以空白/換行/Tab 切詞;未加引號時易導致字串被過度切割。
- 以單/雙引號保護空白與特殊符號可避免誤解讀;更動 IFS 有風險,僅於必要時使用。
標準資料流與轉向(Redirection)
- 三大資料流
- stdin(0)、stdout(1)、stderr(2);終端下可同時看到 stdout 與 stderr。
- 輸出轉向
覆寫、>> 追加;可顯式指定 1>。
- 輸入轉向
- < 由檔案餵入 stdin;<< Here-document 以旗標結束多行輸入,旗標需精確匹配。
- 錯誤輸出轉向與合併
- 2> 覆寫錯誤輸出、2>> 追加錯誤輸出。
- 全部合併導向:&> file、&>> file,或以 > file 2>&1 達成;避免混淆與錯誤的非標準組合。
- 管線與 tee
- 指令 | tee 檔名:同時顯示於終端並寫入檔案;tee -a 追加。
- 適合即時監看且留存紀錄;若僅用 > 或 >>,終端可能看不到輸出。
轉向目的地與裝置
- 檔案:保存 stdout/stderr 供後續處理或稽核。
- /dev/null:丟棄不需要的輸出(例如 2> /dev/null 隱去錯誤訊息)。
- 印表機:傳統 /dev/lp0,現行多為 /dev/usb/lp0;可將文字直接轉向列印(受驅動/系統列印管理影響)。
- 終端機/主控台:/dev/ttyX;可將輸出送至指定終端,可能干擾對方畫面。
郵件寄送指令(歷史與限制)
- 傳統 mail -s "主旨" 收件者,郵件本文以 < 檔案或 Here-document 提供。
- 現況多未預裝 MTA,寄件者設定不當易被視為垃圾郵件;多由 Gmail 等取代。未安裝時會提示安裝,配置需設定寄件者資訊。
Shell script 入門與結構閱讀
- 入門與練習
- 以 hello 範例起步,再加上互動讀取姓名與時間;逐步引入中斷條件與狀態回報($?)的概念,強調每步都回應狀態以利監控與除錯。
- 使用條件與邏輯運算子將多行判斷濃縮為單行以快速達成條件效果。
- 連續與條件指令
- && 與 || 的短路行為:前者前一成功才執行後一;後者前一失敗才執行後一。
- 腳本位置與結構
- 常見於 /etc、/etc/init.d、/etc/rc.* 等;服務啟動腳本為可執行文字檔,shebang(#!/bin/sh)宣告直譯器。
- 常見元素:set(如 -e/-u 等錯誤處理策略)、test、if/else、case、函數、群組執行 ( )、管線與 grep、變數賦值、U-MASK 022 等。
- 以 sshd 為例,可透過執行輸出搭配 grep 關鍵字來判斷是否 OpenSSH,採用簡單可讀的檢測方式而非複雜程式。
- 學習策略
- 先看懂結構與流程,再逐步補充每個參數與設計理由;能讀懂與辨識模式(控制流、函數、變數、權限遮罩)是關鍵。
綜合練習與案例
- find 與時間條件(一般使用者)
- 在 /etc 或 /var/log 搜尋最近 N 分鐘內被存取的項目;同時分流 stdout 與 stderr(例如 stdout 至 find.out、錯誤至 find.err)。
- 權限不足多屬預期錯誤;執行時終端可能無即時輸出,完成後再檢視結果檔。
- tee 的雙重導向
- 對會產生多行輸出的指令(如 ls -l)配合 tee 寫檔並顯示;需要追加則 tee -a。
- 輸出管理與日誌
- 比較 >、>>、2>、2>>、&>、&>> 與 tee 的差異;根據需求選擇單純寫檔、追加、合併或同時顯示與保存。
Shell條件判斷基礎(if/elif/else與test)
- if語法結構與顏色分組概念
- 講義以顏色標示:藍色為必備(if條件+對應分支),紫色為elif(可多組),紅色為else(至多一組、可省略)。強調「藍色一定要」,紫色與紅色為選配。
- 標準語法示意:if [ 表達式 ]; then … elif [ 表達式 ]; then … else … fi。不同程式員縮排或括號風格不一;單行需以分號分隔,換行可省略分號。
- test/[] 返回值邏輯
- 布林結果僅兩種:0(真)與非0(假)。講師口語以「0與非0」對應分支:為真進入then(偶稱「LEN/Land」),為假進入else。
- 使用test(或[ … ])對數值、字串、檔案性質判斷;示範以-e/-d/-f等檔案測試參數檢查存在與型態(後文範例補充)。
- 命令區塊與風格
- then/elif/else區塊可含多行命令;可選單行(以分號分隔)或換行排列。示例引用「SS群」作者寫法:then連在同一行時需多一個分號;願意折行則可不加分號。
檔案/目錄存在性檢查(範例:CheckSet)
- 需求與行為
- 讀取使用者輸入路徑,判斷檔案或目錄是否存在;存在則顯示「存在」,否則顯示「不存在」。示例提及/ETC(口誤示例ETC);若輸入EDC/EDC底下的東西不存在則回應「不存在」。
- 實作重點
- 使用read讀入變數(VAR/LAN等名稱示例,重點在存放輸入路徑)。
- if test -e "$VAR" 判斷存在性;結果0(存在)走then,非0(不存在)走else;echo輸出對應訊息。
- 目錄與檔案皆屬「檔案」:-e通用;需區分型態時用-d(目錄)或-f(一般檔案)。講師強調「目錄也是檔案」,如需嚴格區分請用對應選項。
- 實務提示
- 初學者可先照範例撰寫,反覆練習建立獨立能力。
- 測試與顯示時注意引號與路徑正確性。
使用者輸入與防呆(read、Ctrl+C/Ctrl+D)
- read用法
- read -p "提示" 變數:帶提示字串讀取輸入並存入變數。
- read -s 可與 -p 搭配:遮蔽輸入(如密碼),螢幕不顯示,功能相同。
- 防呆與中斷處理
- 使用者可能亂按或用Ctrl+C、Ctrl+D中斷;可考慮關閉或捕捉這些中斷(先前課程提過可停用Ctrl+C/Ctrl+D)以避免不當跳出。
- 程式需考慮輸入超出預期集合(僅測Y/y時,其他字元會進入else,可能被視為Bug);建議擴充驗證、提供預設分支與清楚錯誤訊息。
旗標判斷範例:Watermelon與包子邏輯
- 條件敘事與邏輯重點
- 故事:下班買10個包子;若看到賣西瓜的就買一個西瓜。示例強調「邏輯」設計重要性:語法正確但條件寫錯仍會出現怪異行為(如只買一個包子,或拿了西瓜卻沒包子)。
- 實作細節
- 變數:WatermelonVendor,存放是否遇到賣西瓜(Y/N)。
- read -p "…按Y或N" WatermelonVendor:提示輸入Y/y或N。
- if test "$WatermelonVendor" == "Y" || "$WatermelonVendor" == "y":檢測大小寫Y。為真則echo「買10個包子與1個西瓜」;否則echo「買10個包子」。
- 擴充考量
- 僅測Y/y時,其他輸入(如N、88)落入else,可能不完善。建議加入輸入驗證、循環重試或錯誤提示。
- 可設定退出碼(exit/return值);後續程式若檢查上一段退出碼非0(例如9)可採不同行為。
多條件數值判斷(範例:BunPrice)
- 需求規則
- 包子價格決定購買數量:價格≥20不買;15≤價格<20買5個;價格<15買10個。
- 實作與流程
- 變數:BunPrice(存放使用者輸入價格)。
- read -p "today bun price, …
- \r(展示前兆ND轉義差異)" BunPrice:說明未加反斜線時字面中的$ND可能被展開;加反斜線可避免展開,演示輸出差異。
- if test "$BunPrice" -ge 20:echo「不買」;elif test "$BunPrice" -ge 15:echo「買5個」;else:echo「買10個」。示例輸入90、19、1對應三分支。
- 檔案/目錄判斷補充
- 再強調「目錄也是檔案」,但需分型態則用-d/-f等。
多分支模式匹配(case語法與CheckPass)
- case語法結構與特點
- 語法:case "$變數" in pattern1) commands ;; pattern2) commands ;; … ) commands ;; esac。
- pattern的小括號只在右側;每個分支命令結尾以「;;」,最後以「esac」結束。
- 可添加多個分支(5、10、20皆可);預設分支用)表示「其他未匹配」。
- 打字技巧:對保留字(導向字)記憶的幽默口訣(如鍵序C左鍵A左鍵S左鍵E組成「case」),重點在理解而非死背。
- 範例:CheckPass(密碼對應大門)
- read -p "Enter the password" Pass;需隱藏輸入則用read -sp(或-s -p)。
- case "$Pass" in
- '12345') echo "Correct, door number 1 is open" ;;
- … 其他密碼對應不同門 …
- ) echo "You cannot enter" ;;
- esac
- 示範:輸入456456落入預設分支顯示不可進入;輸入12345匹配第一分支開門。
- 工程習慣:格式一致便於複製貼上增列分支;單/雙引號皆可用於字串pattern。
使用模式集合判斷工作日/假日
- 以數字集合判定
- 規則:星期一至星期五為工作日;星期六、星期日為休假。
- case "$day" in
- [12345]) echo "work day" ;;
- [67]) echo "holiday" ;;
- ) … ;;
- esac
- 說明中括號集合含義:「中括號表示其中任一字元」,非整串;例如day為4,匹配[12345]中的單一字元4。
- 規則:星期一至星期五為工作日;星期六、星期日為休假。
- 可替代寫法
- 使用|分隔的多pattern(如1|2|3|4|5);或以if數值比較(day<=5為工作日,否則休假)。
- 若輸入域限定1–7,可用通配模式進一步精簡。
- 英文輸出示例
- 口語示範曾說"If the date is Thursday then it's a work day"與"If the date is Sunday then it's a work day."(後者口誤,依規則Sunday應為休假),重點在模式匹配方法而非句子本身。
字元類別分類(大寫/小寫/數字/其他)
- 類別與用途
- 將輸入字元分類為upper(大寫字母)、lower(小寫字母)、digit(數字)、other(其他符號),以便依類型處理。
- 模式寫法
- 使用case與字元集合、範圍與否定,例如:
- [A-Z]) …(大寫)
- [a-z]) …(小寫)
- [0-9]) …(數字)
- *) …(其他)
- 講師口語示範「兩個中括號、中括號還有個帽號(^)」等進階寫法,用於否定或複合集合;提醒寫法較「怪」但可直接套用範例。
- 使用case與字元集合、範圍與否定,例如:
- 實務應用
- 可用於輸入驗證、密碼強度檢查、命令分流等。