05.01.2015 Views

Linux/Unix 程式設計 - 系統管理王德譽

Linux/Unix 程式設計 - 系統管理王德譽

Linux/Unix 程式設計 - 系統管理王德譽

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Linux</strong>/<strong>Unix</strong> 程 式 設 計<br />

Department of Computer Science and Information Engineering<br />

Chaoyang University of Technology<br />

Taichung, Taiwan, Republic of China<br />

Instructor: De-Yu Wang ( 王 德 譽 )<br />

E-mail: dywang@csie.cyut.edu.tw<br />

Homepage: http://dywang.csie.cyut.edu.tw<br />

Phone: (04)23323000 ext 4538<br />

Office: E738<br />

♣ ✉ ✈ ✇ 1 2 3 4 5 6 7 7<br />

March 11, 2014


• Instructor: De-Yu Wang<br />

1. Email: dywang@csie.cyut.edu.tw<br />

2. Homepage: http://dywang.csie.cyut.edu.tw<br />

3. Phone: (04)23323000 ext 4538<br />

4. Office: E738<br />

• 參 考 資 料<br />

1. 鳥 哥 的 <strong>Linux</strong> 私 房 菜<br />

2. Neil Matthew Richard Stones 著 , 江 俊 龍 譯 ,”<strong>Linux</strong> 程 式 設 計 教 學 手 冊<br />

( 第 三 版 )(Beginning <strong>Linux</strong> Programming (Third Edition))”, 碁 峰 資<br />

訊 股 份 有 限 公 司 。<br />

3. vim 官 方 網 站 亦 稱 vim 為 程 式 開 發 工 具 。<br />

4. 大 家 來 學 VIM( 一 個 歷 久 彌 新 的 編 輯 器 )<br />

5. Bash shell<br />

6. 中 央 研 究 院 計 算 中 心 RCS 簡 介 網 頁<br />

7. C++ GUI Programming with Qt 3 by Jasmin Blanchette and Mark Summerfield,<br />

Published by Prentice Hall.<br />

8. Maximum RPM 網 頁<br />

9. Python<br />

10. Python Tutorial<br />

11. Glade - A User Interface Designer<br />

12. PyGTK: GTK+ for Python<br />

13. PyGTK tutorial<br />

14. 線 上 程 式 練 習<br />

De-Yu Wang CSIE CYUT<br />

i


De-Yu Wang CSIE CYUT<br />

ii


CONTENTS<br />

CONTENTS<br />

Contents<br />

1 vi 編 輯 器 1<br />

1.1 vi 與 vim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1<br />

1.2 vi 的 使 用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1<br />

1.3 vim 的 額 外 功 能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

1.4 vi 實 機 練 習 題 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

1.4.1 練 習 一 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

1.4.2 練 習 二 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12<br />

1.4.3 練 習 三 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />

2 Shell 變 數 15<br />

2.1 Shell 的 變 數 功 能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15<br />

2.2 環 境 變 數 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19<br />

2.3 變 數 鍵 盤 讀 取 與 宣 告 . . . . . . . . . . . . . . . . . . . . . . . . . . . 27<br />

2.4 陣 列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28<br />

2.5 變 數 的 變 化 與 取 代 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29<br />

2.6 變 數 的 設 定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31<br />

3 資 料 導 向 與 管 線 處 理 37<br />

3.1 資 料 流 重 導 向 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37<br />

3.2 管 線 命 令 (pipe) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41<br />

4 正 規 表 示 法 59<br />

4.1 前 言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59<br />

4.2 基 礎 正 規 表 示 法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60<br />

4.3 延 伸 正 規 表 示 法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69<br />

4.4 格 式 化 列 印 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71<br />

5 sed 與 awk 工 具 75<br />

5.1 sed 工 具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75<br />

5.2 awk 工 具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80<br />

6 Shell Scripts – 簡 介 與 test 功 能 85<br />

6.1 前 言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85<br />

6.2 視 Shell 為 一 種 程 式 語 言 . . . . . . . . . . . . . . . . . . . . . . . . . 88<br />

6.3 shell script 練 習 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90<br />

De-Yu Wang CSIE CYUT<br />

iii


CONTENTS<br />

CONTENTS<br />

6.4 善 用 判 斷 式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92<br />

7 Shell scripts – 條 件 判 斷 與 迴 圈 99<br />

7.1 條 件 判 斷 式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99<br />

7.2 迴 圈 (loop) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108<br />

7.3 shell script 的 追 蹤 與 debug . . . . . . . . . . . . . . . . . . . . . . . 113<br />

8 開 發 工 具 – make 與 makefile 119<br />

8.1 編 譯 器 與 可 執 行 檔 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119<br />

8.2 make 命 令 和 makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . 122<br />

8.3 makefile 的 變 數 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131<br />

8.4 多 重 目 標 項 目 (target) . . . . . . . . . . . . . . . . . . . . . . . . . 135<br />

8.5 Makefile 其 他 法 則 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139<br />

8.6 函 式 庫 管 理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141<br />

8.7 撰 寫 使 用 者 手 冊 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148<br />

9 開 發 工 具 – makefile 其 他 功 能 157<br />

9.1 多 重 目 標 項 目 (target) . . . . . . . . . . . . . . . . . . . . . . . . . 157<br />

9.2 Makefile 其 他 法 則 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160<br />

9.3 函 式 庫 管 理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163<br />

9.4 撰 寫 使 用 者 手 冊 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170<br />

10 *RCS 版 本 控 制 系 統 177<br />

10.1 版 本 控 制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177<br />

10.2 RCS 基 本 功 能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180<br />

10.3 識 別 關 鍵 字 串 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197<br />

10.4 標 記 符 號 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205<br />

10.5 版 本 比 較 與 整 合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210<br />

10.6 存 取 名 單 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215<br />

11 * 使 用 QT 設 計 KDE 視 窗 程 式 219<br />

11.1 KDE 和 QT 介 紹 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219<br />

11.2 Qt 開 發 環 境 建 立 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220<br />

11.3 gtk+ 開 發 環 境 建 立 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223<br />

11.4 Signals 和 Slots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224<br />

11.5 QT Widget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231<br />

11.6 對 話 窗 dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244<br />

11.7 選 單 和 工 具 列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249<br />

12 Python 255<br />

12.1 Python 簡 介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255<br />

12.2 Python 變 數 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259<br />

12.3 python 運 算 子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263<br />

12.4 python 流 程 控 制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263<br />

12.5 python 函 式 與 模 組 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263<br />

12.6 python I/O 與 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . 263<br />

De-Yu Wang CSIE CYUT<br />

iv


CONTENTS<br />

CONTENTS<br />

13 PyGTK 265<br />

13.1 PyGTK 簡 介 與 開 始 . . . . . . . . . . . . . . . . . . . . . . . . . . . 265<br />

13.2 Buttons 與 Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266<br />

13.3 Signals, Events and Functions . . . . . . . . . . . . . . . . . . . . . . 267<br />

13.4 Label and Entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269<br />

14 Glade 275<br />

14.1 簡 介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275<br />

14.2 Calculator Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277<br />

15 *Tarball 套 件 發 行 279<br />

15.1 套 件 發 行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279<br />

15.2 Tarballs 簡 介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280<br />

15.3 KPlayer Tarball 實 例 . . . . . . . . . . . . . . . . . . . . . . . . . . . 290<br />

16 *RPM 與 SRPM 套 件 發 行 297<br />

16.1 RPM 與 SRPM 套 件 . . . . . . . . . . . . . . . . . . . . . . . . . . . 297<br />

16.2 建 立 RPM 套 件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302<br />

16.3 KPlayer RPM 實 例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310<br />

17 * 套 件 修 補 、 檢 驗 與 管 理 315<br />

17.1 patch 程 式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315<br />

17.2 檢 驗 軟 體 正 確 性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325<br />

17.3 RPM 套 件 管 理 程 式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330<br />

De-Yu Wang CSIE CYUT<br />

v


CHAPTER 1.<br />

VI 編 輯 器<br />

Chapter 1<br />

vi 編 輯 器<br />

1.1 vi 與 vim<br />

1. <strong>Linux</strong> 的 系 統 中 使 用 文 字 編 輯 器 來 編 輯 您 的 <strong>Linux</strong> 參 數 設 定 檔 。<br />

2. <strong>Linux</strong> 與 <strong>Unix</strong> 系 統 中 的 參 數 檔 幾 乎 都 是 ASCII 碼 的 『 純 文 字 』 檔 。<br />

3. vi 為 文 書 編 輯 器 , vim 是 vi 的 進 階 軟 體 。<br />

4. vim 加 入 了 支 援 正 規 表 示 法 的 搜 尋 架 構 、 多 檔 編 輯 、 區 塊 複 製 等 功 能 。<br />

5. vim 官 方 網 站 亦 稱 vim 為 程 式 開 發 工 具 。<br />

6. 大 家 來 學 VIM( 一 個 歷 久 彌 新 的 編 輯 器 )<br />

1.2 vi 的 使 用<br />

1. vi 共 分 為 三 種 模 式 , 分 別 是 『 一 般 模 式 』、『 編 輯 模 式 』 與 『 指 令 列 命 令 模<br />

式 』 三 種 。<br />

i,o,a,r<br />

I,O,A,R✲<br />

編 輯 模 式<br />

一 般 模 式<br />

✛ [Esc] 可 輸 入 任 何 字 元<br />

游 標 移 動<br />

搜 尋 、 取 代<br />

刪 除 字 元 、 刪 除 整 列 :, /, <br />

✲ 指 令 列 模 式<br />

複 製 整 列 、 貼 上 整 列<br />

讀 取 、 儲 存 檔 案<br />

✛<br />

其 他 額 外 功 能<br />

2. 簡 易 範 例<br />

(a) 使 用 vi 進 入 一 般 模 式<br />

✞<br />

圱 [dywang@dywOffice tmp]$ vim test.txt<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 1


1.2. VI 的 使 用 CHAPTER 1. VI 編 輯 器<br />

(b) 按 下 i 進 入 編 輯 模 式 , 開 始 編 輯 文 字 。<br />

(c) 按 下 [Esc] 按 鈕 回 到 一 般 模 式 。<br />

(d) 在 一 般 模 式 中 按 下 :x 儲 存 後 離 開 vi。<br />

3. 常 用 指 令 列 表<br />

一 般 模 式<br />

移 動 游 標<br />

坨 或 向 左 方 向 鍵<br />

游 標 向 左 移 動 一 個 字 元<br />

坪 或 向 下 方 向 鍵<br />

游 標 向 下 移 動 一 個 字 元<br />

坫 或 向 上 方 向 鍵<br />

游 標 向 上 移 動 一 個 字 元<br />

坬 或 向 右 方 向 鍵<br />

游 標 向 右 移 動 一 個 字 元<br />

[Ctrl]+f<br />

螢 幕 『 向 前 』 移 動 一 頁<br />

[Ctrl]+b<br />

螢 幕 『 向 後 』 移 動 一 頁<br />

[Ctrl]+d<br />

螢 幕 『 向 前 』 移 動 半 頁<br />

[Ctrl]+u<br />

螢 幕 『 向 後 』 移 動 半 頁<br />

圫<br />

游 標 移 動 到 非 空 白 字 元 的 下 一 列<br />

圭<br />

游 標 移 動 到 非 空 白 字 元 的 上 一 列<br />

n<br />

按 下 數 字 後 再 按 空 白 鍵 , 游 標 會 向 右 移 動 這 一 行 的 坮 個<br />

字 元 。 例 如 20 則 游 標 會 向 後 面 移 動 圲 地 個 字 元 距<br />

離 。<br />

地 這 是 數 字 『 地 』: 移 動 到 這 一 行 的 最 前 面 字 元 處 。<br />

$ 移 動 到 這 一 行 的 最 後 面 字 元 處<br />

坈<br />

游 標 移 動 到 這 個 螢 幕 的 最 上 方 那 一 行<br />

坍<br />

游 標 移 動 到 這 個 螢 幕 的 中 央 那 一 行<br />

坌<br />

游 標 移 動 到 這 個 螢 幕 的 最 下 方 那 一 行<br />

均<br />

游 標 移 動 到 這 個 檔 案 的 最 後 一 行<br />

坮 均<br />

游 標 移 動 到 這 個 檔 案 的 第 坮 行 。 例 如 圲 地 均 則 會 移 動 到 檔<br />

案 的 第 圲 地 行 在 可 配 合 场 坳 坥 坴 坮 坵 圩<br />

n<br />

游 標 向 下 移 動 坮 行<br />

一 般 模 式<br />

搜 尋 與 取 代<br />

圯 坷 坯 坲 坤 向 游 標 之 後 尋 找 一 個 字 串 名 稱 為 坷 坯 坲 坤 的 字 串 。<br />

圿 坷 坯 坲 坤 向 游 標 之 前 尋 找 一 個 字 串 名 稱 為 坷 坯 坲 坤 的 字 串 。<br />

坮 重 複 前 一 個 搜 尋 。<br />

坎 反 向 進 行 前 一 個 搜 尋 動 作 。<br />

场 坮 圱 圬 坮 圲 坳 圯 坷 坯 坲 坤 圱 圯 坷 坯 坲 坤 圲 圯 坧 在 第 坮 圱 與 坮 圲 行 之 間 尋 找 坷 坯 坲 坤 圱 這 個 字 串 , 並 將 該 字 串<br />

取 代 為 坷 坯 坲 坤 圲 。<br />

场 圱 圬 圤 坳 圯 坷 坯 坲 坤 圱 圯 坷 坯 坲 坤 圲 圯 坧 從 第 一 行 到 最 後 一 行 尋 找 坷 坯 坲 坤 圱 字 串 , 並 將 該 字 串 取 代<br />

為 坷 坯 坲 坤 圲 。<br />

场 圱 圬 圤 坳 圯 坷 坯 坲 坤 圱 圯 坷 坯 坲 坤 圲 圯 坧 坣 從 第 一 行 到 最 後 一 行 尋 找 坷 坯 坲 坤 圱 字 串 , 並 將 該 字 串 取 代<br />

為 坷 坯 坲 坤 圲 且 在 取 代 前 顯 示 提 示 字 元 給 使 用 者 確 認 是 否 需<br />

要 取 代 。<br />

一 般 模 式<br />

刪 除 、 複 製 與 貼 上<br />

坸 圬 坘<br />

坸 為 向 後 刪 除 一 個 字 元 , 坘 為 向 前 刪 除 一 個 字 元<br />

坮 坸<br />

向 後 刪 除 坮 個 字 元<br />

坤 坤<br />

刪 除 游 標 所 在 的 那 一 整 列<br />

坮 坤 坤<br />

刪 除 游 標 所 在 的 向 下 坮 列 , 例 如 圲 地 坤 坤 則 是 刪 除 圲 地 列<br />

坤 圱 均<br />

刪 除 游 標 所 在 到 第 一 行 的 所 有 資 料<br />

De-Yu Wang CSIE CYUT 2


1.2. VI 的 使 用 CHAPTER 1. VI 編 輯 器<br />

坤 均<br />

刪 除 游 標 所 在 到 最 後 一 行 的 所 有 資 料<br />

坤 坷 刪 除 一 個 字 在 坤 坥 坬 坥 坴 坥 坷 坯 坲 坤 圩 。 不 適 用 於 中 文 。<br />

坹 坹 複 製 游 標 所 在 的 那 一 行 ( 常 用 )<br />

坮 坹 坹<br />

複 製 游 標 所 在 的 向 下 坮 列 , 例 如 圲 地 坹 坹 則 是 複 製 圲 地 列<br />

坹 圱 均<br />

複 製 游 標 所 在 列 到 第 一 列 的 所 有 資 料<br />

坹 均<br />

複 製 游 標 所 在 列 到 最 後 一 列 的 所 有 資 料<br />

坰 圬 坐<br />

坰 為 複 製 的 資 料 在 游 標 下 一 行 貼 上 , 坐 則 為 貼 在 游 標 上 一<br />

行 。<br />

坊<br />

將 游 標 所 在 列 與 下 一 列 的 資 料 結 合 成 同 一 列<br />

坵 復 原 前 一 個 動 作 。<br />

[Ctrl]+r 反 復 原 前 一 個 動 作 。<br />

圮 重 做 上 一 個 動 作 。<br />

進 入 編 輯 模 式<br />

坩 圬 坉<br />

插 入 : 坩 在 坉 圩 在 目 前 的 游 標 所 在 處 在 所 在 行 第 一 個 非 空 白 字<br />

元 處 圩 插 入 輸 入 之 文 字 ;<br />

坡 圬 坁<br />

增 加 : 坡 在 坁 圩 由 目 前 游 標 所 在 的 下 一 個 在 最 後 一 個 圩 字 元 處<br />

開 始 輸 入 :<br />

坯 圬 坏<br />

插 入 新 的 一 行 : 坯 在 坏 圩 從 游 標 所 在 的 下 在 上 圩 一 行 插 入 新 的<br />

一 行 ;<br />

坲 圬 坒<br />

取 代 : 坲 會 取 代 游 標 所 在 的 那 一 個 字 元 ; 坒 會 一 直 取 代 游<br />

標 所 在 的 文 字 , 直 到 按 下 坅 坓 坃 為 止 ;<br />

坅 坳 坣 退 出 編 輯 模 式 , 回 到 一 般 模 式 中 。<br />

指 令 列 命 令 模 式<br />

场 坷<br />

將 編 輯 的 資 料 寫 入 硬 碟 檔 案 中<br />

场 坷 圡<br />

若 檔 案 屬 性 為 『 唯 讀 』 時 , 強 制 寫 入 該 檔 案<br />

场 坱<br />

離 開 坶 坩<br />

场 坱 圡<br />

若 曾 修 改 過 檔 案 , 又 不 想 儲 存 , 使 用 圡 為 強 制 離 開 不 儲 存<br />

檔 案 。<br />

场 坷 坱<br />

儲 存 後 離 開 , 若 為 场 坷 坱 圡 則 為 強 制 儲 存 後 離 開<br />

场 坸<br />

與 坷 坱 相 同<br />

场 坥 圡 將 檔 案 還 原 到 最 原 始 的 狀 態 。<br />

坚 坚 若 檔 案 沒 有 更 動 , 則 不 儲 存 離 開 , 若 檔 案 已 經 經 過 更 動 ,<br />

則 儲 存 後 離 開 。<br />

场 坷 坛 圌 坬 坥 坮 坡 坭 坥 坝 將 編 輯 的 資 料 儲 存 成 另 一 個 檔 案 ( 類 似 另 存 新 檔 )<br />

场 坲 坛 圌 坬 坥 坮 坡 坭 坥 坝<br />

在 編 輯 的 資 料 中 , 讀 入 另 一 個 檔 案 的 資 料 。 亦 即 將<br />

『 圌 坬 坥 坮 坡 坭 坥 』 這 個 檔 案 內 容 加 到 游 標 所 在 行 後 面 。<br />

场 坳 坥 坴 坮 坵<br />

顯 示 行 號 , 設 定 之 後 , 會 在 每 一 行 的 字 首 顯 示 該 行 的 行 號<br />

场 坳 坥 坴 坮 坯 坮 坵 與 坳 坥 坴 坮 坵 相 反 , 為 取 消 行 號 。<br />

场 坮 圱 圬 坮 圲 坷 坛 圌 坬 坥 坮 坡 坭 坥 坝 將 坮 圱 到 坮 圲 的 內 容 儲 存 成 圌 坬 坥 坮 坡 坭 坥 這 個 檔 案 。<br />

场 圡 坣 坯 坭 坭 坡 坮 坤 暫 時 離 開 坶 坩 到 指 令 列 模 式 下 執 行 坣 坯 坭 坭 坡 坮 坤 的 顯 示 結 果 。<br />

例 如 坛 场 圡 坬 坳 圯 坨 坯 坭 坥 坝<br />

4. vi 編 輯 中 回 復 與 暫 存 檔<br />

(a) 如 果 編 輯 檔 案 為 /home/csie/vitest.txt, 則 同 時 會 有 一 個 暫 存 檔 /home-<br />

/csie/.vitest.txt.swp 產 生 , 其 為 隱 藏 檔 。<br />

(b) 結 束 vi 編 輯 時 暫 存 檔 也 會 刪 除 。<br />

De-Yu Wang CSIE CYUT 3


1.2. VI 的 使 用 CHAPTER 1. VI 編 輯 器<br />

(c) 若 不 知 因 素 導 致 vi 程 式 中 斷 , 則 在 下 次 編 輯 該 檔 案 時 會 出 現 是 否 回 復 的<br />

訊 息 。<br />

練 習 題<br />

1. vi 有 那 三 種 模 式 <br />

Sol. 一 般 模 式 、 編 輯 模 式 與 指 令 列 模 式<br />

2. 在 vi 一 般 模 式 下 , 可 以 那 四 個 字 元 鍵 進 行 游 標 向 左 、 下 、 上 、 右 移 動 一 個<br />

字 元 <br />

Sol. h j k l<br />

3. 在 vi 一 般 模 式 下 , 如 何 使 螢 幕 『 向 前 』 移 動 一 頁 <br />

Sol. [Ctrl]+f<br />

4. 在 vi 一 般 模 式 下 , 如 何 使 螢 幕 『 向 後 』 移 動 一 頁 <br />

Sol. [Ctrl]+b<br />

5. 在 vi 一 般 模 式 下 , 如 何 使 螢 幕 『 向 前 』 移 動 半 頁 <br />

Sol. [Ctrl]+d<br />

6. 在 vi 一 般 模 式 下 , 如 何 使 螢 幕 『 向 後 』 移 動 半 頁 <br />

Sol. [Ctrl]+u<br />

7. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 非 空 白 字 元 的 下 一 列 <br />

Sol. 按 + 鍵<br />

8. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 非 空 白 字 元 的 上 一 列 <br />

Sol. 按 - 鍵<br />

9. 在 vi 一 般 模 式 下 , 如 何 使 游 標 向 右 移 動 這 一 行 的 12 個 字 元 <br />

Sol. 按 12 鍵<br />

10. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 這 一 行 的 最 前 面 字 元 處 <br />

Sol. 按 0 鍵<br />

11. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 這 一 行 的 最 後 面 字 元 處 <br />

Sol. 按 $ 鍵<br />

12. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 這 個 螢 幕 的 最 上 方 那 一 行 <br />

Sol. 按 H 鍵<br />

13. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 這 個 螢 幕 的 中 央 那 一 行 <br />

Sol. 按 M 鍵<br />

14. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 這 個 螢 幕 的 最 下 方 那 一 行 <br />

Sol. 按 L 鍵<br />

15. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 這 個 螢 幕 的 最 後 一 行 <br />

Sol. 按 G 鍵<br />

De-Yu Wang CSIE CYUT 4


1.2. VI 的 使 用 CHAPTER 1. VI 編 輯 器<br />

16. 在 vi 一 般 模 式 下 , 如 何 使 游 標 移 動 到 這 個 檔 案 的 第 12 行 <br />

Sol. 輸 入 12G<br />

17. 在 vi 一 般 模 式 下 , 如 何 使 游 標 游 標 向 下 移 動 12 行 <br />

Sol. 輸 入 12<br />

18. 在 vi 一 般 模 式 下 , 如 何 向 游 標 之 後 尋 找 一 個 字 串 名 稱 為 word 的 字 串 , 接<br />

著 重 複 搜 尋 <br />

Sol. 輸 入 /word , 接 著 按 n 鍵<br />

19. 在 vi 一 般 模 式 下 , 如 何 向 游 標 之 後 尋 找 一 個 字 串 名 稱 為 word 的 字 串 , 接<br />

著 反 向 重 複 搜 尋 <br />

Sol. 輸 入 /word , 接 著 按 N 鍵<br />

20. 在 vi 一 般 模 式 下 , 如 何 向 游 標 之 前 尋 找 一 個 字 串 名 稱 為 word 的 字 串 , 接<br />

著 重 複 搜 尋 <br />

Sol. 輸 入 word , 接 著 按 n 鍵<br />

21. 在 vi 一 般 模 式 下 , 如 何 向 游 標 之 前 尋 找 一 個 字 串 名 稱 為 word 的 字 串 , 接<br />

著 反 向 重 複 搜 尋 <br />

Sol. 輸 入 word , 接 著 按 N 鍵<br />

22. 在 vi 一 般 模 式 下 , 如 何 向 游 標 後 刪 除 一 個 字 元 <br />

Sol. 按 x 鍵<br />

23. 在 vi 一 般 模 式 下 , 如 何 向 游 標 前 刪 除 一 個 字 元 <br />

Sol. 按 X 鍵<br />

24. 在 vi 一 般 模 式 下 , 如 何 向 游 標 後 刪 除 12 個 字 元 <br />

Sol. 按 12x 鍵<br />

25. 在 vi 一 般 模 式 下 , 如 何 向 游 標 前 刪 除 12 個 字 元 <br />

Sol. 按 12X 鍵<br />

26. 在 vi 一 般 模 式 下 , 如 何 刪 除 游 標 所 在 的 那 一 整 列 <br />

Sol. 按 dd<br />

27. 在 vi 一 般 模 式 下 , 如 何 刪 除 一 個 字 ( 不 適 用 於 中 文 )<br />

Sol. 按 dw<br />

28. 在 vi 一 般 模 式 下 , 如 何 刪 除 游 標 所 在 的 向 下 12 列 <br />

Sol. 按 12dd<br />

29. 在 vi 一 般 模 式 下 , 如 何 刪 除 游 標 所 在 到 最 後 一 行 的 所 有 資 料 <br />

Sol. 按 d1G<br />

30. 在 vi 一 般 模 式 下 , 如 何 複 製 游 標 所 在 的 那 一 行 <br />

Sol. 按 yy<br />

De-Yu Wang CSIE CYUT 5


1.2. VI 的 使 用 CHAPTER 1. VI 編 輯 器<br />

31. 在 vi 一 般 模 式 下 , 如 何 複 製 游 標 所 在 的 向 下 12 列 <br />

Sol. 按 12yy<br />

32. 在 vi 一 般 模 式 下 , 如 何 複 製 游 標 所 在 列 到 第 一 列 的 所 有 資 料 <br />

Sol. 按 y1G<br />

33. 在 vi 一 般 模 式 下 , 如 何 複 製 游 標 所 在 列 到 最 後 一 列 的 所 有 資 料 <br />

Sol. 按 yG<br />

34. 在 vi 一 般 模 式 下 , 如 何 將 複 製 的 資 料 在 游 標 下 一 行 貼 上 <br />

Sol. 按 p<br />

35. 在 vi 一 般 模 式 下 , 如 何 將 複 製 的 資 料 在 游 標 上 一 行 貼 上 <br />

Sol. 按 P<br />

36. 在 vi 一 般 模 式 下 , 如 何 將 游 標 所 在 列 與 下 一 列 的 資 料 結 合 成 同 一 列 <br />

Sol. 按 J<br />

37. 我 已 經 在 vi 內 進 行 很 多 動 作 , 但 現 在 想 要 復 原 , 如 何 做 <br />

Sol. 一 直 重 複 按 u 即 可 ;<br />

38. 在 vi 的 一 般 模 式 中 , 反 復 原 前 一 個 動 作 <br />

Sol. [Ctrl]+r<br />

39. 在 vi 的 一 般 模 式 中 , 重 做 前 一 個 動 作 <br />

Sol. .<br />

40. vi 如 何 由 一 般 模 式 進 入 編 輯 模 式 ( 在 目 前 游 標 處 插 入 輸 入 之 文 字 )<br />

Sol. i<br />

41. vi 如 何 由 一 般 模 式 進 入 編 輯 模 式 ( 所 在 行 第 一 個 非 空 白 字 元 處 插 入 輸 入 之 文<br />

字 )<br />

Sol. I<br />

42. vi 如 何 由 一 般 模 式 進 入 編 輯 模 式 ( 由 目 前 游 標 所 在 的 下 一 個 字 元 處 開 始 輸<br />

入 )<br />

Sol. a<br />

43. vi 如 何 由 一 般 模 式 進 入 編 輯 模 式 ( 由 目 前 游 標 所 在 的 最 後 一 個 字 元 處 開 始 輸<br />

入 )<br />

Sol. A<br />

44. vi 如 何 由 一 般 模 式 進 入 編 輯 模 式 ( 從 游 標 所 在 的 下 一 行 插 入 新 的 一 行 )<br />

Sol. o<br />

45. vi 如 何 由 一 般 模 式 進 入 編 輯 模 式 ( 從 游 標 所 在 的 上 一 行 插 入 新 的 一 行 )<br />

Sol. O<br />

46. vi 如 何 由 一 般 模 式 進 入 編 輯 模 式 ( 會 取 代 游 標 所 在 的 那 一 個 字 元 )<br />

Sol. r<br />

De-Yu Wang CSIE CYUT 6


1.2. VI 的 使 用 CHAPTER 1. VI 編 輯 器<br />

47. vi 如 何 由 一 般 模 式 進 入 編 輯 模 式 ( 會 一 直 取 代 游 標 所 在 的 文 字 , 直 到 退 出 編<br />

輯 模 式 )<br />

Sol. R<br />

48. vi 如 何 退 出 編 輯 模 式 , 回 到 一 般 模 式 中 <br />

Sol. 按 下 ESC<br />

49. 在 vi 的 一 般 模 式 中 , 輸 入 13 後 按 Enter 與 輸 入 13 後 按 下 G , 代 表 什<br />

麼 意 義 <br />

Sol. 向 下 移 動 13 行 , 以 及 去 到 第 13 行 。<br />

50. 在 vi 的 一 般 模 式 中 , 先 以 指 令 將 游 標 移 到 第 13 行 , 複 製 13 到 17 行 ,<br />

再 以 指 令 將 游 標 移 到 第 20 行 , 最 後 將 資 料 貼 到 20 行 以 後 , 如 何 做 <br />

Sol. 13G 5yy 20G p<br />

51. 在 vi 的 一 般 模 式 中 , 先 以 指 令 將 游 標 移 到 第 50 行 , 刪 除 50 到 55 行 ,<br />

如 何 做 <br />

Sol. 50G 6dd<br />

52. 在 vi 的 一 般 模 式 中 , 如 何 以 指 令 將 游 標 移 到 第 5 行 , 再 連 結 第 5, 6<br />

行 <br />

Sol. 5G J<br />

53. 在 vi 的 一 般 模 式 , 輸 入 /find 代 表 什 麼 意 義 另 外 , 輸 入 j 又 代 表 什 麼<br />

意 義 輸 入 5k 代 表 什 麼<br />

Sol. 搜 尋 find 這 個 字 串 ; 向 下 移 動 : 向 上 移 動 5 個 字 元 。<br />

54. 在 vi 的 一 般 模 式 中 , 我 想 要 取 代 目 前 檔 案 第 100 到 200 行 之 間 的 test<br />

成 為 TEST 且 不 詢 問 , 要 如 何 做 <br />

Sol. :100,200s/test/TEST/g<br />

55. 在 vi 的 一 般 模 式 中 , 我 想 要 取 代 目 前 檔 案 第 100 到 200 行 之 間 的 test<br />

成 為 TEST 且 取 代 前 詢 問 , 要 如 何 做 <br />

Sol. :100,200s/test/TEST/gc<br />

56. 在 vi 的 一 般 模 式 中 , 我 想 要 取 代 目 前 檔 案 第 1 到 最 後 一 行 之 間 的 test<br />

成 為 TEST 且 不 詢 問 , 要 如 何 做 <br />

Sol. :1,$s/test/TEST/g<br />

57. 在 vi 的 一 般 模 式 中 , 我 想 要 取 代 目 前 檔 案 第 1 到 最 後 一 行 之 間 的 test<br />

成 為 TEST 且 取 代 前 詢 問 , 要 如 何 做 <br />

Sol. :1,$s/test/TEST/gc<br />

58. 在 vi 的 一 般 模 式 中 , 如 何 儲 存 並 結 束 檔 案 後 離 開 <br />

Sol. 在 一 般 模 式 下 執 行 :wq 或 :x<br />

59. 在 vi 的 指 令 列 模 式 中 ,『 :q! 』 代 表 什 麼 意 思 <br />

Sol. 不 儲 存 , 強 制 離 開 vi<br />

De-Yu Wang CSIE CYUT 7


1.2. VI 的 使 用 CHAPTER 1. VI 編 輯 器<br />

60. 在 vi 的 一 般 模 式 當 中 , 輸 入 ZZ 代 表 什 麼 意 思 <br />

Sol. 若 檔 案 已 更 動 , 則 儲 存 後 離 開 , 若 未 被 更 動 , 則 直 接 離 開 vi 。<br />

61. 在 vi 的 一 般 模 式 中 , 如 何 將 編 輯 的 資 料 寫 入 硬 碟 檔 案 中 <br />

Sol. 輸 入 :w<br />

62. 在 vi 的 一 般 模 式 中 , 如 何 將 目 前 編 輯 的 檔 案 另 存 為 file1.txt<br />

Sol. 輸 入 :w file1.txt<br />

63. 在 vi 的 一 般 模 式 中 , 若 目 前 編 輯 的 檔 案 為 唯 讀 檔 , 如 何 強 制 存 回 <br />

Sol. 輸 入 :w!<br />

64. 在 vi 的 一 般 模 式 中 , 如 何 離 開 vi<br />

Sol. 輸 入 :q<br />

65. 在 vi 的 一 般 模 式 中 , 如 何 強 制 離 開 不 儲 存 檔 案 <br />

Sol. 輸 入 :q!<br />

66. 在 vi 的 一 般 模 式 中 , 如 何 儲 存 後 離 開 <br />

Sol. 輸 入 :wq 或 :x<br />

67. 在 vi 的 一 般 模 式 中 , 如 何 強 制 儲 存 後 離 開 <br />

Sol. 輸 入 :wq! 或 :x!<br />

68. 在 vi 的 一 般 模 式 中 , 如 何 將 目 前 編 輯 的 檔 案 還 原 到 原 始 狀 態 <br />

Sol. 輸 入 :e!<br />

69. 在 vi 的 一 般 模 式 中 , 如 何 設 定 顯 示 行 號 <br />

Sol. 輸 入 :set nu<br />

70. 在 vi 的 一 般 模 式 中 , 如 何 取 消 設 定 顯 示 行 號 <br />

Sol. 輸 入 :set nonu<br />

71. 在 vi 的 一 般 模 式 中 , 如 何 讀 取 另 一 檔 案 file.txt<br />

Sol. 輸 入 :r file.txt<br />

72. 在 vi 的 一 般 模 式 中 , 如 何 將 10 到 20 的 內 容 儲 存 成 file1.txt 這 個 檔<br />

案 <br />

Sol. 輸 入 :10,20 w file1.txt<br />

73. 在 vi 的 一 般 模 式 中 , 如 何 將 10 到 最 後 一 行 的 內 容 儲 存 成 file1.txt 這<br />

個 檔 案 <br />

Sol. 輸 入 :10,$ w file1.txt<br />

74. 在 vi 的 一 般 模 式 中 , 如 何 暫 時 離 開 , 執 行 指 令 ls -l<br />

Sol. 輸 入 :! ls -l<br />

75. 在 vi 編 輯 檔 案 file.txt 中 , 同 時 會 產 生 一 暫 存 檔 , 其 檔 名 為 何 <br />

Sol. .file.txt.swp<br />

De-Yu Wang CSIE CYUT 8


1.3. VIM 的 額 外 功 能 CHAPTER 1. VI 編 輯 器<br />

76. 如 果 要 以 vi 編 輯 檔 案 file.txt 時 , 出 現 是 否 回 復 的 訊 息 , 表 示 有 那 個 暫<br />

存 檔 存 在 <br />

Sol. .file.txt.swp<br />

1.3 vim 的 額 外 功 能<br />

1. 如 果 使 用 vi, 在 畫 面 右 下 角 有 目 前 游 標 所 在 行 列 號 碼 , 則 vi 己 被 vim 取<br />

代 了 。<br />

✞<br />

圱 [dywang@dywOffice tmp]$ ll /bin/vi*<br />

lrwxrwxrwx 1 root root 20 Oct 17 13:11 /bin/vi -> /etc/<br />

alternatives/vi*<br />

圳 lrwxrwxrwx 1 root root 21 Oct 17 13:11 /bin/vim -> /etc/<br />

alternatives/vim*<br />

[dywang@dywOffice tmp]$ ll /etc/alternatives/vi*<br />

圵 lrwxrwxrwx 1 root root 21 Oct 17 13:11 /etc/alternatives/vi -><br />

/usr/bin/vim-enhanced*<br />

圷 lrwxrwxrwx 1 root root 21 Oct 17 13:11 /etc/alternatives/vim -><br />

/usr/bin/vim-enhanced*<br />

✡✝<br />

✆<br />

2. vim 具 有 顏 色 顯 示 的 功 能 , 並 且 還 支 援 許 多 的 程 式 語 法 。<br />

3. vim /etc/man.config 出 現 訊 息 說 明 :<br />

✞<br />

"/etc/man.config" [readonly] 150L, 4900C 1,1<br />

Top<br />

✡✝<br />

✆<br />

(a) 編 輯 檔 案 名 稱 為 /etc/man.config;<br />

(b) 檔 案 為 唯 讀 檔 ;<br />

(c) 檔 案 共 有 150 行 ,4900 字 元 ;<br />

(d) 目 前 游 標 所 在 位 置 為 第 一 行 , 第 一 列 ;<br />

(e) 目 前 頁 面 在 最 前 頁 。<br />

4. 區 塊 選 擇<br />

區 塊 選 擇 的 按 鍵 意 義<br />

v 字 元 選 擇 , 會 將 游 標 經 過 的 地 方 反 白 選 擇 。<br />

V 行 選 擇 , 會 將 游 標 經 過 的 反 白 選 擇 。<br />

[Ctrl]+v 區 塊 選 擇 , 可 以 用 長 方 形 的 方 式 選 擇 資 料 。<br />

y 將 反 白 的 地 方 複 製 起 來 。<br />

d 將 反 白 的 地 方 刪 除 掉 。<br />

De-Yu Wang CSIE CYUT 9


1.3. VIM 的 額 外 功 能 CHAPTER 1. VI 編 輯 器<br />

5. 多 檔 案 編 輯<br />

(a) vi 內 使 用 :r filename 可 將 檔 案 filename 的 內 容 在 游 標 處 插 入 。<br />

(b) 可 於 vim 後 接 多 個 檔 案 來 同 時 開 啟 多 個 檔 案 , 例 如 :vim filename1<br />

filename2 filename3。 其 相 關 按 鍵 有 :<br />

多 檔 案 編 輯 的 按 鍵<br />

:n 編 輯 下 一 個 檔 案 。<br />

:N 編 輯 上 一 個 檔 案 。<br />

:files 列 出 目 前 開 啟 的 所 有 檔 案 。<br />

6. 多 視 窗 功 能<br />

(a) 在 指 令 列 模 式 輸 入 :sp filename。<br />

(b) 如 果 省 略 filename 則 兩 視 窗 為 同 一 檔 案 。<br />

多 視 窗 下 的 按 鍵 功 能<br />

:sp 開 啟 同 一 檔 案 於 新 視 窗 。<br />

:sp filename 開 啟 檔 案 filename 於 新 視 窗 。<br />

[Ctrl]+wj 游 標 移 動 到 下 方 的 視 窗 。 按 法 為 : 先 按 下<br />

[Ctrl] 不 放 , 再 下 w 後 放 開 所 有 的 按 鍵 , 然<br />

後 再 按 下 j。<br />

[Ctrl]+wk 游 標 移 動 到 上 方 的 視 窗 。 按 法 為 同 上 。<br />

[Ctrl]+wq 結 束 下 方 視 窗 , 與 [Ctrl]+w 移 動 到 下 方 視 窗<br />

後 , 再 按 下 :q 離 開 相 同 。<br />

7. vim 環 境 設 定<br />

(a) 個 人 動 作 記 錄 檔 案 :~/.viminfo。 例 如 : 編 輯 同 一 檔 案 時 , 游 標 會 在 上<br />

次 退 出 時 的 位 置 。<br />

(b) 整 體 vim 的 設 定 值 放 在 /etc/vimrc。<br />

(c) 若 要 更 改 vim 設 定 , 建 議 自 行 建 立 ~/.vimrc。<br />

vim 的 環 境 設 定 參 數<br />

:set nu 設 定 行 號 。<br />

:set nonu 取 消 定 行 號 。<br />

:set hlsearch 將 搜 尋 的 字 串 反 白 。<br />

:set autoindent 自 動 縮 排 。<br />

:set noautoindent 不 自 動 縮 排 。<br />

:set backup<br />

自 動 儲 存 備 份 。 備 份 檔 名 為 filename~。<br />

:set rule 顯 示 右 下 角 的 狀 態 說 明 。<br />

:set showmode 顯 示 --insert-- 等 字 眼 在 左 下 角 的 狀 態 列 。<br />

:set backspace=(012) 2 利 用 backspace 例 退 鍵 除 任 意 字 元 ;<br />

0 或 1 僅 可 刪 除 剛 剛 輸 入 的 字 元 。<br />

:set all 顯 示 目 前 所 有 的 環 境 參 數 設 定 值 。<br />

:syntax (off|on) 是 否 依 據 程 式 相 關 語 法 顯 示 不 同 顏 色 。<br />

De-Yu Wang CSIE CYUT 10


1.3. VIM 的 額 外 功 能 CHAPTER 1. VI 編 輯 器<br />

練 習 題<br />

1. 在 vim 的 一 般 模 式 中 , 如 何 將 游 標 經 過 的 地 方 反 白 選 擇 <br />

Sol. 按 v<br />

2. 在 vim 的 一 般 模 式 中 , 如 何 將 游 標 經 過 的 反 白 選 擇 <br />

Sol. 按 V<br />

3. 在 vim 的 一 般 模 式 中 , 如 何 進 入 區 塊 選 擇 ( 長 方 形 ) 環 境 <br />

Sol. [Ctrl]+v<br />

4. 在 vim 的 一 般 模 式 中 , 區 塊 選 擇 後 , 要 將 反 白 的 區 塊 複 製 , 需 按 什 麼 鍵 <br />

Sol. y<br />

5. 在 vim 的 一 般 模 式 中 , 區 塊 選 擇 後 , 要 將 反 白 的 區 塊 刪 除 , 需 按 什 麼 鍵 <br />

Sol. d<br />

6. vim 在 多 檔 編 輯 時 , 如 何 列 出 開 啟 的 所 有 檔 案 <br />

Sol. :files<br />

7. vim 如 何 將 檔 案 filename 的 內 容 在 游 標 處 插 入 <br />

Sol. :r filename<br />

8. 如 何 在 啟 動 vim 時 , 同 時 編 輯 file1 與 file2 兩 個 檔 案 <br />

Sol. vim file1 file2<br />

9. vim 在 多 檔 案 編 輯 時 , 如 何 編 輯 下 一 個 檔 案 <br />

Sol. 按 :n<br />

10. vim 在 多 檔 案 編 輯 時 , 如 何 編 輯 上 一 個 檔 案 <br />

Sol. 按 :N<br />

11. vim 如 何 開 啟 同 一 檔 案 於 新 視 窗 <br />

Sol. :sp<br />

12. vim 如 何 開 啟 檔 案 filename 於 新 視 窗 <br />

Sol. :sp filename<br />

13. vim 在 多 視 窗 下 , 如 何 將 檔 游 標 移 動 到 上 方 的 視 窗 <br />

Sol. 先 按 [Ctrl] 不 放 , 再 按 w 後 , 放 開 所 有 按 鍵 , 再 按 下 k。<br />

14. vim 在 多 視 窗 下 , 如 何 將 檔 游 標 移 動 到 下 方 的 視 窗 <br />

Sol. 先 按 [Ctrl] 不 放 , 再 按 w 後 , 放 開 所 有 按 鍵 , 再 按 下 j。<br />

15. vim 個 人 動 作 記 錄 檔 案 為 何 ( 請 寫 出 目 錄 / 檔 名 )<br />

Sol. ~/.viminfo<br />

16. 整 體 vim 的 設 定 檔 案 為 何 ( 請 寫 出 目 錄 / 檔 名 )<br />

Sol. /etc/vimrc<br />

17. 若 要 更 改 vim 設 定 , 可 以 在 自 己 的 家 目 錄 建 立 那 個 檔 案 <br />

Sol. ~/.vimrc。<br />

De-Yu Wang CSIE CYUT 11


1.4. VI 實 機 練 習 題 CHAPTER 1. VI 編 輯 器<br />

1.4 vi 實 機 練 習 題<br />

1.4.1 練 習 一<br />

1. 在 自 己 的 家 目 錄 建 立 一 個 新 的 目 錄 zzz。<br />

2. 進 入 目 錄 zzz。<br />

3. 下 載 檔 案 viex1.txt, 並 重 新 命 名 為 vi1.txt<br />

4. 使 用 vi 或 vim 編 輯 vi1.txt, 執 行 以 下 動 作 :<br />

(a) 先 到 第 10 行 。<br />

(b) 複 製 3 行 。<br />

(c) 再 到 第 20 行 , 往 下 貼 上 。<br />

(d) 再 到 最 後 一 行 , 往 下 產 生 一 行 空 白 行 方 式 進 入 " 插 入 " 模 式 進 行 編 輯 。<br />

(e) 加 入 文 字 ’ABCDEabcde’。<br />

(f) 換 行 再 加 入 ’1234567890’。<br />

(g) 搜 尋 字 串 "MANPATH", 並 將 其 取 代 為 你 的 學 號 。<br />

(h) 存 檔 後 退 出 。<br />

1.4.2 練 習 二<br />

1. 在 自 己 的 家 目 錄 建 立 一 個 新 的 目 錄 zzz。<br />

2. 進 入 目 錄 zzz。<br />

3. 下 載 檔 案 viex2.txt, 並 重 新 命 名 為 vi2.txt<br />

4. 使 用 vi 或 vim 編 輯 vi2.txt, 執 行 以 下 動 作 :<br />

(a) 先 到 第 5 行 。<br />

(b) 刪 除 3 行 。<br />

(c) 再 到 第 30 行 , 往 上 貼 上 。<br />

(d) 再 到 第 一 行 , 往 上 產 生 一 行 空 白 行 方 式 進 入 " 插 入 " 模 式 進 行 編 輯 。<br />

(e) 加 入 文 字 ’ABCDEabcde’。<br />

(f) 換 行 再 加 入 ’1234567890’。<br />

(g) 從 第 30 行 至 最 後 一 行 搜 尋 字 串 "MANPATH", 並 將 其 取 代 為 你 的 學 號 。<br />

(h) 存 檔 後 退 出 。<br />

De-Yu Wang CSIE CYUT 12


1.4. VI 實 機 練 習 題 CHAPTER 1. VI 編 輯 器<br />

1.4.3 練 習 三<br />

1. 在 自 己 的 家 目 錄 建 立 一 個 新 的 目 錄 zzz。<br />

2. 進 入 目 錄 zzz。<br />

3. 下 載 檔 案 viex3.txt, 並 重 新 命 名 為 vi2.txt<br />

4. 使 用 vi 或 vim 編 輯 vi3.txt, 執 行 以 下 動 作 :<br />

(a) 先 到 第 35 行 。<br />

(b) 將 下 一 行 合 併 至 這 一 行<br />

(c) 再 到 第 20 行 , 刪 除 這 一 行 到 第 一 行 的 資 料 。<br />

(d) 再 到 第 10 行 , 在 這 行 的 最 後 加 入 文 字 ’ABCDEabcde’。<br />

(e) 換 行 再 加 入 ’1234567890’。<br />

(f) 從 第 30 行 至 第 55 行 搜 尋 字 串 "man", 並 將 其 取 代 為 你 的 學 號 。<br />

(g) 存 檔 後 退 出 。<br />

De-Yu Wang CSIE CYUT 13


1.4. VI 實 機 練 習 題 CHAPTER 1. VI 編 輯 器<br />

De-Yu Wang CSIE CYUT 14


CHAPTER 2.<br />

SHELL 變 數<br />

Chapter 2<br />

Shell 變 數<br />

2.1 Shell 的 變 數 功 能<br />

• 何 謂 變 數 :<br />

1. 以 一 組 文 字 或 符 號 等 , 來 取 代 一 些 設 定 或 者 是 一 串 保 留 的 資 料 。<br />

2. 例 如 : 每 個 帳 號 的 郵 件 信 箱 預 設 是 以 MAIL 這 個 變 數 來 進 行 存 取 。<br />

✞<br />

圱 [root@dywOffice ~]# cat /etc/profile<br />

圳<br />

LOGNAME=$USER<br />

MAIL="/var/spool/mail/$USER"<br />

✡✝<br />

✆<br />

• 變 數 取 用<br />

✞<br />

[root@dywOffice ~]# echo $variable<br />

圲 [root@dywOffice ~]# echo ${variable}<br />

圴 [root@dywOffice ~]# echo $PATH<br />

/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/usr/<br />

local/sbin<br />

圶 [root@dywOffice ~]# echo ${PATH}<br />

/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/usr/<br />

local/sbin<br />

✡✝<br />

✆<br />

• 變 數 設 定<br />

✞<br />

圱 [root@linux ~]# echo $myname<br />


2.1. SHELL 的 變 數 功 能 CHAPTER 2. SHELL 變 數<br />

圵 csie


2.1. SHELL 的 變 數 功 能 CHAPTER 2. SHELL 變 數<br />

(a) 使 用 quote 『 ‘ command‘ 』;( ‘ 是 鍵 盤 上 方 的 數 字 鍵 1 左 邊<br />

那 個 按 鍵 , 而 不 是 單 引 號 。)<br />

(b) 使 用 $(command)。<br />

✞<br />

# 範 例 四 : 先 以 指 令 locate 找 到 crontab 目 錄 , 再 顯 示 目 錄 內 容<br />

圲 [root@linux ~]# ls -l ‘locate crontab‘<br />

圴 # 範 例 五 : 進 入 目 前 核 心 的 模 組 目 錄 <br />

[root@linux ~]# cd /lib/modules/$(uname -r)/kernel<br />

圶 # 利 用 uname -r 指 令 先 取 得 版 本 資 訊 。<br />

✡✝<br />

✆<br />

7. 若 該 變 數 為 擴 增 變 數 內 容 時 , 則 需 以 雙 引 號 及 $ 變 數 名 稱 如 :『<br />

"$PATH":/home』 繼 續 累 加 內 容 ;<br />

✞<br />

# 範 例 六 : 在 PATH 變 數 中 『 累 加 』 目 錄 /home/csie/bin<br />

圲 [root@linux ~]# PATH=$PATH:/home/csie/bin<br />

[root@linux ~]# PATH="$PATH":/home/csie/bin<br />

圴 # 上 面 這 兩 種 格 式 在 PATH 裡 頭 的 設 定 都 是 OK 。 但 是 底 下 的 例 子 就 不 見<br />

得 。<br />

圶 # 範 例 七 : 承 範 例 三 , 將 name 的 內 容 多 出 "yes" <br />

[root@linux ~]# name=$nameyes<br />

圸 # name 的 內 容 是 $nameyes 這 個 變 數 。 但 沒 有 設 定 變 數 , 應 該 如<br />

下 : nameyes<br />

[root@linux ~]# name="$name"yes<br />

圱 地 [root@linux ~]# name=${name}yes<br />

✡✝<br />

✆<br />

8. 通 常 大 寫 字 元 為 系 統 預 設 變 數 , 自 行 設 定 變 數 可 以 使 用 小 寫 字 元 , 方 便<br />

判 斷 ;<br />

9. 取 消 變 數 的 方 法 為 :『unset 變 數 名 稱 』。<br />

✞<br />

# 範 例 九 : 取 消 設 定 的 name 變 數 內 容<br />

圲 [root@linux ~]# unset name<br />

✡✝<br />

✆<br />

• 變 數 的 用 途<br />

1. 簡 化 路 徑 名 稱<br />

✞<br />

[dywang@dywOffice ~]$ linuxpro=\<br />

圲 /home/dywang/Documents/latex/cjk-tex/linuxprogram/<br />

[dywang@dywOffice ~]$ cd linuxpro<br />

圴 bash: cd: linuxpro: No such file or directory<br />

[dywang@dywOffice ~]$ cd $linuxpro<br />

De-Yu Wang CSIE CYUT 17


2.1. SHELL 的 變 數 功 能 CHAPTER 2. SHELL 變 數<br />

圶<br />

[dywang@dywOffice linuxprogram]$ pwd<br />

/home/dywang/Documents/latex/cjk-tex/linuxprogram<br />

✡✝<br />

✆<br />

2. 方 便 程 式 修 改<br />

✞<br />

圱 #define QGL_VERSION 450<br />

#define QGL_VERSION_STR "4.5"<br />

圳 QM_EXPORT_OPENGL inline const char *qGLVersion() {<br />

qObsolete( 0, "qGLVersion", "qVersion" );<br />

圵<br />

✡✝<br />

return QGL_VERSION_STR;<br />

✆<br />

練 習 題<br />

1. 在 Bash shell 環 境 下 , 如 何 取 出 變 數 VAR1 的 內 容 <br />

Sol. $VAR1 或 ${VAR1}<br />

2. 在 Bash shell 環 境 下 , 如 何 將 變 數 VAR1 的 內 容 顯 示 在 螢 幕 上 <br />

Sol. echo $VAR1 或 echo ${VAR1}<br />

3. 在 Bash shell 環 境 下 , 以 23name=csie 設 定 變 數 是 否 正 確 , 若 不 正 確 請<br />

說 明 其 原 因 <br />

Sol. 變 數 不 能 以 數 字 開 頭<br />

4. 在 Bash shell 環 境 下 , 以 name = csie 設 定 變 數 是 否 正 確 , 若 不 正 確 請<br />

說 明 其 原 因 <br />

Sol. 等 號 兩 邊 不 能 直 接 接 空 白 字 元<br />

5. 在 Bash shell 環 境 下 , 以 na$me=csie 設 定 變 數 是 否 正 確 , 若 不 正 確 請 說<br />

明 其 原 因 <br />

Sol. 變 數 名 稱 只 能 是 英 文 字 母 與 數 字 , 但 是 數 字 不 能 是 開 頭 字 元<br />

6. 在 Bash shell 環 境 下 , 若 變 數 name=csie, 則<br />

myname="$name its me",myname 內 容 為 何 <br />

Sol. csie its me<br />

7. 在 Bash shell 環 境 下 , 若 變 數 name=csie, 則<br />

myname=’$name its me’,myname 內 容 為 何 <br />

Sol. $name its me<br />

8. 在 Bash shell 環 境 下 , 若 變 數 name=csie, 則<br />

myname=CYUT\ CSIE,myname 內 容 為 何 <br />

Sol. CYUT CSIE<br />

9. 在 Bash shell 環 境 下 , 要 在 PATH 變 數 中 『 累 加 』 目 錄 /home/csie/bin<br />

如 何 處 理 <br />

Sol. PATH=$PATH:/home/csie/bin 或 PATH="$PATH":/home/csie/bin<br />

De-Yu Wang CSIE CYUT 18


2.2. 環 境 變 數 CHAPTER 2. SHELL 變 數<br />

10. 在 Bash shell 環 境 下 , 要 將 name 的 內 容 多 出 "yes" 如 何 處 理 <br />

Sol. name="$name"yes 或 name=${name}yes<br />

11. 在 Bash shell 環 境 下 , 若 變 數 name="csie’s name", 則<br />

myname=name,myname 內 容 為 何 <br />

Sol. name<br />

12. 在 Bash shell 環 境 下 , 若 變 數 name="csie’s name", 則<br />

myname=$name,myname 內 容 為 何 <br />

Sol. csie’s name<br />

13. 在 Bash shell 環 境 下 , 若 變 數 name=csie\’s\ name, 則<br />

myname=$name,myname 內 容 為 何 <br />

Sol. csie’s name<br />

14. 在 Bash shell 環 境 下 , 若 要 先 以 指 令 locate 找 到 crontab 目 錄 , 再 顯<br />

示 目 錄 , 如 何 以 一 行 指 令 完 成 <br />

Sol. ls -l ‘locate crontab‘( ‘ 是 鍵 盤 上 方 的 數 字 鍵 1 左 邊 那 個 按<br />

鍵 , 而 不 是 單 引 號 。) 或 ls -l $(locate crontab)<br />

15. 在 Bash shell 環 境 下 , 若 要 進 入 目 前 核 心 的 模 組 目 錄 , 如 何 以 一 行 指 令 完<br />

成 <br />

Sol. cd /lib/modules/‘uname -r‘/kernel( ‘ 是 鍵 盤 上 方 的 數 字 鍵 1 左<br />

邊 那 個 按 鍵 , 而 不 是 單 引 號 。) 或 cd /lib/modules/$(uname -r)/kernel<br />

16. 在 Bash shell 環 境 下 , 若 要 先 指 令 foo 時 , 需 要 先 執 行 命 令 bar 以 提 供<br />

資 訊 , 除 了 以 quote ‘bar‘ 括 起 來 外 , 還 可 如 何 執 行 <br />

Sol. $(bar)<br />

2.2 環 境 變 數<br />

• 變 數 的 有 效 範 圍<br />

1. shell 的 父 、 子 程 序 : 被 導 出 (export) 後 的 變 數 , 可 以 被 子 程 序 所 引<br />

用 , 其 他 自 訂 變 數 內 容 則 不 會 存 在 於 子 程 序 中 。<br />

2. 腳 本 ( scripts ) 的 編 寫 : 軟 體 若 使 用 到 2 個 scripts,scripts1.sh<br />

及 scripts2.sh ,scripts2.sh 要 引 用 scripts1.sh 的 變 數 , 則<br />

scripts1.sh 中 設 定 的 變 數 必 須 以 export 設 定 。<br />

3. 環 境 變 數 可 以 讓 子 程 序 繼 續 引 用 的 原 因 :<br />

(a) 啟 動 一 個 shell 時 , 作 業 系 統 分 配 一 記 憶 區 塊 給 shell 使 用 , 此<br />

區 域 之 變 數 可 以 讓 子 程 序 存 取 ;<br />

(b) 利 用 export 功 能 , 可 以 讓 變 數 的 內 容 寫 到 上 述 的 記 憶 區 塊 當 中 ( 環<br />

境 變 數 );<br />

(c) 當 載 入 另 一 個 shell 時 ( 亦 即 啟 動 子 程 序 , 而 離 開 原 本 的 父 程 序<br />

了 ), 子 shell 可 以 將 父 shell 的 環 境 變 數 所 在 的 記 憶 區 塊 導 入<br />

自 己 的 環 境 變 數 區 塊 當 中 。<br />

De-Yu Wang CSIE CYUT 19


2.2. 環 境 變 數 CHAPTER 2. SHELL 變 數<br />

• export、env、set 不 加 選 項 參 數 , 列 出 之 變 數 :<br />

1. export 列 出 所 有 設 定 為 導 出 (export) 的 變 數 :<br />

2. env 列 出 所 有 的 環 境 變 數 :<br />

3. set 列 出 所 有 的 自 訂 及 環 境 變 數 , 也 包 括 設 定 為 空 的 變 數 。<br />

• export、env、set 使 用 之 不 同 :<br />

1. 使 用 export 設 定 變 數 為 導 出 , 給 子 程 序 或 後 來 呼 叫 的 程 式 使 用 ;<br />

2. 使 用 env 設 定 環 境 變 數 給 後 接 命 令 使 用 , 只 限 於 命 令 執 行 時 使 用 ;<br />

3. 使 用 set 設 定 環 境 變 數 , 等 同 於 直 接 設 定 , 如 FOO=settest。<br />

• 自 訂 變 數 轉 成 環 境 變 數 : export<br />

1. 僅 下 達 export 而 沒 有 接 變 數 時 , 會 列 出 所 有 設 定 為 導 出 (export) 的<br />

變 數 。<br />

✞<br />

圱 [root@dywHome2 ~]# export<br />

declare -x DISPLAY=":0"<br />

圳 declare -x ENV="/root/.bashrc"<br />

declare -x GCONF_TMPDIR="/tmp"<br />

圵 declare -x G_FILENAME_ENCODING="@locale"<br />

declare -x HISTCONTROL="ignoredups"<br />

圷 declare -x HISTSIZE="1000"<br />

declare -x HOME="/root"<br />

圹 declare -x HOSTNAME="dywHome2"<br />

declare -x INPUTRC="/etc/inputrc"<br />

圱 圱 declare -x LANG="en_US.UTF-8" 中 間 省 略<br />

圱 圳 declare -x USER="root"<br />

declare -x USERNAME="root"<br />

圱 圵 declare -x XAUTHORITY="/home/dywang/.Xauthority"<br />

✡✝<br />

✆<br />

2. 進 入 子 程 序 後 , 在 父 程 序 中 的 自 訂 變 數 設 定 將 不 再 繼 續 的 存 在 。 會 存 在<br />

子 程 序 中 的 , 僅 有 『 環 境 變 數 』。<br />

3. 如 果 能 將 自 訂 變 數 變 成 導 出 , 則 可 讓 該 變 數 值 繼 續 存 在 於 子 程 序 。<br />

4. 想 讓 變 數 內 容 繼 續 在 子 程 序 中 使 用 :export 變 數 。<br />

5. 若 該 變 數 需 要 在 其 他 子 程 序 執 行 , 則 需 要 以 export 來 導 出 變 數 , 例<br />

如 『export PATH』;<br />

✞<br />

圱 # 範 例 : 如 何 讓 name=csie 用 在 下 個 shell 的 程 序 <br />

[root@dywOffice ~]# echo $SHLVL


2.2. 環 境 變 數 CHAPTER 2. SHELL 變 數<br />

[root@dywOffice ~]# echo $SHLVL


2.2. 環 境 變 數 CHAPTER 2. SHELL 變 數<br />

LANG=en_US.UTF-8<br />


2.2. 環 境 變 數 CHAPTER 2. SHELL 變 數<br />

圲 圶


2.2. 環 境 變 數 CHAPTER 2. SHELL 變 數<br />

5. PS1: 提 示 字 元 的 設 定<br />

(a) \d : 代 表 日 期 , 格 式 為 Weekday Month Date, 例 如 "Mon Aug 1"<br />

(b) \H : 完 整 的 主 機 名 稱 。 例 如 linux.csie.tw。<br />

(c) \h : 僅 取 主 機 名 稱 的 第 一 個 名 字 。 上 例 為 linux,.csie.tw 被 省<br />

略 。<br />

(d) \t : 顯 示 時 間 , 為 24 小 時 格 式 , 如 : HH:MM:SS<br />

(e) \T : 顯 示 時 間 ,12 小 時 的 時 間 格 式 。<br />

(f) \A : 顯 示 時 間 ,24 小 時 格 式 , HH:MM<br />

(g) \u : 目 前 使 用 者 的 帳 號 名 稱 ;<br />

(h) \v :BASH 的 版 本 資 訊 ;<br />

(i) \w : 完 整 的 工 作 目 錄 名 稱 。 家 目 錄 會 以 ~ 取 代 ;<br />

(j) \W : 利 用 指 令 basename 取 得 工 作 目 錄 名 稱 , 所 以 僅 會 列 出 最 後 一<br />

個 目 錄 名 。<br />

(k) \# : 下 達 的 第 幾 個 指 令 。<br />

(l) \$ : 提 示 字 元 , 如 果 是 root 時 , 提 示 字 元 為 # , 否 則 就 是 $。<br />

✞<br />

[dywang@dywOffice ~]$ PS1=’[\u@\h \w \A #\#]\$ ’<br />

圲 [dywang@dywOffice ~ 10:51 #16]$ echo $PS1<br />

[\u@\h \w \A #\#]\$<br />

圴 [dywang@dywOffice ~ 10:51 #17]$<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 在 Bash shell 環 境 下 , 如 何 讓 變 數 name=csie 用 在 下 一 層 shell 的 程<br />

序 <br />

Sol. export name<br />

2. 在 Bash shell 環 境 下 , 如 何 取 消 變 數 name=csie 的 設 定 <br />

Sol. unset name<br />

3. 在 Bash shell 環 境 下 , 設 定 變 數 linux=/home/csie/Documents/linux/,<br />

則 執 行 cd linux, 結 果 為 何 <br />

Sol. No such file or directory<br />

4. 在 Bash shell 環 境 下 , 設 定 變 數 linux=/home/csie/Documents/linux/,<br />

則 執 行 cd $linux , 結 果 為 何 <br />

Sol. 改 變 目 錄 至 /home/csie/Documents/linux/<br />

5. 在 目 前 shell 環 境 下 自 訂 變 數 name=csie, 進 入 子 shell 後 執 行<br />

echo $name 會 出 現 什 麼 結 果 <br />

Sol. 空 的 內 容 , 因 為 自 訂 變 數 內 容 不 會 存 在 於 子 程 序 中 。<br />

De-Yu Wang CSIE CYUT 24


2.2. 環 境 變 數 CHAPTER 2. SHELL 變 數<br />

6. 在 目 前 shell 環 境 下 有 一 環 境 變 數 name=csie, 則 進 入 子 shell 後 執 行<br />

echo $name 會 出 現 什 麼 結 果 <br />

Sol. csie<br />

7. 某 一 體 使 用 到 2 個 腳 本 (scripts):scripts1.sh 及<br />

scripts2.sh,scripts2.sh 要 引 用 scripts1.sh 的 變 數 , 則<br />

scripts1.sh 中 設 定 的 變 數 必 須 如 何 設 定 <br />

Sol. 以 export 設 定 。<br />

8. 在 Bash shell 環 境 下 ,export、env、set 不 加 選 項 參 數 , 列 出 之 變 數 有<br />

何 不 同 <br />

Sol. export 及 env 列 出 所 有 導 出 的 環 境 變 數 : set 列 出 所 有 的 自 訂 及<br />

環 境 變 數 , 也 包 括 設 定 為 空 的 變 數 。<br />

9. 在 Bash shell 環 境 下 , 如 何 查 看 目 前 是 在 第 幾 層 shell<br />

Sol. echo $SHLVL<br />

10. 在 Bash shell 環 境 下 , 如 何 列 出 目 前 環 境 下 的 所 有 環 境 變 數 與 其 內 容 <br />

Sol. env<br />

11. Bash shell 的 環 境 變 數 HOSTNAME=linux.csie.tw, 代 表 意 義 為 何 <br />

Sol. 主 機 名 稱 為 linux.csie.tw<br />

12. Bash shell 的 環 境 變 數 HISTSIZE=1000, 代 表 意 義 為 何 <br />

Sol. 『 記 錄 指 令 的 筆 數 』 預 設 可 記 錄 1000 筆<br />

13. Bash shell 的 環 境 變 數 ENV=/root/.bashrc, 代 表 意 義 為 何 <br />

Sol. 使 用 者 root 的 個 人 環 境 設 定 檔<br />

14. Bash shell 的 環 境 變 數 PWD=/root, 代 表 意 義 為 何 <br />

Sol. 目 前 使 用 者 所 在 的 工 作 目 錄 為 /root<br />

15. Bash shell 的 環 境 變 數 HOME=/root, 代 表 意 義 為 何 <br />

Sol. 使 用 者 的 家 目 錄 為 /root<br />

16. 在 Bash shell 中 有 一 變 數 name=CSIE, 則 執 行 echo $name 與 env<br />

name=CYUT, 產 生 的 變 數 name 內 容 有 何 不 同 <br />

Sol. echo $name 的 結 果 為 CSIE;env name=CYUT env 的 結 果 為 CYUT。<br />

17. 列 出 Bash shell 的 所 有 變 數 , 要 使 用 那 個 指 令 <br />

Sol. set<br />

18. Bash shell 的 變 數 0, 代 表 意 義 為 何 <br />

Sol. 目 前 shell 的 執 行 命 令 名 稱<br />

19. Bash shell 的 變 數 $, 代 表 意 義 為 何 <br />

Sol. 目 前 shell 的 PID<br />

20. Bash shell 的 變 數 , 代 表 意 義 為 何 <br />

Sol. 上 個 執 行 的 指 令 所 回 傳 的 值<br />

De-Yu Wang CSIE CYUT 25


2.2. 環 境 變 數 CHAPTER 2. SHELL 變 數<br />

21. 一 般 而 言 , 上 個 指 令 執 行 成 功 , 則 echo $ 結 果 為 何 <br />

Sol. 0<br />

22. Bash shell 的 變 數 RANDOM, 代 表 意 義 為 何 <br />

Sol. 產 生 介 於 0~32767 之 間 的 一 個 整 數<br />

23. 在 Bash shell 下 , 隨 機 產 生 0~9 之 間 的 數 值 , 如 何 做 <br />

Sol. declare -i number=$RANDOM*10/32767 ; echo $number<br />

24. Bash shell 設 定 PS1=’\d ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 代 表 日 期 , 格 式 為 Weekday Month Date, 例 如 "Mon Aug 1"<br />

25. Bash shell 設 定 PS1=’\H ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 完 整 的 主 機 名 稱 。 例 如 linux.csie.tw。<br />

26. Bash shell 設 定 PS1=’\h ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 僅 取 主 機 名 稱 的 第 一 個 名 字 。 例 如 linux.csie.tw, 則 只 取 linux。<br />

27. Bash shell 設 定 PS1=’\t ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 顯 示 時 間 , 為 24 小 時 格 式 , 如 : HH:MM:SS 。<br />

28. Bash shell 設 定 PS1=’\T ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 顯 示 時 間 ,12 小 時 的 時 間 格 式 。<br />

29. Bash shell 設 定 PS1=’\A ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 顯 示 時 間 ,24 小 時 格 式 , HH:MM。<br />

30. Bash shell 設 定 PS1=’\u ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 目 前 使 用 者 的 帳 號 名 稱 。<br />

31. Bash shell 設 定 PS1=’\v ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. BASH 的 版 本 資 訊 。<br />

32. Bash shell 設 定 PS1=’\w ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 完 整 的 工 作 目 錄 名 稱 。 家 目 錄 會 以 ~ 取 代 。<br />

33. Bash shell 設 定 PS1=’\W ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 利 用 basename 取 得 工 作 目 錄 名 稱 , 所 以 僅 會 列 出 最 後 一 個 目 錄 名 。<br />

34. Bash shell 設 定 PS1=’\# ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 下 達 的 第 幾 個 指 令 。<br />

35. Bash shell 設 定 PS1=’\$ ’, 則 的 提 示 字 元 如 何 顯 示 <br />

Sol. 提 示 字 元 , 如 果 是 root 時 , 提 示 字 元 為 # , 否 則 就 是 $。<br />

36. Bash shell 的 提 示 字 元 為 [dywang@dywOffice ~ 10:51 #16]$ , 則 變 數<br />

PS1 應 如 何 設 定 <br />

Sol. PS1=’[\u@\h \w \A #\#]\$ ’<br />

De-Yu Wang CSIE CYUT 26


2.3. 變 數 鍵 盤 讀 取 與 宣 告 CHAPTER 2. SHELL 變 數<br />

2.3 變 數 鍵 盤 讀 取 與 宣 告<br />

• 讀 取 來 自 鍵 盤 輸 入 的 變 數 :read<br />

1. read 指 令<br />

✞<br />

[root@linux ~]# read [-pt] variable 選 項 :<br />

圲<br />

-p : 後 面 可 以 接 提 示 字 元 。<br />

圴 -t : 後 面 可 以 接 等 待 的 『 秒 數 』, 不 會 一 直 等 待 使 用 者 。<br />

✡✝<br />

✆<br />

2. 讓 使 用 者 由 鍵 盤 輸 入 一 內 容 , 將 該 內 容 變 成 atest 變 數<br />

✞<br />

[root@linux ~]# read atest<br />

圲 This is a test<br />

[root@linux ~]# echo $atest<br />

圴 This is a test<br />

✡✝<br />

✆<br />

3. 提 示 使 用 者 30 秒 內 輸 入 自 己 的 大 名 , 將 該 輸 入 字 串 做 成 named 變 數<br />

圲<br />

圴<br />

✞<br />

[root@linux ~]# read -p "Please keyin your name: " -t 30<br />

named<br />

Please keyin your name: csie<br />

[root@linux ~]# echo $named<br />

csie<br />

✡✝<br />

✆<br />

• 宣 告 變 數 的 屬 性 :<br />

1. declare / typeset 指 令<br />

✞<br />

[root@linux ~]# declare [-aixr] variable 選 項 :<br />

圲<br />

-a : 將 後 面 的 variable 定 義 成 為 陣 列 (array), 大 小 無 限<br />

圴<br />

制 ,index 從 0 開 始<br />

-i : 將 後 面 接 的 variable 定 義 成 為 整 數 數 字 (integer)<br />

-x : 用 法 與 export 一 樣 , 就 是 將 後 面 的 variable 變 成 環 境 變 數 ;<br />

圶 -r : 將 一 個 variable 的 變 數 設 定 成 為 readonly , 該 變 數 不 可 被 更<br />

✡✝<br />

改 內 容 , 也 不 能 unset<br />

✆<br />

2. 讓 變 數 sum 進 行 100+300+50 的 加 總 結 果<br />

✞<br />

[root@linux ~]# sum=100+300+50<br />

圲 [root@linux ~]# echo $sum<br />

De-Yu Wang CSIE CYUT 27


2.4. 陣 列 CHAPTER 2. SHELL 變 數<br />

100+300+50


2.5. 變 數 的 變 化 與 取 代 CHAPTER 2. SHELL 變 數<br />

圱 圱 11 22 33<br />

[dywang@deyu ~]$ sum=(11 22 33); echo ${sum[@]}<br />

圱 圳 11 22 33<br />

✡✝<br />

✆<br />

3. 陣 列 元 素 的 變 化<br />

✞<br />

圱 [dywang@deyu ~]$ arr=(1 22 333 4444); arr=(${arr[@]} 55555); echo<br />

${arr[@]}<br />

1 22 333 4444 55555<br />

圳 # 從 第 個 元 素 取 到 最 後 一 個 元 素 #2<br />

[dywang@deyu ~]$ arr=(${arr[@]:2}); echo ${arr[@]}<br />

圵 333 4444 55555<br />

圷<br />

# 從 最 前 面 加 入 元 素 #<br />

[dywang@deyu ~]$ arr=(0 ${arr[@]}); echo ${arr[@]}<br />

0 333 4444 55555<br />

圹 # 從 第 個 元 素 取 到 倒 數 第 個 元 素 #01<br />

[dywang@deyu ~]$ arr=(${arr[@]:0:$((${#arr[@]}-1))}); echo ${arr[<br />

@]}<br />

圱 圱 0 333 4444<br />

✡✝<br />

✆<br />

2.5 變 數 的 變 化 與 取 代<br />

1. 兩 種 變 數 取 用 的 方 法 :<br />

✞<br />

圱 [root@linux ~]# echo $HOME<br />

[root@linux ~]# echo ${HOME}<br />

✡✝<br />

✆<br />

2. 完 整 變 數 的 內 容 ;<br />

✞<br />

[dywang@deyu linuxprogram]$ blkid /dev/mapper/vg_dywusb-root<br />

圲 /dev/mapper/vg_dywusb-root: LABEL="dywusb-root" UUID="76989c3fa591-47a7-98dc-9dcc32fb7f19"<br />

TYPE="ext4"<br />

[dywang@deyu linuxprogram]$ uuid=$(blkid /dev/mapper/vg_dywusbroot);echo<br />

$uuid<br />

圴 /dev/mapper/vg_dywusb-root: LABEL="dywusb-root" UUID="76989c3fa591-47a7-98dc-9dcc32fb7f19"<br />

TYPE="ext4"<br />

✡✝<br />

✆<br />

3. 從 最 前 面 開 始 比 對 , 刪 除 符 合 的 字 元 。<br />

De-Yu Wang CSIE CYUT 29


2.5. 變 數 的 變 化 與 取 代 CHAPTER 2. SHELL 變 數<br />

圲<br />

圴<br />

圶<br />

圸<br />

✞<br />

[dywang@deyu linuxprogram]$ uuid=$(blkid /dev/mapper/vg_dywusbroot);echo<br />

$uuid<br />

/dev/mapper/vg_dywusb-root: LABEL="dywusb-root" UUID="76989c3fa591-47a7-98dc-9dcc32fb7f19"<br />

TYPE="ext4"<br />

[dywang@deyu linuxprogram]$ uuid=${uuid#*=\"}; echo $uuid<br />

dywusb-root" UUID="76989c3f-a591-47a7-98dc-9dcc32fb7f19" TYPE="<br />

ext4"<br />

[dywang@deyu linuxprogram]$ uuid=$(blkid /dev/mapper/vg_dywusbroot);echo<br />

$uuid<br />

/dev/mapper/vg_dywusb-root: LABEL="dywusb-root" UUID="76989c3fa591-47a7-98dc-9dcc32fb7f19"<br />

TYPE="ext4"<br />

[dywang@deyu linuxprogram]$ uuid=${uuid##*=\"}; echo $uuid<br />

ext4"<br />

# 變 數 名 稱 後 面 如 果 接 了 兩 個 ## , 表 示 在 ## 後 面 的 字 串 取 『 最 長 的 』 那 一<br />

段 ;<br />

圱 地 # 如 果 僅 有 一 個 # , 表 示 取 『 最 小 的 那 一 段 』。<br />

✡✝<br />

✆<br />

4. 從 後 面 開 始 比 對 並 刪 除 :<br />

圲<br />

圴<br />

圶<br />

圸<br />

✞<br />

[dywang@deyu linuxprogram]$ uuid=$(blkid /dev/mapper/vg_dywusbroot);echo<br />

$uuid<br />

/dev/mapper/vg_dywusb-root: LABEL="dywusb-root" UUID="76989c3fa591-47a7-98dc-9dcc32fb7f19"<br />

TYPE="ext4"<br />

[dywang@deyu linuxprogram]$ uuid=${uuid%%\"*}; echo $uuid<br />

/dev/mapper/vg_dywusb-root: LABEL=<br />

[dywang@deyu linuxprogram]$ uuid=$(blkid /dev/mapper/vg_dywusbroot);echo<br />

$uuid<br />

/dev/mapper/vg_dywusb-root: LABEL="dywusb-root" UUID="76989c3fa591-47a7-98dc-9dcc32fb7f19"<br />

TYPE="ext4"<br />

[dywang@deyu linuxprogram]$ uuid=${uuid%\"*}; echo $uuid<br />

/dev/mapper/vg_dywusb-root: LABEL="dywusb-root" UUID="76989c3fa591-47a7-98dc-9dcc32fb7f19"<br />

TYPE="ext4<br />

# %% 刪 除 最 長 的 匹 配 ,% 則 是 最 短 的 匹 配 。<br />

✡✝<br />

✆<br />

5. 取 代 變 數 部 分 字 串<br />

✞<br />

圱 [dywang@deyu linuxprogram]$ uuid=$(blkid /dev/mapper/vg_dywusbroot);echo<br />

$uuid<br />

/dev/mapper/vg_dywusb-root: LABEL="dywusb-root" UUID="76989c3fa591-47a7-98dc-9dcc32fb7f19"<br />

TYPE="ext4"<br />

圳 [dywang@deyu linuxprogram]$ uuid=$(blkid /dev/mapper/vg_dywusbroot);echo<br />

${uuid/dywusb/DYW}<br />

/dev/mapper/vg_DYW/-root: LABEL="dywusb-root" UUID="76989c3f-a591<br />

-47a7-98dc-9dcc32fb7f19" TYPE="ext4"<br />

圵 [dywang@deyu linuxprogram]$ uuid=$(blkid /dev/mapper/vg_dywusbroot);echo<br />

${uuid//dywusb/DYW}<br />

De-Yu Wang CSIE CYUT 30


2.6. 變 數 的 設 定 CHAPTER 2. SHELL 變 數<br />

/dev/mapper/vg_DYW/-root: LABEL="DYW/-root" UUID="76989c3f-a591<br />

-47a7-98dc-9dcc32fb7f19" TYPE="ext4"<br />

圷 # 變 數 後 面 接 / 時 , 表 示 進 行 『 取 代 』 的 工 作 , 且 僅 取 代 『 第 一 個 』<br />

# 如 果 是 // , 則 表 示 全 部 的 字 串 都 取 代 。<br />

✡✝<br />

✆<br />

6. 例 題 : 請 取 出 uuid 編 號 , 不 含 雙 引 號 。<br />

2.6 變 數 的 設 定<br />

1. 變 數 設 定 方 式<br />

變 數 設 定 方 式 str 沒 有 設 定 str 為 空 字 串 str 已 設 定 非 為 空 字 串<br />

var=${str-expr} var=expr var= var=$str<br />

var=${str:-expr} var=expr var=expr var=$str<br />

var=${str+expr} var= var=expr var=expr<br />

var=${str:+expr} var= var= var=expr<br />

var=${str=expr} str=expr str 不 變 str 不 變<br />

var=expr var= var=$str<br />

var=${str:=expr} str=expr str=expr str 不 變<br />

var=expr var=expr var=$str<br />

var=${strexpr} expr 輸 出 至 stderr var= var=$str<br />

var=${str:expr} expr 輸 出 至 stderr expr 輸 出 至 stderr var=$str<br />

2. 若 str 這 個 變 數 內 容 存 在 , 則 var 設 定 為 str , 否 則 var 設 定 為<br />

"newvar"<br />

✞<br />

[root@linux ~]# unset str; var=${str:-newvar}<br />

圲 [root@linux ~]# echo var="$var", str="$str"<br />

var=newvar, str=


2.6. 變 數 的 設 定 CHAPTER 2. SHELL 變 數<br />

4. 若 str 這 個 變 數 存 在 , 則 var 等 於 str , 否 則 輸 出 "novar"<br />

✞<br />

[root@linux ~]# unset str; var=${strnovar}<br />

圲 -bash: str: novar


2.6. 變 數 的 設 定 CHAPTER 2. SHELL 變 數<br />

10. 在 Bash shell 環 境 下 , 如 何 將 陣 列 變 數 sum 的 內 容 全 部 列 出 <br />

Sol. echo ${sum[@]}<br />

11. 在 Bash shell 環 境 下 , 如 何 將 陣 列 變 數 sum 的 元 素 個 數 列 出 <br />

Sol. echo ${#sum[@]}<br />

12. 在 Bash shell 環 境 下 , 如 何 列 出 檔 案 系 統 及 程 序 的 所 有 限 制 <br />

Sol. ulimit -a<br />

13. 在 Bash shell 環 境 下 , 如 何 限 制 單 一 使 用 者 可 以 使 用 的 最 大 程<br />

序 (process) 數 量 為 1024<br />

Sol. ulimit -u 1024<br />

14. 在 Bash shell 環 境 下 , 如 何 限 制 使 用 者 僅 能 建 立 1MBytes 以 下 的 容 量 的<br />

檔 案 <br />

Sol. ulimit -f 1024<br />

15. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie##/*/}, 結 果 為 何 <br />

Sol. testing.x.sh<br />

16. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie#/*/}, 結 果 為 何 <br />

Sol. csie/testing/testing.x.sh<br />

17. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie##/*}, 結 果 為 何 <br />

Sol. ( 空 白 , 被 刪 光 )<br />

18. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie#/*}, 結 果 為 何 <br />

Sol. home/csie/testing/testing.x.sh<br />

19. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie%%/*/}, 結 果 為 何 <br />

Sol. /home/csie/testing/testing.x.sh<br />

20. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie%%/*}, 結 果 為 何 <br />

Sol. ( 空 白 , 被 刪 光 )<br />

21. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie%/*/}, 結 果 為 何 <br />

Sol. /home/csie/testing/testing.x.sh<br />

22. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie%/*}, 結 果 為 何 <br />

Sol. /home/csie/testing<br />

De-Yu Wang CSIE CYUT 33


2.6. 變 數 的 設 定 CHAPTER 2. SHELL 變 數<br />

23. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie/testing/TEST}, 結 果 為 何 <br />

Sol. /home/csie/TEST/testing.x.sh<br />

24. 在 Bash shell 環 境 下 , 若 變 數 csie="/home/csie/testing/testing.x.sh",<br />

則 執 行 echo ${csie//testing/TEST}, 結 果 為 何 <br />

Sol. /home/csie/TEST/TEST.x.sh<br />

25. 在 Bash shell 環 境 下 , 如 果 變 數 str 已 設 定 或 為 空 字 串 , 則 變 數<br />

var=$str; 否 則 var=new 字 串 , 如 何 設 定 <br />

Sol. var=${str-new}<br />

26. 在 Bash shell 環 境 下 , 如 果 變 數 str 已 設 定 為 非 空 字 串 , 則 變 數<br />

var=$str; 否 則 var=new 字 串 , 如 何 設 定 <br />

Sol. var=${str:-new}<br />

27. 在 Bash shell 環 境 下 , 如 果 變 數 str 已 設 定 或 為 空 字 串 , 則 變 數<br />

var=new 字 串 ; 否 則 var= 空 字 串 , 如 何 設 定 <br />

Sol. var=${str+new}<br />

28. 在 Bash shell 環 境 下 , 如 果 變 數 str 已 設 定 為 非 空 字 串 , 則 變 數<br />

var=new 字 串 ; 否 則 var= 空 字 串 , 如 何 設 定 <br />

Sol. var=${str:+new}<br />

29. 在 Bash shell 環 境 下 , 執 行 unset str; var=${str-new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=<br />

30. 在 Bash shell 環 境 下 , 執 行 str=""; var=${str-new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=, str=<br />

31. 在 Bash shell 環 境 下 , 執 行 str="old"; var=${str-new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=old, str=old<br />

32. 在 Bash shell 環 境 下 , 執 行 unset str; var=${str:-new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=<br />

33. 在 Bash shell 環 境 下 , 執 行 str=""; var=${str:-new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=<br />

34. 在 Bash shell 環 境 下 , 執 行 str="old"; var=${str:-new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=old, str=old<br />

De-Yu Wang CSIE CYUT 34


2.6. 變 數 的 設 定 CHAPTER 2. SHELL 變 數<br />

35. 在 Bash shell 環 境 下 , 執 行 unset str; var=${str+new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=, str=<br />

36. 在 Bash shell 環 境 下 , 執 行 str=""; var=${str+new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=<br />

37. 在 Bash shell 環 境 下 , 執 行 str="old"; var=${str+new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=old<br />

38. 在 Bash shell 環 境 下 , 執 行 unset str; var=${str:+new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=, str=<br />

39. 在 Bash shell 環 境 下 , 執 行 str=""; var=${str:+new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=, str=<br />

40. 在 Bash shell 環 境 下 , 執 行 str="old"; var=${str:+new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=old<br />

41. 在 Bash shell 環 境 下 , 執 行 unset str; var=${str=new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=new<br />

42. 在 Bash shell 環 境 下 , 執 行 str=""; var=${str=new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=, str=<br />

43. 在 Bash shell 環 境 下 , 執 行 str="old"; var=${str=new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=old, str=old<br />

44. 在 Bash shell 環 境 下 , 執 行 unset str;<br />

var=${str:=new};echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=new<br />

45. 在 Bash shell 環 境 下 , 執 行 str=""; var=${str:=new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=new, str=new<br />

46. 在 Bash shell 環 境 下 , 執 行 str="old"; var=${str:=new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=old, str=old<br />

De-Yu Wang CSIE CYUT 35


2.6. 變 數 的 設 定 CHAPTER 2. SHELL 變 數<br />

47. 在 Bash shell 環 境 下 , 執 行 unset str; var=${strnew};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. -bash: str: new ( 錯 誤 訊 息 )<br />

48. 在 Bash shell 環 境 下 , 執 行 str=""; var=${strnew};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=, str=<br />

49. 在 Bash shell 環 境 下 , 執 行 str="old"; var=${strnew};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=old, str=old<br />

50. 在 Bash shell 環 境 下 , 執 行 unset str; var=${str:new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. -bash: str: new ( 錯 誤 訊 息 )<br />

51. 在 Bash shell 環 境 下 , 執 行 str=""; var=${str:new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. -bash: str: new ( 錯 誤 訊 息 )<br />

52. 在 Bash shell 環 境 下 , 執 行 str="old"; var=${str:new};<br />

echo var="$var", str="$str" 的 結 果 為 何 <br />

Sol. var=old, str=old<br />

De-Yu Wang CSIE CYUT 36


CHAPTER 3.<br />

資 料 導 向 與 管 線 處 理<br />

Chapter 3<br />

資 料 導 向 與 管 線 處 理<br />

3.1 資 料 流 重 導 向<br />

• 為 何 要 使 用 命 令 輸 出 重 導 向 <br />

1. 儲 存 螢 幕 輸 出 的 資 訊 ;<br />

2. 背 景 執 行 中 的 程 式 , 不 希 望 他 干 擾 螢 幕 正 常 的 輸 出 結 果 時 ;<br />

3. 儲 存 系 統 例 行 命 令 ( 例 如 寫 在 /etc/crontab 中 的 檔 案 ) 的 執 行 結 果 ;<br />

4. 將 已 知 的 可 能 錯 誤 訊 息 丟 掉 『 2> /dev/null 』;<br />

5. 錯 誤 訊 息 與 正 確 訊 息 需 要 分 別 輸 出 時 。<br />

• 指 令 執 行 過 程 之 資 料 傳 輸<br />

file standard input✲<br />

command standard output✲<br />

file/device<br />

standard error<br />

❄<br />

file/device<br />

1. 例 題 : 執 行 cat /etc/crontab /etc/dywang,standard input 與<br />

standard output 同 時 出 現 。<br />

✞<br />

圱 [dywang@dywHome ~]$ cat /etc/crontab /etc/dywang<br />

# /etc/crontab 存 在 , 螢 幕 出 現 以 下 standard output<br />

圳 SHELL=/bin/bash<br />

圵<br />

圷<br />

圹<br />

MAILTO=root<br />

HOME=/<br />

# run-parts<br />

01 * * * * root nice -n 19 run-parts --report /etc/cron.<br />

hourly<br />

De-Yu Wang CSIE CYUT 37


3.1. 資 料 流 重 導 向 CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

02 4 * * * root nice -n 19 run-parts --report /etc/cron.daily<br />

圱 圱 22 4 * * 0 root nice -n 19 run-parts --report /etc/cron.<br />

weekly<br />

42 4 1 * * root nice -n 19 run-parts --report /etc/cron.<br />

monthly<br />

圱 圳 # /etc/dywang 不 存 在 , 螢 幕 出 現 以 下 standard error<br />

cat: /etc/dywang: No such file or directory<br />

✡✝<br />

✆<br />

2. 傳 送 指 令<br />

(a) 標 準 輸 入 (stdin) : 代 碼 為 0 , 使 用 < 或 >;<br />

(c) 標 準 錯 誤 輸 出 (stderr): 代 碼 為 2 , 使 用 2> 或 2>>;<br />

>, 1> 標 準 輸 出 至 檔 案 , 該 檔 案 被 覆 蓋 或 建 立 。<br />

>>, 1>> 標 準 輸 出 至 檔 案 , 該 檔 案 被 建 立 或 累 加 。<br />

command 2> 裝 置 或 檔 案 錯 誤 輸 出 至 檔 案 , 該 檔 案 被 覆 蓋 或 建 立 。<br />

2>> 錯 誤 輸 出 至 檔 案 , 該 檔 案 被 建 立 或 累 加 。<br />

< 輸 入<br />

~/rootfile<br />

圲 # 將 ls -l / 要 列 出 到 螢 幕 上 的 資 料 『 重 新 導 向 』 到 ~/rootfile 檔<br />

✡✝<br />

案 。<br />

✆<br />

(a) 該 檔 案 ( 本 例 中 是 ~/rootfile ) 若 不 存 在 , 系 統 會 自 動 建 立 ;<br />

(b) 檔 案 存 在 時 , 系 統 會 先 將 檔 案 內 容 清 空 再 將 資 料 寫 入 ;<br />

(c) 以 > 輸 出 到 一 個 既 存 檔 案 中 , 該 檔 案 會 被 覆 蓋 。<br />

4. 下 達 > 與 >><br />

✞<br />

# 將 目 前 目 錄 下 的 檔 案 資 訊 儲 存 到 list.txt<br />

圲 [root@linux ~]# ls -al > list.txt<br />

圴<br />

# 將 根 目 錄 下 的 資 料 累 加 到 list.txt<br />

[root@linux ~]# ls -al / >> list.txt<br />

✡✝<br />

✆<br />

5. 下 達 2><br />

✞<br />

圱 [csie@linux ~]$ find /home -name testing<br />

find: /home/test1: Permission denied


3.1. 資 料 流 重 導 向 CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

圵 /home/csie/testing list_right 2><br />

list_error<br />

[csie@linux ~]$ find /home -name testing > list_right 2> /dev<br />

/null<br />

✡✝<br />

✆<br />

6. 下 達 2>&1: 標 準 輸 出 與 標 準 錯 誤 輸 出 同 時 寫 入 同 一 個 檔 案<br />

✞<br />

[csie@linux ~]$ find /home -name testing > list 2> list<br />

list 2>&1<br />

catfile<br />

testing<br />

圳 cat file test<br />

catfile OK now stop<br />

圹 > eof catfile < somefile<br />

✡✝<br />

✆<br />

• 命 令 執 行 的 判 斷 依 據<br />

1. 指 令 間 以 分 號 ( ; ) 隔 開 : 連 續 執 行 指 令 。<br />

✞<br />

圱 [root@linux ~]# sync; sync; shutdown -h now<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 39


3.1. 資 料 流 重 導 向 CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

2. 指 令 間 以 && 隔 開 : 前 面 指 令 執 行 結 果 正 確 , 就 接 著 執 行 後 續 的 指 令 ,<br />

否 則 就 略 過 。<br />

✞<br />

圱 [root@linux ~]# ls /tmp && touch /tmp/testingagin<br />

## 目 錄 / 存 在 , 所 以 tmp/tmp/ 會 被 建 立 。testingagin<br />

圳 [root@linux ~]# ls /csie && touch /csie/test<br />

## 目 錄 / 不 存 在 , 所 以 csietouch /csie/ 不 會 被 執 行 。test<br />

✡✝<br />

✆<br />

3. 指 令 間 以 || 隔 開 : 前 一 個 指 令 有 錯 誤 時 , 後 面 的 指 令 才 被 執 行 。<br />

✞<br />

[root@linux ~]# ls /tmp/csieing || touch /tmp/csieing<br />

✡✝<br />

✆<br />

4. 例 題 : 以 ls 測 試 /tmp/csie 是 否 存 在 若 存 在 則 顯 示 "exist" ,<br />

若 不 存 在 , 則 顯 示 "not exist"。<br />

✞<br />

圱 ls /tmp/csie && echo "exist" || echo "not exist" ~/list<br />

2. 要 將 ls -al / 的 標 準 輸 出 重 新 導 向 , 存 到 ( 建 立 或 累 加 ) ~/list, 如 何 下<br />

指 令 <br />

Sol. ls -al / >> ~/list 或 ls -al / 1>> ~/list<br />

3. 要 將 ls -al /csie 的 錯 誤 輸 出 重 新 導 向 , 存 到 ( 覆 蓋 或 建 立 ) ~/listerr,<br />

如 何 下 指 令 <br />

Sol. ls -al /csie 2> ~/listerr<br />

4. 要 將 ls -al / /csie 的 標 準 輸 出 及 錯 誤 輸 出 分 別 重 新 導 向 , 存 到 ( 覆 蓋 或<br />

建 立 ) ~/list 及 ~/listerr, 如 何 下 指 令 <br />

Sol. ls -al / /csie > ~/list 2> ~/listerr 或<br />

ls -al / /csie 1> ~/list 2> ~/listerr<br />

5. 要 將 ls -al / /csie 的 標 準 輸 出 及 錯 誤 輸 出 分 別 重 新 導 向 , 存 到 ( 建 立 或<br />

累 加 ) ~/list 及 ~/listerr, 如 何 下 指 令 <br />

Sol. ls -al / /csie >> ~/list 2>> ~/listerr 或<br />

ls -al / /csie 1>> ~/list 2>> ~/listerr<br />

De-Yu Wang CSIE CYUT 40


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

6. 要 將 ls -al / /csie 的 標 準 輸 出 及 錯 誤 輸 出 同 時 重 新 導 向 , 存 到 ( 覆 蓋 或<br />

建 立 ) ~/list, 如 何 下 指 令 <br />

Sol. ls -al / /csie > ~/list 2>&1<br />

7. 要 將 ls -al / /csie 的 標 準 輸 出 及 錯 誤 輸 出 同 時 重 新 導 向 , 存 到 ( 建 立 或<br />

累 加 ) ~/list, 如 何 下 指 令 <br />

Sol. ls -al / /csie >> ~/list 2>&1<br />

8. 請 說 明 指 令 ls /tmp && touch /tmp/testing 中 『&&』 之 意 義 <br />

Sol. 前 面 指 令 ls /tmp 執 行 結 果 正 確 , 就 接 著 執 行 後 續 的 指 令 touch<br />

/tmp/testing, 否 則 就 略 過<br />

9. 請 說 明 指 令 ls /tmp/testing || touch /tmp/testing 中 『||』 之 意 義 <br />

Sol. 前 面 指 令 ls /tmp/testing 執 行 有 錯 誤 時 , 才 執 行 後 續 的 指 令<br />

touch /tmp/testing<br />

10. 請 以 ls 測 試 /tmp/csie 是 否 存 在 若 存 在 則 顯 示 "exist" , 若 不 存<br />

在 , 則 顯 示 "not exist"。<br />

Sol. ls /tmp/csie && echo "exist" || echo "not exist"<br />

3.2 管 線 命 令 (pipe)<br />

• 管 線 命 令 的 處 理<br />

STDOUT STDIN STDOUT STDIN<br />

❄<br />

command1 command2 command3<br />

❄<br />

1. 例 題 : 使 用 ls 指 令 輸 出 後 的 內 容 , 被 less 讀 取 , 並 且 利 用 less<br />

的 功 能 前 後 翻 動 相 關 的 資 訊 。<br />

✞<br />

[root@linux ~]# ls -al /etc | less<br />

✡✝<br />

✆<br />

2. 習 題 : 使 用 ls 指 令 輸 出 /home/csie 內 容 後 , 其 被 more 讀 取 。<br />

• 擷 取 命 令 cut: 可 以 將 一 段 訊 息 的 某 一 段 『 切 』 出 來 , 處 理 的 訊 息 以 『 行 』<br />

為 單 位 。<br />

1. cut 指 令 :<br />

De-Yu Wang CSIE CYUT 41


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

✞<br />

圱 [root@linux ~]# cut -d 分 隔 字 元 ’’ -f fields<br />

[root@linux ~]# cut -c 字 元 區 間 選 項 :<br />

圳<br />

-d : 後 面 接 分 隔 字 元 。 與 -f 一 起 使 用 ;<br />

圵 -f : 依 據 -d 的 分 隔 字 元 將 一 段 訊 息 分 割 成 為 數 段 , 用 -f 取 出 第 幾<br />

段 ;<br />

-c : 以 字 元<br />

✡✝<br />

(characters) 的 單 位 取 出 固 定 字 元 區 間 ;<br />

✆<br />

2. 將 PATH 變 數 取 出 , 找 出 第 三 個 路 徑 。<br />

✞<br />

[root@linux ~]# echo $PATH<br />

圲 /bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin:/<br />

usr/games:<br />

[root@linux ~]# echo $PATH | cut -d ’:’ -f 5<br />

圴 # 以 : 作 為 分 隔 符 號 , 第 五 個 是 /usr/local/。bin<br />

# 若 要 列 出 第 3 與 第 5 個 <br />

圶 [root@linux ~]# echo $PATH | cut -d ’:’ -f 3,5<br />

## 習 題 : 取 出 PATH 變 數 之 第 2 與 第 4 個 路 徑 。<br />

✡✝<br />

✆<br />

3. 將 export 輸 出 的 訊 息 , 取 得 第 12 字 元 以 後 的 所 有 字 串<br />

✞<br />

圱 [root@linux ~]# export<br />

declare -x HISTSIZE="1000"<br />

圳 declare -x INPUTRC="/etc/inputrc"<br />

declare -x KDEDIR="/usr"<br />

圵 declare -x LANG="zh_TW.big5" 其 他 省 略<br />

............<br />

圷 [root@linux ~]# export | cut -c 12-<br />

HISTSIZE="1000"<br />

圹 INPUTRC="/etc/inputrc"<br />

KDEDIR="/usr"<br />

圱 圱 LANG="zh_TW.big5" 其 他 省 略<br />

............<br />

圱 圳 # 用 -c 可 以 處 理 比 較 具 有 格 式 的 輸 出 資 料 。<br />

# 還 可 以 指 定 某 個 範 圍 的 值 , 例 如 第 12-20 的 字 元<br />

為 cut -c 12-20 等 。<br />

圱 圵 ## 習 題 : 取 出 /etc/issue 之 第 1 至 13 個 字 元 。<br />

✡✝<br />

✆<br />

4. 用 last 將 本 月 登 入 者 的 資 訊 中 , 僅 留 下 使 用 者 大 名<br />

✞<br />

圱 [root@linux ~]# last<br />

csie tty1 192.168.1.28 Mon Aug 15 11:55 - 17:48 (05:53)<br />

圳 csie tty1 192.168.1.28 Mon Aug 15 10:17 - 11:54 (01:37)<br />

[root@linux ~]# last | cut -d ’ ’ -f 1<br />

圵 # 用 last 可 以 取 得 最 近 一 個 月 登 入 主 機 的 使 用 者 資 訊 ,<br />

De-Yu Wang CSIE CYUT 42


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

# 利 用 空 白 字 元 的 間 隔 , 取 出 第 一 個 資 訊 , 就 是 使 用 者 帳 號 。<br />

圷 # 但 因 csie tty1 之 間 空 格 並 非 僅 有 一 個 ,cut -d ’ ’ -f 的 輸 出 不<br />

是 1,2 。tty1<br />

✡✝<br />

✆<br />

• 擷 取 命 令 grep: 分 析 一 行 訊 息 , 若 當 中 有 需 要 的 資 訊 , 就 將 該 行 取 出 。<br />

1. grep 指 令 :<br />

✞<br />

圱 [root@linux ~]# grep [-acinv] 搜 尋 字 串 ’’ filename 選 項 :<br />

圳 -a : 將 binary 檔 案 以 text 檔 案 的 方 式 搜 尋 資 料<br />

-c : 計 算 找 到 搜 尋 字 串 ’’ 的 次 數<br />

圵 -i : 忽 略 大 小 寫 的 不 同<br />

-n : 輸 出 行 號<br />

圷 -v : 反 向 選 擇 , 亦 即 顯 示 出 沒 有 搜 尋 字 串 內 容 的 那 一 行 。’’<br />

✡✝<br />

✆<br />

2. 取 出 last 中 出 現 root 的 那 一 行<br />

✞<br />

圱 [root@linux ~]# last | grep ’root’<br />

## 習 題 : 請 找 出 /etc/issue 下 出 現 Mandrake 的 那 一 行 。<br />

✡✝<br />

✆<br />

3. 與 上 例 相 反 , 只 要 沒 有 root 的 就 取 出 。<br />

✞<br />

[root@linux ~]# last | grep -v ’root’<br />

圲 ## 習 題 : 請 找 出 /etc/issue 下 沒 出 現 Mandrake 的 那 一 行 。<br />

✡✝<br />

✆<br />

4. 在 last 的 輸 出 訊 息 中 , 只 要 有 root 就 取 出 , 並 且 僅 取 第 一 欄<br />

✞<br />

[root@linux ~]# last | grep ’root’ |cut -d ’ ’ -f1<br />

圲 ## 習 題 : 在 cat /etc/group 的 輸 出 訊 息 中 , 只 要 有 sshd 就 取 出 , 並<br />

且 僅 取 第 一 欄 及 第 三 欄 。<br />

✡✝<br />

✆<br />

• 排 序 命 令 sort: 可 依 據 不 同 的 資 料 型 態 來 排 序 。<br />

1. sort 指 令 :<br />

✞<br />

[root@linux ~]# sort [-fbMnrtuk] [file or stdin] 選 項 :<br />

圲<br />

-f : 忽 略 大 小 寫 的 差 異 , 例 如 A 與 a 視 為 編 碼 相 同 ;<br />

圴 -b : 忽 略 最 前 面 的 空 白 字 元 部 分 ;<br />

De-Yu Wang CSIE CYUT 43


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

-M : 以 月 份 的 名 字 來 排 序 , 例 如 JAN, DEC 等 排 序 方 法 ;<br />

圶 -n : 使 用 『 純 數 字 』 進 行 排 序 預 設 是 以 文 字 型 態 排 序 ();<br />

-r : 反 向 排 序 ;<br />

圸<br />

-u :, 相 同 的 資 料 中 僅 出 現 一 行 ; uniq<br />

-t : 分 隔 符 號 , 預 設 是 tab 鍵 ;<br />

圱 地 -k : 以 第 幾 個 區 間 (field) 進 行 排 序 ,<br />

✡✝<br />

✆<br />

2. 個 人 帳 號 都 記 錄 在 /etc/passwd 下 , 請 將 帳 號 進 行 排 序 。<br />

✞<br />

[root@linux ~]# cat /etc/passwd | sort<br />

圲 adm:x:3:4:adm:/var/adm:/sbin/nologin<br />

apache:x:48:48:Apache:/var/www:/sbin/nologin<br />

圴 bin:x:1:1:bin:/bin:/sbin/nologin<br />

daemon:x:2:2:daemon:/sbin:/sbin/nologin<br />

圶 # sort 預 設 『 以 第 一 個 』 資 料 排 序 , 且 以 『 文 字 』 型 態 排 序 。<br />

✡✝<br />

✆<br />

3. /etc/passwd 內 容 以 : 分 隔 , 如 何 以 第 三 欄 來 排 序 <br />

✞<br />

[root@linux ~]# cat /etc/passwd | sort -t ’:’ -k 3<br />

圲 root:x:0:0:root:/root:/bin/bash<br />

iiimd:x:100:101:IIIMF server:/usr/lib/iiim:/sbin/nologin<br />

圴 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin<br />

operator:x:11:0:operator:/root:/sbin/nologin<br />

圶 bin:x:1:1:bin:/bin:/sbin/nologin<br />

games:x:12:100:games:/usr/games:/sbin/nologin<br />

圸 # 使 用 數 字 排 序 :cat /etc/passwd | sort -t ’:’ -k 3 -。n<br />

# 參 數 -n 告 知 sort 以 數 字 排 序 。<br />

✡✝<br />

✆<br />

4. 利 用 last 將 輸 出 的 資 料 僅 取 帳 號 並 加 以 排 序<br />

✞<br />

圱 [root@linux ~]# last | cut -d ’ ’ -f1 | sort<br />

## 習 題 : 請 以 cat 顯 示 /etc/fstab 檔 案 內 容 , 切 下 其 第 二 欄 , 並 排<br />

序 。<br />

✡✝<br />

✆<br />

• uniq: 將 重 複 的 資 料 僅 列 出 一 個 顯 示<br />

1. uniq 指 令 :<br />

✞<br />

[root@linux ~]# uniq [-ic] 選 項 :<br />

圲<br />

-i : 忽 略 大 小 寫 字 元 的 不 同 ;<br />

圴 -c : 進 行 計 數<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 44


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

2. 使 用 last 將 帳 號 列 出 , 僅 取 出 帳 號 欄 , 進 行 排 序 後 僅 取 出 一 位 ;<br />

✞<br />

[root@linux ~]# last | cut -d ’ ’ -f1 | sort -u<br />

圲 [root@linux ~]# last | cut -d ’ ’ -f1 | sort | uniq<br />

✡✝<br />

✆<br />

3. 承 上 題 , 如 何 知 道 每 個 人 的 登 入 總 次 數 <br />

✞<br />

[root@linux ~]# last | cut -d ’ ’ -f1 | sort | uniq -c<br />

圲 ##(1) 先 將 所 有 的 資 料 列 出 ;(2) 再 將 人 名 獨 立 出 來 ;(3) 經 過 排<br />

序 ;(4) 只 顯 示 一 個 。<br />

✡✝<br />

✆<br />

• wc: 計 算 輸 出 的 訊 息 的 行 、 字 及 字 元 數 等<br />

1. wc 指 令 :<br />

✞<br />

[root@linux ~]# wc [-lwm] 選 項 :<br />

圲<br />

-l : 僅 列 出 行 ;<br />

圴 -w : 僅 列 出 多 少 字 英 文 單 字 ();<br />

-m : 多 少 字 元 ;<br />

✡✝<br />

✆<br />

2. 計 算 /etc/man.config 有 多 少 字 、 行 、 字 元 數 <br />

✞<br />

圱 [root@linux ~]# cat /etc/man.config | wc<br />

138 709 4506<br />

圳 # 輸 出 的 三 個 數 字 分 別 代 表 :『 行 、 字 數 、 字 元 數 』<br />

## 習 題 : 請 列 出 /etc/issue 有 多 少 字 、 行 、 字 元 數 <br />

✡✝<br />

✆<br />

3. 如 何 以 last 指 令 串 取 得 登 入 系 統 的 總 人 次 ( last 會 輸 出 空 白 行 與<br />

wtmp 字 樣 在 最 底 下 兩 行 , 其 並 非 帳 號 內 容 )<br />

✞<br />

[root@linux ~]# last | grep [a-zA-Z] | grep -v ’wtmp’ | wc -l<br />

圲 # 利 用 grep 取 出 非 空 白 行 以 及 去 除 wtmp 那 一 行 , 再 計 算 行 數 。<br />

## 習 題 : 請 取 得 以 a- 開 頭 登 入 系 統 的 總 人 次 。f<br />

✡✝<br />

✆<br />

• 雙 向 重 導 向 : tee 工 作 流 程<br />

De-Yu Wang CSIE CYUT 45


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

standard input ✲ tee ✲ screen<br />

❄<br />

file<br />

1. tee 指 令 :<br />

✞<br />

圱 [root@linux ~]# tee [-a] file 選 項 :<br />

圳 -a : 以 累 加 (append) 的 方 式 , 將 資 料 加 入 file 當 中 。<br />

✡✝<br />

✆<br />

2. 將 last 的 輸 出 存 一 份 到 last.list 檔 案 中<br />

✞<br />

圱 [root@linux ~]# last | tee last.list | cut -d " " -f1<br />

✡✝<br />

✆<br />

3. 將 ls 的 資 料 存 一 份 到 ~/homefile, 同 時 螢 幕 也 有 輸 出 訊 息 。<br />

✞<br />

圱 [root@linux ~]# ls -l /home | tee ~/homefile | more<br />

✡✝<br />

✆<br />

4. 將 ls 的 資 料 累 加 到 ~/homefile , 同 時 螢 幕 也 有 輸 出 訊 息 。<br />

✞<br />

圱 [root@linux ~]# ls -l / | tee -a ~/homefile | more<br />

✡✝<br />

✆<br />

• 字 元 轉 換 命 令 tr: 可 以 用 來 刪 除 一 段 訊 息 當 中 的 文 字 , 或 者 是 進 行 文 字 訊 息<br />

的 替 換 。<br />

1. tr 指 令 :<br />

✞<br />

圱 [root@linux ~]# tr [-ds] SET1 ... 選 項 :<br />

圳 -d : 刪 除 訊 息 當 中 的 SET1 這 個 字 串 ;<br />

-s : 取 代 重 複 的 字 元 。<br />

✡✝<br />

✆<br />

2. 將 last 輸 出 的 訊 息 中 , 所 有 的 小 寫 變 成 大 寫 字 元 :<br />

De-Yu Wang CSIE CYUT 46


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

✞<br />

[root@linux ~]# last | tr ’[a-z]’ ’[A-Z]’<br />

✡✝<br />

✆<br />

3. 將 /etc/passwd 輸 出 的 訊 息 中 , 將 冒 號 (:) 刪 除<br />

✞<br />

圱 [root@linux ~]# cat /etc/passwd | tr -d ’:’<br />

✡✝<br />

✆<br />

4. 將 檔 案 /home/csie/txtfile 中 的 重 複 字 元 p 取 代 成 單 一 個 q 字 元 :<br />

✞<br />

圱 [root@linux ~]# cat /home/csie/txtfile | tr -s ’p’ ’q’<br />

✡✝<br />

✆<br />

• 字 元 轉 換 命 令 col: 濾 除 標 準 輸 入 的 反 向 換 行 符 號 。<br />

1. col 指 令 :<br />

✞<br />

圱 [root@linux ~]# col [-bfpx] [-l num] 選 項<br />

:<br />

圳 -b 不 輸 出 任 何 的 退 格 (backspaces), 只 列 出 行 末 的 符 號<br />

-f 允 許 不 濾 除 () 正 向 半 換 行 符 ("fine" 模 式 ). 通 常 , 位 在 半 行 分 界 線<br />

的 字 元 會 列 印 到 下 一 行 。<br />

圵 -p 讓 無 法 判 別 的 控 制 字 元 通 過 並 列 印 到 輸 出 。<br />

-x 以 輸 出 連 續 空 格 取 替 換 跳 格 (tab)<br />

圷 -lnum 設 定 緩 衝 記 憶 體 , 以 " 行 " 為 單 位 。 預 設 值 為 128 行 。<br />

✡✝<br />

✆<br />

2. 轉 存 man 指 令 的 輸 出 資 料 。<br />

✞<br />

圱 [root@dywHome2 ~]# man ls |cat -v | sed -n ’5,10p’<br />

N^HNA^HAM^HME^HE<br />


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

3. [tab] 按 鍵 被 取 代 成 空 白 。<br />

[root@dywHome2 ~]# cat -A /etc/man.config | sed -n ’43,47p’<br />

MANPATH^I/usr/share/man$ %*


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

0:root:x:0:root:/root:/bin/bash:root:x:<br />

圳 1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:root,bin,daemon<br />

2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:root,bin,<br />

daemon<br />

圵 4:adm:x:3:adm:/var/adm:/sbin/nologin:adm:x:root,adm,daemon<br />

# /etc/passwd 的 第 一 行 內 容 是 root:x:0:0:root:/root:/bin/bash<br />

圷 # /etc/group 第 一 行 內 容 是 root:x:0:<br />

# 將 第 一 個 檔 案 的 第 四 欄 與 第 二 個 檔 案 的 第 三 欄 取 出 , 放 置 到 輸 出 的 最 前<br />

方 , 剩 下 的 資 料 加 在 一 起 。<br />

✡✝<br />

✆<br />

• paste: 可 將 兩 行 貼 在 一 起 , 且 中 間 以 [tab] 鍵 隔 開<br />

1. paste 指 令 :<br />

✞<br />

[root@linux ~]# paste [-d] file1 file2 選 項 :<br />

圲<br />

-d : 後 面 可 以 接 分 隔 字 元 。 預 設 是 以 [tab] 來 分 隔 的 。<br />

圴 - : 如 果 file 部 分 寫 成 - , 表 示 來 自 standard input 的 資 料 。<br />

✡✝<br />

✆<br />

2. 將 /etc/passwd 與 /etc/shadow 同 一 行 貼 在 一 起<br />

✞<br />

[root@linux ~]# paste /etc/passwd /etc/shadow<br />

圲 bin:x:1:1:bin:/bin:/sbin/nologin bin<br />

:*:12959:0:99999:7:::<br />

daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon<br />

:*:12959:0:99999:7:::<br />

圴 adm:x:3:4:adm:/var/adm:/sbin/nologin adm<br />

:*:12959:0:99999:7:::<br />

# 同 一 行 中 間 是 以 [tab] 按 鍵 隔 開 的 。<br />

✡✝<br />

✆<br />

3. 先 將 /etc/group 讀 出 ( 用 cat), 然 後 與 範 例 一 貼 上 一 起 , 且 僅 取 出 前<br />

三 行 。<br />

✞<br />

圱 [root@linux ~]# cat /etc/group|paste /etc/passwd /etc/shadow<br />

-|head -n 3<br />

# - 代 表 。 stdin<br />

✡✝<br />

✆<br />

• expand: 將 [tab] 按 鍵 轉 成 空 白 鍵<br />

1. expand 指 令 :<br />

✞<br />

[root@linux ~]# expand [-t] file 選 項 :<br />

De-Yu Wang CSIE CYUT 49


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

圲<br />

-t : 後 面 可 以 接 數 字 。 一 般 , 一 個 tab 按 鍵 可 以 用 8 個 空 白 鍵 取<br />

代 。 也 可 以 自 行 定 義 一 個<br />

圴 [tab] 按 鍵 代 表 多 少 個 字 元 。<br />

✡✝<br />

✆<br />

2. 將 /etc/man.config 內 行 首 為 MANPATH 的 字 樣 取 出 ; 僅 取 前 三 行 ;<br />

✞<br />

[root@linux ~]# grep ’^MANPATH’ /etc/man.config | head -n 3<br />

圲 MANPATH /usr/man<br />

MANPATH /usr/share/man<br />

圴 MANPATH /usr/local/man<br />

# 行 首 的 代 表 標 誌 為 ^ 。<br />

✡✝<br />

✆<br />

3. 承 上 題 , 將 所 有 的 符 號 都 列 出 來 ( 用 cat)<br />

✞<br />

圱 [root@linux ~]# grep ’^MANPATH’ /etc/man.config | head -n 3 |<br />

cat -A<br />

MANPATH^I/usr/man$<br />

圳 MANPATH^I/usr/share/man$<br />

MANPATH^I/usr/local/man$<br />

圵 # [tab] 按 鍵 可 以 被 cat -A 顯 示 成 為 ^I<br />

✡✝<br />

✆<br />

4. 承 上 題 , 將 [tab] 按 鍵 設 定 成 6 個 字 元 <br />

✞<br />

圱 [root@linux ~]# grep ’^MANPATH’ /etc/man.config | head -n 3 |<br />

\<br />

> expand -t 6 - | cat -A<br />

圳 MANPATH /usr/man$<br />

MANPATH /usr/share/man$<br />

圵 MANPATH /usr/local/man$<br />

123456123456123456.....<br />

圷 # 因 為 [tab] 的 長 度 為 6 個 字 元 , 所 以 ,MAN... 到 /usr 之 間<br />

隔 12 兩 個 ( [tab]) 個 字 元 。<br />

# 如 果 tab 改 成 9 個 字 元 <br />

✡✝<br />

✆<br />

• 分 割 命 令 :split 可 將 檔 案 分 割<br />

1. split 指 令 :<br />

✞<br />

[root@linux ~]# split [-bl] file PREFIX 選 項 :<br />

圲<br />

-b : 後 面 接 欲 分 割 成 的 檔 案 大 小 , 可 加 單 位 , 例 如 b, k, m 等 ;<br />

圴 -l : 以 行 數 來 進 行 分 割 。<br />

De-Yu Wang CSIE CYUT 50


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

✡✝<br />

✆<br />

2. /etc/termcap 有 七 百 多 K, 如 何 分 成 300K 一 個 檔 案 <br />

✞<br />

[root@linux ~]# cd /tmp; split -b 300k /etc/termcap termcap<br />

圲 [root@linux tmp]# ls -l termcap*<br />

-rw-rw-r-- 1 root root 307200 月 8 17 00:25 termcapaa<br />

圴 -rw-rw-r-- 1 root root 307200 月 8 17 00:25 termcapab<br />

-rw-rw-r-- 1 root root 184848 月 8 17 00:25 termcapac<br />

圶 # 只 要 寫 上 前 導 文 字 ,xxxsplit 就 會 以 xxxaa, xxxab, xxxac 建 立 小<br />

✡✝<br />

檔 案 。<br />

✆<br />

3. 將 上 面 的 三 個 小 檔 案 合 成 一 個 檔 案 , 檔 名 為 termcapback<br />

✞<br />

[root@linux tmp]# cat termcap* >> termcapback<br />

✡✝<br />

✆<br />

4. 使 用 ls -al / 輸 出 的 資 訊 中 , 每 十 行 記 錄 成 一 個 檔 案<br />

✞<br />

圱 [root@linux tmp]# ls -al / | split -l 10 - lsroot<br />

# - 會 被 當 成 stdin 或 stdout<br />

✡✝<br />

✆<br />

• 參 數 代 換 :xargs 可 以 讀 入 stdin 的 資 料 , 並 且 以 空 白 字 元 或 斷 行 字 元 作<br />

為 分 辨 , 將 stdin 的 資 料 分 隔 成 為 arguments。<br />

1. xargs 指 令 : 使 用 於 非 管 線 處 理 命 令 。<br />

圲<br />

✞<br />

[root@linux ~]# xargs [-0epn] command 選 項 :<br />

-0 : 如 果 輸 入 的 stdin 含 有 特 殊 字 元 , 例 如 ‘, \, 空 白 鍵 等 等 字 元<br />

時 , 這 個 -0 參 數 可 以 將 他 還 原 成 一 般 字 元 。<br />

圴<br />

-e : EOF (end of file) 。 當 xargs 分 析 到 其 後 接 的 字 串 時 , 會 停<br />

止 繼 續 工 作 。<br />

圶 -p : 在 執 行 每 個 指 令 的 argument 時 , 都 會 詢 問 使 用 者 ;<br />

-n : 後 面 接 次 數 , 每 次 command 指 令 執 行 時 , 要 使 用 幾 個 參 數 。 看 範<br />

例 三 。 當<br />

圸 xargs 後 面 沒 有 接 任 何 的 指 令 時 , 預 設 是 以 echo 來 進 行 輸 出 。<br />

✡✝<br />

✆<br />

2. 將 /etc/passwd 內 的 第 一 欄 取 出 , 僅 取 三 行 , 使 用 finger 指 令 將 每<br />

個 帳 號 內 容 秀 出 來<br />

De-Yu Wang CSIE CYUT 51


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

✞<br />

[root@linux ~]# cut -d’:’ -f1 < /etc/passwd |head -n 3| xargs<br />

finger<br />

圲 Login: root Name: root<br />

Directory: /root<br />

Shell: /bin/bash<br />

圴 Never logged in.<br />

圶<br />

No mail.<br />

No Plan. 底 下 省 略<br />

...........<br />

圸 # 利 用 cut 取 出 帳 號 名 稱 , 用 head 取 出 三 個 帳 號 。<br />

# 由 xargs 將 三 個 帳 號 的 名 稱 變 成 finger 後 面 需 要 的 參 數 。<br />

圱 地 # 上 例 為 finger root 後 的 結 果 。<br />

✡✝<br />

✆<br />

3. 同 上 題 , 每 次 執 行 finger 時 , 都 要 詢 問 使 用 者 是 否 動 作 <br />

✞<br />

[root@linux ~]# cut -d’:’ -f1 < /etc/passwd |head -n 3| xargs<br />

-p finger<br />

圲 finger root bin daemon ...y 底 下 省 略<br />

...........<br />

✡✝<br />

✆<br />

4. 將 所 有 的 /etc/passwd 內 的 帳 號 都 以 finger 查 閱 , 但 一 次 僅 查 閱 五<br />

個 帳 號<br />

✞<br />

圱 [root@linux ~]# cut -d’:’ -f1 < /etc/passwd | xargs -p -n 5<br />

finger<br />

finger root bin daemon adm lp ...y 底 下 省 略<br />

圳 ...........<br />

# 某 些 指 令 後 面 可 以 接 的 arguments 是 有 限 制 的 , 不 能 無 限 制 的 累 加 ,<br />

圵 # 此 時 可 以 利 用 -n 將 參 數 分 成 數 個 部 分 , 每 個 部 分 分 別 再 以 指 令 來 執<br />

行 。<br />

✡✝<br />

✆<br />

5. 同 上 題 , 但 當 分 析 到 lp 就 結 束 這 串 指 令 <br />

✞<br />

圱 [root@linux ~]# cut -d’:’ -f1 < /etc/passwd | xargs -p -e’lp’<br />

finger<br />

finger root bin daemon adm ...<br />

圳 # -e’lp’ 中 間 沒 有 空 白 鍵 。<br />

# 上 例 中 第 五 個 參 數 是 lp ,<br />

圵 # 分 析 到 字 串 lp 時 , 後 面 的 其 他 stdin 的 內 容 會 被 xargs 捨 棄 掉 。<br />

✡✝<br />

✆<br />

• 關 於 減 號 - 的 用 途 : 代 替 stdin 與 stdout<br />

✞<br />

圱 [root@linux ~]# tar -cvf - /home | tar -xvf -<br />

De-Yu Wang CSIE CYUT 52


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

# 將 /home 裡 面 的 檔 案 打 包 , 打 包 的 資 料 傳 送 到 ; stdout<br />

圳 # 利 用 管 線 處 理 , 將 tar -cvf - /home 傳 送 給 後 面 的 tar -xvf 。-<br />

# 後 面 的 - 則 是 取 用 前 一 個 指 令 的 。 stdout<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 如 何 使 用 管 線 命 令 , 以 ls 指 令 輸 出 /home/csie 內 容 後 , 其 被 more 讀<br />

取 <br />

Sol. ls /home/csie | more<br />

2. 如 何 使 用 管 線 命 令 , 以 echo $PATH 指 令 輸 出 PATH 路 徑 後 , 再 以 指 令 cut<br />

切 出 其 第 三 個 路 徑 <br />

Sol. echo $PATH | cut -d ’:’ -f 3<br />

3. 如 何 使 用 管 線 命 令 , 以 echo $PATH 指 令 輸 出 PATH 路 徑 後 , 再 以 指 令 cut<br />

切 出 其 第 二 及 五 個 路 徑 <br />

Sol. echo $PATH | cut -d ’:’ -f 2,5<br />

4. 如 何 使 用 管 線 命 令 , 將 export 指 令 輸 出 , 用 cut 切 出 每 行 的 第 12 字 元<br />

以 後 的 所 有 字 串 <br />

Sol. export | cut -c 12-<br />

5. 如 何 使 用 管 線 命 令 , 將 ls -al 指 令 輸 出 , 用 cut 切 出 每 行 的 第 10 至 22<br />

字 元 <br />

Sol. ls -al | cut -c 10-22<br />

6. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 用 grep 取 出 出 現 root 的 那 一<br />

行 <br />

Sol. last | grep ’root’ (root, "root" 亦 可 )<br />

7. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 用 grep 取 出 沒 有 出 現 root 的 那<br />

一 行 <br />

Sol. last | grep -v ’root’ (root, "root" 亦 可 )<br />

8. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 用 grep 取 出 出 現 root 的 那 一 行<br />

並 計 算 找 到 的 次 數 <br />

Sol. last | grep -c ’root’ (root, "root" 亦 可 )<br />

9. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 用 grep 取 出 出 現 root ( 忽 略 大<br />

小 寫 的 不 同 ) 的 那 一 行 <br />

Sol. last | grep -i ’root’ (root, "root" 亦 可 )<br />

10. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 用 grep 取 出 出 現 root 的 那 一 行<br />

並 輸 出 行 號 <br />

Sol. last | grep -n ’root’ (root, "root" 亦 可 )<br />

De-Yu Wang CSIE CYUT 53


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

11. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 用 grep 取 出 出 現 root 的 那 一 行<br />

並 且 用 cut 僅 取 第 一 欄 <br />

Sol. last | grep ’root’ | cut -d ’ ’ -f1 (root 不 加 引 號 及 加 雙 引<br />

號 亦 可 )<br />

12. 如 何 使 用 管 線 命 令 , 找 出 /etc/issue 下 出 現 Mandrake 的 那 一 行 <br />

Sol. cat /etc/issue | grep ’Mandrake’ (Mandrake 不 加 引 號 及 加 雙 引<br />

號 亦 可 )<br />

13. 如 何 使 用 管 線 命 令 , 找 出 /etc/issue 下 沒 有 出 現 Mandrake 的 那 一 行 <br />

Sol. cat /etc/issue | grep -v ’Mandrake’ (Mandrake 不 加 引 號 及 加<br />

雙 引 號 亦 可 )<br />

14. 如 何 使 用 管 線 命 令 , 在 cat /etc/group 的 輸 出 訊 息 中 , 只 要 有 sshd 就 取<br />

出 , 並 且 僅 取 第 一 欄 及 第 三 欄 <br />

Sol. cat /etc/group | grep ’sshd’ | cut -d ’:’ -f1,3 (sshd 不 加<br />

引 號 及 加 雙 引 號 亦 可 )<br />

15. 如 何 使 用 管 線 命 令 , 在 cat /etc/passwd 的 輸 出 訊 息 中 , 以 第 三 欄 進 行 帳<br />

號 排 序 <br />

Sol. cat /etc/passwd | sort -t ’:’ -k 3<br />

16. 如 何 使 用 管 線 命 令 , 在 cat /etc/passwd 的 輸 出 訊 息 中 , 以 第 三 欄 且 以 數<br />

字 進 行 帳 號 排 序 <br />

Sol. cat /etc/passwd | sort -t ’:’ -k 3 -n<br />

17. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 僅 取 帳 號 並 加 以 排 序 <br />

Sol. last | cut -d ’ ’ -f1 | sort<br />

18. 如 何 使 用 管 線 命 令 , 將 指 令 cat /etc/fstab 輸 出 , 切 下 其 第 二 欄 並 排 序 <br />

Sol. cat /etc/fstab | cut -d ’ ’ -f2 | sort<br />

19. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 僅 取 帳 號 並 加 以 排 序 , 且 相 同 的 帳<br />

號 僅 出 現 一 行 <br />

Sol. last | cut -d ’ ’ -f1 | sort -u 或 last | cut -d ’ ’ -f1 |<br />

sort | uniq<br />

20. 如 何 使 用 管 線 命 令 , 將 last 指 令 輸 出 , 僅 取 帳 號 並 加 以 排 序 , 且 相 同 的 帳<br />

號 僅 出 現 一 行 並 計 算 每 個 帳 號 的 登 入 總 次 數 <br />

Sol. last | cut -d ’ ’ -f1 | sort | uniq -c<br />

21. 如 何 使 用 管 線 命 令 , 計 算 /etc/man.config 有 多 少 字 、 行 、 字 元 數 <br />

Sol. cat /etc/man.config | wc<br />

22. 如 何 使 用 管 線 命 令 , 以 一 行 指 令 串 取 得 登 入 系 統 的 總 人 次 <br />

Sol. last | grep [a-zA-Z] | grep -v ’wtmp’ | wc -l<br />

De-Yu Wang CSIE CYUT 54


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

23. 如 何 使 用 雙 向 重 導 向 命 令 , 將 last 指 令 輸 出 存 一 份 到 last.list 檔 案<br />

中 , 而 螢 幕 上 僅 秀 出 帳 號 <br />

Sol. last | tee last.list | cut -d ’ ’ -f1<br />

24. 如 何 使 用 雙 向 重 導 向 命 令 , 將 ls /home 的 資 料 累 加 到 /homefile , 同 時<br />

螢 幕 也 以 more 輸 出 訊 息 <br />

Sol. ls /home | tee -a /homefile | more|<br />

25. 如 何 使 用 管 線 命 令 , 將 last 輸 出 的 訊 息 中 , 所 有 的 小 寫 變 成 大 寫 字 元 <br />

Sol. last | tr ’[a-z]’ ’[A-Z]’<br />

26. 如 何 使 用 管 線 命 令 , 將 cat /etc/passwd 輸 出 的 訊 息 中 , 所 有 的 冒 號 (:)<br />

刪 除 <br />

Sol. cat /etc/passwd | tr -d ’:’<br />

27. 如 何 使 用 管 線 命 令 , 將 cat /etc/passwd 輸 出 的 訊 息 中 , 所 有 的 重 複 字 元<br />

p 取 代 成 單 一 個 q 字 元 <br />

Sol. cat /home/csie/txtfile | tr -s ’p’ ’q’<br />

28. 線 上 說 明 文 件 man page 常 夾 雜 許 多 控 制 符 號 , 如 何 將 man ls 轉 存 為 一 般<br />

不 含 椌 制 符 號 的 文 字 檔 ls.txt<br />

Sol. man ls | col -b > ls.txt<br />

29. 如 何 將 設 定 檔 /etc/man.config 中 的 [tab] 改 成 空 白 , 且 轉 存 文 字 檔<br />

man.txt<br />

Sol. cat /etc/man.config | col -x > man.txt<br />

30. 如 何 用 root 的 身 份 , 將 /etc/group 與 /etc/gshadow 相 關 資 料 整 合 成 一<br />

欄 <br />

Sol. join -t ’:’ /etc/group /etc/gshadow<br />

31. 如 何 用 root 的 身 份 , 將 /etc/passwd 與 /etc/shadow 相 關 資 料 整 合 成 一<br />

欄 <br />

Sol. join -t ’:’ /etc/passwd /etc/shadow<br />

32. /etc/passwd 第 四 個 欄 位 是 GID, 其 記 錄 在 /etc/group 中 的 第 三 個 欄 位 ,<br />

如 何 用 root 的 身 份 , 將 兩 個 檔 案 整 合 <br />

Sol. join -t ’:’ -1 4 /etc/passwd -2 3 /etc/group<br />

33. 如 何 用 root 的 身 份 , 將 /etc/fstab 與 /etc/mtab 相 關 資 料 整 合 成 一<br />

欄 <br />

Sol. join /etc/fstab /etc/mtab<br />

34. 如 何 用 root 的 身 份 , 將 /etc/passwd 與 /etc/shadow 同 一 行 貼 在 一 起 ,<br />

且 中 間 是 以 [tab] 按 鍵 隔 開 <br />

Sol. paste /etc/passwd /etc/shadow<br />

De-Yu Wang CSIE CYUT 55


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

35. 如 何 用 root 的 身 份 , 將 /etc/passwd 與 /etc/shadow 同 一 行 貼 在 一 起 ,<br />

且 中 間 是 以 冒 號 : 隔 開 <br />

Sol. paste -d ":" /etc/passwd /etc/shadow<br />

36. 如 何 將 /etc/man.config 內 行 首 為 MANPATH 的 字 樣 取 出 , 且 僅 取 前 三 行 <br />

Sol. grep ’^MANPATH’ /etc/man.config | head -n 3<br />

37. 如 何 將 /etc/man.config 內 行 首 為 MANPATH 的 字 樣 取 出 , 且 僅 取 前 三 行 並<br />

用 cat 將 所 有 的 符 號 都 列 出 來 <br />

Sol. grep ’^MANPATH’ /etc/man.config | head -n 3 | cat -A<br />

38. 如 何 將 /etc/man.config 內 行 首 為 MANPATH 的 字 樣 取 出 , 且 僅 取 前 三 行 ,<br />

並 將 [tab] 按 鍵 設 定 成 9 個 字 元 , 最 後 用 cat 將 所 有 的 符 號 都 列 出 來 <br />

Sol. grep ’^MANPATH’ /etc/man.config | head -n 3 | expand -t 9 -<br />

| cat -A<br />

39. /etc/termcap 有 七 百 多 Mbytes, 如 何 分 成 300M 一 個 檔 案 <br />

Sol. split -b 300m /etc/termcap termcap<br />

40. /etc/termcap 有 七 百 多 Kbytes, 如 何 分 成 300K 一 個 檔 案 <br />

Sol. split -b 300k /etc/termcap termcap<br />

41. /etc/termcap 有 七 百 多 Kbytes, 如 何 分 成 300K 一 個 檔 案 , 會 產 生 那 幾 個<br />

檔 案 <br />

Sol. termcapaa, termcapab 及 termcapac<br />

42. 有 一 檔 案 以 split 分 成 多 個 小 檔 案 termcap, 如 何 將 其 合 成 一 個 檔 案 名<br />

為 termcap<br />

Sol. cat termcap >> termcap<br />

43. 如 何 將 ls -al / 輸 出 的 資 訊 , 每 十 行 記 錄 成 一 個 檔 案 lsroot<br />

Sol. ls -al / | split -l 10 - lsroot<br />

44. 如 何 將 /etc/passwd 內 的 第 一 欄 取 出 , 僅 取 三 行 , 使 用 指 令 finger 將 每<br />

個 帳 號 內 容 秀 出 來 <br />

Sol. cut -d ’:’ -f1 < /etc/passwd | head -n 3 | xargs finger<br />

45. 如 何 將 /etc/passwd 內 的 第 一 欄 取 出 , 僅 取 三 行 , 使 用 指 令 finger 將 每<br />

個 帳 號 內 容 秀 出 來 , 且 每 次 執 行 finger 時 , 都 要 詢 問 使 用 者 是 否 動 作 <br />

Sol. cut -d ’:’ -f1 < /etc/passwd | head -n 3 | xargs -p finger<br />

46. 如 何 將 所 有 的 /etc/passwd 內 的 第 一 欄 取 出 , 使 用 指 令 finger 查 閱 帳 號<br />

內 容 , 但 一 次 僅 查 閱 五 個 帳 號 , 且 每 次 執 行 finger 時 , 都 要 詢 問 使 用 者 是<br />

否 動 作 <br />

Sol. cut -d ’:’ -f1 < /etc/passwd | xargs -p -n 5 finger<br />

De-Yu Wang CSIE CYUT 56


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

47. 如 何 將 所 有 的 /etc/passwd 內 的 第 一 欄 取 出 , 使 用 指 令 finger 查 閱 帳 號<br />

內 容 , 但 當 分 析 到 lp 就 結 束 這 串 指 令 <br />

Sol. cut -d ’:’ -f1 < /etc/passwd | xargs -p -e’lp’ finger<br />

48. 如 何 將 /home 裡 面 的 檔 案 打 包 , 打 包 的 資 料 傳 送 到 stdout, 將 /home 裡<br />

面 的 檔 案 打 包 , 打 包 的 資 料 傳 送 到 stdout; 再 利 用 管 線 處 理 , 將 stdout<br />

做 為 後 續 tar -xvf 的 stdin 解 壓 縮 <br />

Sol. tar -cvf - /home | tar -xvf -<br />

De-Yu Wang CSIE CYUT 57


3.2. 管 線 命 令 (PIPE) CHAPTER 3. 資 料 導 向 與 管 線 處 理<br />

De-Yu Wang CSIE CYUT 58


CHAPTER 4.<br />

正 規 表 示 法<br />

Chapter 4<br />

正 規 表 示 法<br />

4.1 前 言<br />

• 什 麼 是 正 規 表 示 法<br />

1. 處 理 字 串 的 方 法 , 以 行 為 單 位 進 行 字 串 的 處 理 行 為 。<br />

2. 透 過 一 些 特 殊 符 號 的 輔 助 , 讓 使 用 者 輕 易 的 達 到 搜 尋 、 取 代 , 限 定 某 特<br />

定 字 串 的 處 理 程 序 。<br />

3. 延 伸 的 正 規 表 示 法 : 可 以 作 群 組 的 字 串 『 或 (or)』 及 『 且 (and)』 的 處<br />

理 。<br />

4. 正 規 表 示 法 與 萬 用 字 元 不 一 樣 , 不 可 混 淆 。<br />

• 正 規 表 示 法 用 途<br />

1. 系 統 管 理 員 的 可 以 透 過 『 正 規 表 示 法 』 的 功 能 , 將 登 錄 的 資 訊 進 行 處<br />

理 , 僅 取 出 『 有 問 題 』 的 資 訊 來 進 行 分 析 。<br />

2. 一 般 支 援 正 規 表 示 法 的 軟 體 可 利 用 其 進 行 字 串 的 處 理 , 例 如 :『 郵 件 伺<br />

服 器 』 以 『 字 串 』 的 比 對 來 過 濾 郵 件 。<br />

3. 軟 體 中 輸 入 欄 位 的 格 式 限 制 , 例 如 : 只 能 為 數 字 。<br />

• vi, grep, awk ,sed 等 工 具 皆 支 援 正 規 表 示 法 。<br />

練 習 題<br />

1. 何 謂 正 規 表 示 法 <br />

Sol. 處 理 字 串 的 方 法<br />

2. 正 規 表 示 法 以 什 麼 為 單 位 進 行 字 串 處 理 <br />

Sol. 以 行 為 單 位<br />

3. 正 規 表 示 法 與 萬 用 字 元 是 否 一 樣 <br />

Sol. 不 一 樣<br />

De-Yu Wang CSIE CYUT 59


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

4.2 基 礎 正 規 表 示 法<br />

字 符<br />

• 重 要 特 殊 字 元 (characters)<br />

圲<br />

圴<br />

✞<br />

RE 意 義 與 範 例<br />

^word 待 搜 尋 的 字 串 (word) 在 行 首 。<br />

# 範 例 :grep -n ’^#’ re.txt 搜 尋 行 首 為<br />

# 開 始 的 那 一 行 。<br />

圶 word$ 待 搜 尋 的 字 串 (word) 在 行 尾 。<br />

# 範 例 :grep -n ’!$’ re.txt 將 行 尾 為<br />

圸 ! 的 那 一 行 列 印 出 來 。<br />

. 代 表 『 任 意 一 個 』 字 符 , 一 定 是 一 個 任 意 字 符 。<br />

圱 地<br />

# 範 例 :grep -n ’e.e’ re.txt 搜 尋 的 字 串 可 以 是<br />

(eve) (eae) (eee) (e e), 但 不 能 僅 有 (ee)。 亦 即<br />

圱 圲 e 與 e 中 間 『 一 定 』 僅 有 一 個 字 元 , 而 空 白 字 元 也 是 字 元 。<br />

圱 圴<br />

\ 跳 脫 字 符 , 將 特 殊 符 號 的 特 殊 意 義 去 除 。<br />

# 範 例 :grep -n \’ re.txt 搜 尋 含 有 單 引 號<br />

’ 的 那 一 行 。<br />

圱 圶 * 重 複 零 個 或 多 個 的 前 一 個 RE 字 符<br />

# 範 例 :grep -n ’ess*’ re.txt 找 出 含 有<br />

圱 圸 (es) (ess) (esss) 等 等 的 字 串 。<br />

\{n,m\} 連 續 n 到 m 個 的 『 前 一 個 RE 字 符 』 若 為<br />

圲 地<br />

\{n\} 則 是 連 續 n 個 的 前 一 個 RE 字 符 , 若 是<br />

\{n,\} 則 是 連 續 n 個 以 上 的 前 一 個 RE 字 符 。<br />

圲 圲<br />

# 範 例 :grep -n ’go\{2,3\}g’ re.txt 在<br />

g 與 g 之 間 有 2 個 到 3 個 的 o 存 在 的 字 串 , 亦<br />

即 (goog)(gooog)<br />

圲 圴 [ ] 在 [ ] 當 中 『 謹 代 表 一 個 待 搜 尋 的 字 元 』<br />

圲 圶<br />

# 範 例 :grep -n ’g[ld]’ re.txt 搜 尋 含 有<br />

(gl) 或 (gd) 的 那 一 行<br />

# 範 例 :grep -n ’[0-9]’ re.txt 搜 尋 含 有 任 意 數 字 的 那 一 行 。 在<br />

字 元 集 合<br />

圲 圸<br />

[ ] 中 的 減 號 - 是 代 表 兩 個 字 元 之 間 的 所 有 連 續 字 元 。:<br />

圳 地 [^]^ 在 [ ] 內 時 , 代 表 的 意 義 是 『 反 向 選 擇 』<br />

# 範 例 :grep -n ’oo[^t]’ re.txt 搜 尋 的 字 串 可 以 是<br />

圳 圲<br />

✡✝<br />

(oog) (ood) 但 不 能 是 (oot)。<br />

✆<br />

• 以 grep 擷 取 字 串<br />

1. 編 輯 re.txt 純 文 字 檔<br />

✞<br />

圱 [root@test root]# vi re.txt<br />

"Open Source" is a good mechanism to develop programs.<br />

圳 apple is my favorite food.<br />

Football game is not use feet only.<br />

圵 this dress doesn’t fit me.<br />

De-Yu Wang CSIE CYUT 60


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

However, this dress is about $ 3183 dollars.<br />

圷 GNU is free air not free beer.<br />

Her hair is very beauty.<br />

圹 I ’cant finish the test.<br />

Oh! The soup taste good.<br />

圱 圱 motorcycle is cheap than car.<br />

This window is clear.<br />

圱 圳 the symbol ’*’ is represented as start.<br />

Oh! My god!<br />

圱 圵 The gd software is a library for drafting programs.<br />

You are the best is mean you are the no. 1.<br />

圱 圷 The world is the same with "glad".<br />

I like dog.<br />

圱 圹 google is the best tools for search keyword.<br />

goooooogle yes!<br />

圲 圱 go! go! Let’s go.<br />

# I am csie<br />

✡✝<br />

✆<br />

2. 搜 尋 特 定 字 串 : 從 檔 案 re.txt 中 取 得 特 定 字 串 the<br />

✞<br />

[root@test root]# grep -n ’the’ re.txt<br />

圲 8:I can’t finish the test.<br />

12:the symbol ’*’ is represented as start.<br />

圴 15:You are the best is mean you are the no. 1.<br />

16:The world is the same with "glad".<br />

圶 18:google is the best tools for search keyword.<br />

✡✝<br />

✆<br />

3. 該 行 沒 有 字 串 the 時 , 才 顯 示 在 螢 幕 上 :<br />

✞<br />

[root@test root]# grep -vn ’the’ re.txt<br />

圲 # 螢 幕 上 出 現 的 行 列 為 除 了 8,12,15,16,18 五 行 之 外 的 其 他 行 列 。<br />

✡✝<br />

✆<br />

4. 取 得 不 論 大 小 寫 的 字 串 the:<br />

✞<br />

[root@test root]# grep -in ’the’ re.txt<br />

圲 8:I can’t finish the test.<br />

9:Oh! The soup taste good.<br />

圴 12:the symbol ’*’ is represented as start.<br />

14:The gd software is a library for drafting programs.<br />

圶 15:You are the best is mean you are the no. 1.<br />

16:The world is the same with "glad".<br />

圸 18:google is the best tools for search keyword.<br />

✡✝<br />

✆<br />

5. 利 用 [ ] 來 搜 尋 集 合 字 元<br />

De-Yu Wang CSIE CYUT 61


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

✞<br />

[root@test root]# grep -n ’t[ae]st’ re.txt<br />

圲 8:I can’t finish the test.<br />

9:Oh! The soup taste good.<br />

圴 # [ ] 裡 面 不 論 有 幾 個 字 元 , 都 謹 代 表 某 『 一 個 』 字 元 。<br />

✡✝<br />

✆<br />

6. 搜 尋 有 oo 的 字 元 :<br />

✞<br />

[root@test root]# grep -n ’oo’ re.txt<br />

圲 1:"Open Source" is a good mechanism to develop programs.<br />

2:apple is my favorite food.<br />

圴 3:Football game is not use feet only.<br />

9:Oh! The soup taste good.<br />

圶 18:google is the best tools for search keyword.<br />

19:goooooogle yes!<br />

✡✝<br />

✆<br />

7. 不 想 要 oo 前 面 有 g , 可 以 利 用 在 集 合 字 元 的 反 向 選 擇 [^]<br />

✞<br />

圱 [root@test root]# grep -n ’[^g]oo’ re.txt<br />

2:apple is my favorite food.<br />

圳 3:Football game is not use feet only.<br />

18:google is the best tools for search keyword.<br />

圵 19:goooooogle yes!<br />

✡✝<br />

✆<br />

8. oo 前 面 不 想 要 有 小 寫 字 元 :<br />

✞<br />

圱 [root@test root]# grep -n ’[^a-z]oo’ re.txt<br />

3:Football game is not use feet only.<br />

✡✝<br />

✆<br />

9. 要 求 字 串 是 數 字 與 英 文 :[a-zA-Z0-9]<br />

✞<br />

[root@test root]# grep -n ’[0-9]’ re.txt<br />

圲 5:However, this dress is about $ 3183 dollars.<br />

15:You are the best is mean you are the no. 1.<br />

✡✝<br />

✆<br />

10. 行 首 與 行 尾 字 元 ^ $:<br />

✞<br />

圱 [root@test root]# grep -n ’^the’ re.txt<br />

12:the symbol ’*’ is represented as start.<br />

圳<br />

[root@test root]# grep -n ’^[a-z]’ re.txt<br />

De-Yu Wang CSIE CYUT 62


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

圵 2:apple is my favorite food.<br />

4:this dress doesn’t fit me.<br />

圷 10:motorcycle is cheap than car.<br />

12:the symbol ’*’ is represented as start.<br />

圹 18:google is the best tools for search keyword.<br />

19:goooooogle yes!<br />

✡✝<br />

✆<br />

11. 不 要 開 頭 是 英 文 字 母 :<br />

✞<br />

[root@test root]# grep -n ’^[^a-zA-Z]’ re.txt<br />

圲 1:"Open Source" is a good mechanism to develop programs.<br />

20:# I am csie<br />

✡✝<br />

✆<br />

12. 行 尾 結 束 為 小 數 點 (.) 的 那 一 行 :<br />

✞<br />

圱 [root@test root]# grep -n ’\.$’ re.txt<br />

1:"Open Source" is a good mechanism to develop programs.<br />

圳 2:apple is my favorite food.<br />

3:Football game is not use feet only.<br />

圵 4:this dress doesn’t fit me.<br />

10:motorcycle is cheap than car.<br />

圷 11:This window is clear.<br />

12:the symbol ’*’ is represented as start.<br />

圹 15:You are the best is mean you are the no. 1.<br />

16:The world is the same with "glad".<br />

圱 圱 17:I like dog.<br />

18:google is the best tools for search keyword.<br />

圱 圳 # 小 數 點 具 有 其 他 意 義 , 必 須 要 使 用 跳 脫 字 元 (\) 來 加 以 解 除 其 特 殊 意<br />

義 。<br />

# 第 5~9 行 最 後 面 也 是 .<br />

✡✝<br />

✆<br />

13. Windows 的 notepad 會 主 動 加 上 ^M 作 為 斷 行 的 判 斷 。<br />

✞<br />

[root@test root]# cat -A re.txt<br />

圲 However, this dress is about $ 3183 dollars.^M$<br />

✡✝<br />

✆<br />

14. 找 出 哪 一 行 是 『 空 白 行 』<br />

✞<br />

[root@test root]# grep -n ’^$’ re.txt<br />

圲 21:<br />

圴<br />

[root@test root]# cat /etc/syslog.conf<br />

[root@test root]# grep -v ’^$’ /etc/syslog.conf | grep -v<br />

’^#’<br />

De-Yu Wang CSIE CYUT 63


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

✡✝<br />

✆<br />

15. 任 意 一 個 字 元 . 與 重 複 字 元 *<br />

✞<br />

圱 #『』 代 表 『 絕 對 有 一 個 任 意 字 元 』.<br />

[root@test root]# grep -n ’g..d’ re.txt<br />

圳 1:"Open Source" is a good mechanism to develop programs.<br />

9:Oh! The soup taste good.<br />

圵 16:The world is the same with "glad".<br />

# 『』 代 表 的 是 『 重 複 * 0 個 或 多 個 前 面 的 RE 字 符 』<br />

圷 [root@test root]# grep -n ’ooo*’ re.txt<br />

1:"Open Source" is a good mechanism to develop programs.<br />

圹 2:apple is my favorite food.<br />

3:Football game is not use feet only.<br />

圱 圱 9:Oh! The soup taste good.<br />

18:google is the best tools for search keyword.<br />

圱 圳 19:goooooogle yes!<br />

✡✝<br />

✆<br />

16. 字 串 開 頭 與 結 尾 都 是 g, 但 是 兩 個 g 之 間 僅 能 存 在 至 少 一 個 o<br />

✞<br />

圱 # 亦 即 gog, goog, gooog.... 等 。<br />

[root@test root]# grep -n ’goo*g’ re.txt<br />

圳 18:google is the best tools for search keyword.<br />

19:goooooogle yes!<br />

✡✝<br />

✆<br />

17. 找 出 g 開 頭 與 g 結 尾 的 字 串 , 當 中 的 字 元 可 有 可 無 。( 錯 誤 找 法 )<br />

✞<br />

[root@test root]# grep -n ’g*g’ re.txt<br />

圲 1:"Open Source" is a good mechanism to develop programs.<br />

3:Football game is not use feet only.<br />

圴 9:Oh! The soup taste good.<br />

13:Oh! My god!<br />

圶 14:The gd software is a library for drafting programs.<br />

16:The world is the same with "glad".<br />

圸 17:I like dog.<br />

18:google is the best tools for search keyword.<br />

圱 地 19:goooooogle yes!<br />

# g*g 的 內 容 是 g, gg, ggg, 。gggg<br />

✡✝<br />

✆<br />

18. 找 出 g 開 頭 與 g 結 尾 的 字 串 , 當 中 的 字 元 可 有 可 無 。<br />

✞<br />

圱 [root@test root]# grep -n ’g.*g’ re.txt<br />

1:"Open Source" is a good mechanism to develop programs.<br />

De-Yu Wang CSIE CYUT 64


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

圳 14:The gd software is a library for drafting programs.<br />

18:google is the best tools for search keyword.<br />

圵 19:goooooogle yes!<br />

✡✝<br />

✆<br />

19. 要 找 出 『 任 意 數 字 』 的 行 列 :<br />

✞<br />

圱 [root@test root]# grep -n ’[0-9][0-9]*’ re.txt<br />

5:However, this dress is about $ 3183 dollars.<br />

圳 15:You are the best is mean you are the no. 1.<br />

# 使 用 grep -n ’[0-9]’ re.txt 也 可 以 得 到 相 同 的 結 果 。<br />

✡✝<br />

✆<br />

20. 限 定 連 續 RE 字 符 範 圍 {}: 找 到 兩 個 o 的 字 串 。<br />

✞<br />

[root@test root]# grep -n ’o\{2\}’ re.txt<br />

圲 1:"Open Source" is a good mechanism to develop programs.<br />

2:apple is my favorite food.<br />

圴 3:Football game is not use feet only.<br />

9:Oh! The soup taste good.<br />

圶 18:google is the best tools for search keyword.<br />

19:goooooogle yes!<br />

✡✝<br />

✆<br />

21. 找 出 g 後 面 接 2 到 5 個 o , 然 後 再 接 一 個 g 的 字 串 :<br />

✞<br />

圱 [root@test root]# grep -n ’go\{2,5\}g’ re.txt<br />

18:google is the best tools for search keyword.<br />

✡✝<br />

✆<br />

22. 找 出 2 個 o 以 上 的 goooo....g 除 了 可 以 是 gooo*g , 也 可 以 是 :<br />

✞<br />

[root@test root]# grep -n ’go\{2,\}g’ re.txt<br />

圲 18:google is the best tools for search keyword.<br />

19:goooooogle yes!<br />

✡✝<br />

✆<br />

23. 找 出 2 個 o 以 上 的 goooo....g, 當 找 到 一 筆 即 停 止 。<br />

✞<br />

圱 [root@test root]# grep -m 1 ’go\{2,\}g’ re.txt<br />

18:google is the best tools for search keyword.<br />

圳 19:goooooogle yes!<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 65


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

圱<br />

• 『 正 規 表 示 法 的 特 殊 字 元 』 與 『 萬 用 字 元 』 之 差 異 :<br />

字 元 或 代 表 意 義 萬 用 字 元 正 規 表 示 法 的 特 殊 字 元<br />

* 0 至 無 限 多 個 字 元 重 複 0 到 多 個 的 前 一 個 RE 字 符<br />

反 向 選 擇 [!range] [^range]<br />

✞<br />

例 題 : 不 支 援 正 規 表 示 法 的<br />

ls 工 具 中 『<br />

圳 ls -l * 』: 代 表 列 出 任 意 檔 名 的 檔 案 ;『<br />

ls -l a* 』: 代 表 列 出 以 a 為 開 頭 的 任 何 檔 名 的 檔 案 。 在 正 規 表 示 法 中 要 找<br />

到 含 有 以<br />

圵 a 為 開 頭 的 檔 案 , 必 須 搭 配 支 援 正 規 表 示 法 的 工 具 : grep<br />

ls | grep -n ’^a.*’<br />

✡✝<br />

✆<br />

• 例 題 : 以 正 規 表 示 法 顯 示 行 號 方 式 找 出 目 錄 /etc 以 下 符 合 下 列 條 件 之 檔<br />

案 。<br />

1. 包 含 boot 或 root 字 串 的 檔 案 。<br />

2. 包 含 b 開 頭 t 結 尾 之 字 串 的 檔 案 。<br />

3. b 開 頭 t 結 尾 且 中 間 1 個 o 以 上 之 字 串 的 檔 案 。<br />

4. 包 含 b 開 頭 t 結 尾 且 中 間 2 至 4 個 o 之 字 串 的 檔 案 。<br />

5. 包 含 行 首 為 root 之 字 串 的 檔 案 。<br />

6. 包 含 行 尾 為 root 之 字 串 的 檔 案 。<br />

• 例 題 : 想 要 查 出 來 檔 案 中 含 有 ! 與 > 的 字 行 ( ! 在 正 規 表 示 法 中 並 不 是<br />

特 殊 字 元 ):<br />

✞<br />

圱 grep -n ’[!>]’ re.txt<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 行 首 為 # 的 行 , 並<br />

列 出 行 號 <br />

Sol. grep -n ’^#’ re.txt<br />

2. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 行 尾 為 ! 的 行 , 並<br />

列 出 行 號 <br />

Sol. grep -n ’!$’ re.txt<br />

3. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , e 與 e 中 間 『 一<br />

定 』 僅 有 一 個 字 元 ( 含 空 白 字 元 ) 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’e.e’ re.txt<br />

De-Yu Wang CSIE CYUT 66


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

4. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 單 引 號 ’ 的<br />

行 , 並 列 出 行 號 <br />

Sol. grep -n \’ re.txt<br />

5. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 es, ess,<br />

esss,... 等 字 串 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’ess*’ re.txt<br />

6. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 在 g 與 g 之 間 有 2<br />

個 到 3 個 o 字 串 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’go\{2,3\}g’ re.txt<br />

7. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 gl 或 gd 的<br />

行 , 並 列 出 行 號 <br />

Sol. grep -n ’g[ld]’ re.txt<br />

8. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 任 意 數 字 的 行 ,<br />

並 列 出 行 號 <br />

Sol. grep -n ’[0-9]’ re.txt<br />

9. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 oo 字 串 , 但 不<br />

能 是 oot 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’oo[^t]’ re.txt<br />

10. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 the 字 串 的<br />

行 , 並 列 出 行 號 <br />

Sol. grep -n ’the’ re.txt<br />

11. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 沒 含 有 the 字 串 的<br />

行 , 並 列 出 行 號 <br />

Sol. grep -vn ’the’ re.txt<br />

12. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 不 論 大 小 寫 the<br />

字 串 的 行 , 並 列 出 行 號 <br />

Sol. grep -in ’the’ re.txt<br />

13. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 tast 或 test<br />

字 串 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’t[ae]st’ re.txt<br />

14. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 oo 字 串 , 但 其<br />

前 面 不 是 g 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’[^g]oo’ re.txt<br />

15. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 oo 字 串 , 但 其<br />

前 面 不 是 小 寫 字 元 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’[^a-z]oo’ re.txt<br />

De-Yu Wang CSIE CYUT 67


4.2. 基 礎 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

16. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 數 字 或 英 文 字<br />

串 , 但 其 前 面 不 是 小 寫 字 元 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’[^a-z][a-zA-Z0-9]’ re.txt<br />

17. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 行 首 為 the 的 行 ,<br />

並 列 出 行 號 <br />

Sol. grep -n ’^the’ re.txt<br />

18. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 行 首 開 頭 為 英 文 字 母<br />

的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’^[a-zA-Z]’ re.txt<br />

19. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 行 首 開 頭 不 要 是 英 文<br />

字 母 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’^[^a-zA-Z]’ re.txt<br />

20. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 行 尾 結 束 為 小 數 點 .<br />

的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’\.$’ re.txt<br />

21. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 空 白 行 , 並 列 出 行 號 <br />

Sol. grep -n ’^$’ re.txt<br />

22. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 以 g 開 頭 d 結<br />

尾 , 且 中 間 剛 好 兩 個 字 元 之 字 串 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’g..d’ re.txt<br />

23. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 以 g 開 頭 d 結<br />

尾 之 字 串 , 但 g 與 d 之 間 僅 能 存 在 至 少 一 個 o 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’goo*d’ re.txt<br />

24. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 『 任 意 數 字 』 的<br />

行 , 並 列 出 行 號 <br />

Sol. grep -n ’[0-9][0-9]*’ re.txt<br />

25. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 2 個 o 字 串 的<br />

行 , 並 列 出 行 號 <br />

Sol. grep -n ’o\{2\}’ re.txt<br />

26. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 g 後 面 接 2 到<br />

5 個 o, 然 後 再 接 一 個 g 之 字 串 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’go\{2,5\}g’ re.txt<br />

27. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 g 後 面 接 2 個<br />

以 上 o, 然 後 再 接 一 個 g 之 字 串 的 行 , 並 列 出 行 號 <br />

Sol. grep -n ’go\{2,\}g’ re.txt<br />

De-Yu Wang CSIE CYUT 68


4.3. 延 伸 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

28. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 g 後 面 接 2 個<br />

以 上 o, 然 後 再 接 一 個 g 之 字 串 的 行 , 且 找 到 第 二 筆 即 停 止 搜 尋 <br />

Sol. grep -m 2 ’go\{2,\}g’ re.txt<br />

29. * 在 『 萬 用 字 元 』 與 『 正 規 表 示 法 』 中 有 何 差 異 <br />

Sol. 在 萬 用 字 元 中 為 0 至 無 限 多 個 字 元 , 而 在 正 規 表 示 法 中 為 重 複 0 到<br />

多 個 的 前 一 個 RE 字 符<br />

30. 在 『 萬 用 字 元 』 與 『 正 規 表 示 法 』 中 反 向 選 擇 之 用 法 有 何 差 異 <br />

Sol. 在 萬 用 字 元 中 為 [!range], 而 在 正 規 表 示 法 中 為 [^range]<br />

31. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 boot 或 root 字<br />

串 的 檔 案 , 並 列 出 行 號 <br />

Sol. grep -n ’[br]oot’ /etc/*<br />

32. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 b 開 頭 t 結 尾 之<br />

字 串 的 檔 案 , 並 列 出 行 號 <br />

Sol. grep -n ’b.*t’ /etc/*<br />

33. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 b 開 頭 t 結 尾 且<br />

中 間 1 個 o 以 上 之 字 串 的 檔 案 , 並 列 出 行 號 <br />

Sol. grep -n ’bo\{1,\}t’ /etc/* 或 grep -n ’boo*t’ /etc/*<br />

34. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 b 開 頭 t 結 尾 且<br />

中 間 2 至 4 個 o 之 字 串 的 檔 案 , 並 列 出 行 號 <br />

Sol. grep -n ’bo\{2,4\}t’ /etc/*<br />

35. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 行 首 為 root 之 字<br />

串 的 檔 案 , 並 列 出 行 號 <br />

Sol. grep -n ’^boot’ /etc/*<br />

36. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 行 尾 為 root 之 字<br />

串 的 檔 案 , 並 列 出 行 號 <br />

Sol. grep -n ’boot$’ /etc/*<br />

37. 如 何 以 grep 配 合 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 ! 與 > 的 字 元<br />

的 檔 案 , 並 列 出 行 號 <br />

Sol. grep -n ’[!>]’ /etc/*<br />

4.3 延 伸 正 規 表 示 法<br />

• grep 支 援 的 是 基 礎 型 的 正 規 表 示 法 , 延 伸 正 規 表 示 法 egrep 是 grep -E<br />

的 命 令 別 名 。<br />

• 延 伸 型 正 規 表 示 法 之 特 殊 符 號<br />

De-Yu Wang CSIE CYUT 69


4.3. 延 伸 正 規 表 示 法 CHAPTER 4. 正 規 表 示 法<br />

✞<br />

圱 RE 字 符 意 義 與 範 例<br />

+ 重 複 『 一 個 或 一 個 以 上 』 的 前 一 個 RE 字 符<br />

圳<br />

# 範 例 :egrep -n ’go+d’ re.txt 搜 尋<br />

(god) (good) (goood)... 等 等 的 字 串 。<br />

圵 『 零 個 或 一 個 』 的 前 一 個 RE 字 符<br />

# 範 例 :egrep -n ’god’ re.txt 搜 尋<br />

圷 (gd) (god) 這 兩 個 字 串 。<br />

| 用 或 ( or ) 的 方 式 找 出 數 個 字 串<br />

圹<br />

# 範 例 :egrep -n ’gd|good|dog’ re.txt 搜 尋<br />

圱 圱<br />

gd 、 good 或 dog 這 三 個 字 串 。<br />

( ) 找 出 『 群 組 』 字 串 或 作 為 『 多 個 重 複 群 組 』 的 判 別<br />

# 範 例 :egrep -n ’g(la|oo)d’ 搜 尋<br />

圱 圳 (glad) 或 (good) 這 兩 個 字 串 。<br />

# 範 例 :egrep -n ’A(xyz)+C’ re.txt 找 開 頭 是<br />

圱 圵 A 結 尾 是 C , 中 間 有 一 個 以 上 的 "xyz" 字 串 。<br />

✡✝<br />

✆<br />

• 例 題 : 去 除 空 白 行 與 行 首 為 # 的 行 列<br />

✞<br />

圱 # 基 礎 型 的 正 規 表 示 法 需 要 使 用 到 管 線 命 令 來 搜 尋 兩 次<br />

grep -v ’^$’ re.txt | grep -v ’^#’<br />

圳 # 支 援 延 伸 型 正 規 表 示 法 可 以 簡 化 為 :<br />

egrep -v ’^$|^#’ re.txt<br />

✡✝<br />

✆<br />

• 例 題 : 以 延 伸 型 正 規 表 示 法 顯 示 行 號 方 式 , 找 出 目 錄 /etc 以 下 符 合 下 列 條<br />

件 之 檔 案 。<br />

練 習 題<br />

1. 包 含 boot 或 root 字 串 的 檔 案 。<br />

2. 包 含 b 開 頭 t 結 尾 且 中 間 0 個 或 1 個 o 之 字 串 的 檔 案 。<br />

3. b 開 頭 t 結 尾 且 中 間 1 個 o 以 上 之 字 串 的 檔 案 。<br />

1. grep 支 援 的 是 基 礎 型 的 正 規 表 示 法 , 如 何 使 grep 支 援 延 伸 正 規 表 示 法 其<br />

命 令 別 名 為 何 <br />

Sol. grep -E, egrep<br />

2. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 g 後 面 接<br />

1 個 以 上 o , 然 後 再 接 一 個 g 之 字 串 的 行 , 並 列 出 行 號 <br />

Sol. egrep -n ’go+g’ re.txt<br />

3. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 g 開 頭 d<br />

結 尾 且 中 間 0 至 1 個 o 之 字 串 的 行 , 並 列 出 行 號 <br />

Sol. egrep -n ’gog’ re.txt<br />

De-Yu Wang CSIE CYUT 70


4.4. 格 式 化 列 印 CHAPTER 4. 正 規 表 示 法<br />

4. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 gd、<br />

good 或 dog 這 三 個 字 串 的 行 , 並 列 出 行 號 <br />

Sol. egrep -n ’gd|good|dog’ re.txt<br />

5. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 glad 或<br />

good 之 字 串 的 行 , 並 列 出 行 號 <br />

Sol. egrep -n ’g(la|oo)d’ re.txt<br />

6. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 開 頭 是 A<br />

結 尾 是 C , 中 間 有 一 個 以 上 的 "xyz" 之 字 串 的 行 , 並 列 出 行 號 <br />

Sol. egrep -n ’A(xyz)+C’ re.txt<br />

7. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 含 有 開 頭 是 A<br />

結 尾 是 C , 中 間 0 至 一 個 "xyz" 之 字 串 的 行 , 並 列 出 行 號 <br />

Sol. egrep -n ’A(xyz)C’ re.txt<br />

8. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 檔 案 re.txt 中 , 不 含 空 白 行 與<br />

行 首 為 # 的 行 列 , 並 列 出 行 號 <br />

Sol. egrep -n ’^ | ^#’ re.txt<br />

9. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 boot 或<br />

root 之 字 串 的 檔 案 , 並 列 出 行 號 <br />

Sol. egrep -n ’(b|r)oot’ /etc/*<br />

10. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 開 頭 是 b 結<br />

尾 是 t , 中 間 0 至 一 個 o 之 字 串 的 檔 案 , 並 列 出 行 號 <br />

Sol. egrep -n ’bot’ /etc/*<br />

11. 如 何 以 egrep 配 合 延 伸 正 規 表 示 法 , 搜 尋 目 錄 /etc 中 , 含 有 開 頭 是 b 結<br />

尾 是 t , 中 間 一 個 以 上 o 之 字 串 的 檔 案 , 並 列 出 行 號 <br />

Sol. egrep -n ’bo+t’ /etc/*<br />

4.4 格 式 化 列 印<br />

• 列 印 格 式 管 理 員 printf<br />

1. 指 令 用 法 :<br />

圲<br />

✞<br />

[root@linux ~]# printf 列 印 格 式 ’’ 實 際 內 容 選 項 : 關 於 格 式 方 面 的<br />

幾 個 特 殊 樣 式 :<br />

圴 \a 警 告 聲 音 輸 出<br />

\b 倒 退 鍵 (backspace)<br />

圶 \f 清 除 螢 幕 (form feed)<br />

\n 輸 出 新 的 一 行<br />

圸 \r 亦 即 Enter 按 鍵<br />

\t 水 平 的 [tab] 按 鍵<br />

De-Yu Wang CSIE CYUT 71


4.4. 格 式 化 列 印 CHAPTER 4. 正 規 表 示 法<br />

圱 地 \v 垂 直 的 [tab] 按 鍵<br />

\xNN NN 為 兩 位 數 的 數 字 , 可 以 轉 換 數 字 成 為 字 元 。 關 於<br />

圱 圲 C 程 式 語 言 內 , 常 見 的 變 數 格 式<br />

%ns 那 個 n 是 數 字 , s 代 表 string , 亦 即 多 少 個 字 元 ;<br />

圱 圴 %ni 那 個 n 是 數 字 , i 代 表 integer , 亦 即 多 少 整 數 位<br />

數 ;<br />

%N.nf 那 個 n 與 N 都 是 數 字 , f 代 表 floating 浮 點 (), 如<br />

果 有 小 數 位 數 , 假 設 我 共 要 十 個 位 數 , 但 小 數 點 有 兩 位 , 即<br />

為<br />

圱 圶 %10.2f 。<br />

✡✝<br />

✆<br />

2. 如 何 將 printf.txt 內 容 , 以 如 下 漂 亮 的 版 面 配 置 輸 出 <br />

✞<br />

Name Chinese English Math Average<br />

圲 DmTsai 80 60 92 77.33<br />

csie 75 55 80 70.00<br />

圴 Ken<br />

✡✝<br />

60 90 70 73.33<br />

✆<br />

3. 每 個 單 字 中 間 以 [tab] 按 鍵 隔 開 。<br />

✞<br />

[root@linux ~]# printf ’%s\t %s\t %s\t %s\t %s\t \n’ ‘cat<br />

printf.txt‘<br />

圲 Name Chinese English Math Average<br />

DmTsai 80 60 92 77.33<br />

圴 csie 75 55 80 70.00<br />

Ken 60 90 70 73.33<br />

圶 # %s 表 示 以 字 串 (string) 顯 示 內 容 , 每 個 內 容 以 \t 即 [tab] 隔<br />

開 。<br />

# 第 一 行 因 為 某 些 單 字 長 度 較 長 , 所 以 無 法 對 齊 。<br />

✡✝<br />

✆<br />

4. 第 二 行 以 後 , 分 別 以 字 串 、 整 數 、 小 數 點 來 顯 示<br />

✞<br />

圱 [root@linux ~]# printf ’%10s %5i %5i %5i %8.2f \n’ ‘cat<br />

printf.txt |\<br />

> grep -v Name‘<br />

圳 DmTsai 80 60 92 77.33<br />

csie 75 55 80 70.00<br />

圵 Ken 60 90 70 73.33<br />

# %8.2f 針 對 不 同 的 小 數 位 數 來 進 行 格 式 輸 出 ,<br />

圷 # 例 題 :printf ’%10s %5i %5i %5i %8.1f \n’ ‘cat printf.txt |<br />

✡✝<br />

grep -v Name‘<br />

✆<br />

5. 列 出 數 值 45 代 表 的 字 元 為 何 <br />

De-Yu Wang CSIE CYUT 72


4.4. 格 式 化 列 印 CHAPTER 4. 正 規 表 示 法<br />

✞<br />

圱 [root@linux ~]# printf ’\x45\n’<br />

E<br />

✡✝<br />

✆<br />

• 檔 案 列 印 : pr<br />

✞<br />

# 列 印 /etc/man.config<br />

圲 [root@linux ~]# pr /etc/man.config<br />

圴 2003-02-10 23:20 /etc/man.config<br />

Page 1<br />

圶 #<br />

# Generated automatically from man.conf.in by the<br />

圸 # configure script. 以 下 省 略<br />

...........<br />

圱 地<br />

# 第 一 行 的 標 題 中 『 檔 案 時 間 』、『 檔 案 檔 名 』 及 『 頁 碼 』 為 pr 處 理 的 結<br />

果 。<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 如 何 以 printf 將 檔 案 printf.txt 中 的 資 料 , 以 每 行 為 [tab] 按 鍵 後 接<br />

字 串 之 方 式 列 出 <br />

Sol. printf ’\t\%s\n’ ‘cat printf.txt‘<br />

2. 如 何 以 printf 將 檔 案 printf.txt 中 的 資 料 , 以 每 行 為 [tab] 按 鍵 後 接<br />

10 個 字 元 字 串 之 方 式 列 出 <br />

Sol. printf ’\t\%10s\n’ ‘cat printf.txt‘<br />

3. 如 何 以 printf 將 檔 案 printf.txt 中 的 資 料 , 以 每 行 為 [tab] 按 鍵 後 接<br />

整 數 之 方 式 列 出 <br />

Sol. printf ’\t\%i\n’ ‘cat printf.txt‘<br />

4. 如 何 以 printf 將 檔 案 printf.txt 中 的 資 料 , 以 每 行 為 [tab] 按 鍵 後 接<br />

7 個 位 數 整 數 之 方 式 列 出 <br />

Sol. printf ’\t\%7i\n’ ‘cat printf.txt‘<br />

5. 如 何 以 printf 將 檔 案 printf.txt 中 的 資 料 , 以 每 行 為 [tab] 按 鍵 後 接<br />

浮 點 數 之 方 式 列 出 <br />

Sol. printf ’\t\%f\n’ ‘cat printf.txt‘<br />

6. 如 何 以 printf 將 檔 案 printf.txt 中 的 資 料 , 以 每 行 為 [tab] 按 鍵 後<br />

接 , 十 個 位 數 , 但 小 數 點 有 兩 位 的 浮 點 數 之 方 式 列 出 <br />

Sol. printf ’\t\%10.2f\n’ ‘cat printf.txt‘<br />

De-Yu Wang CSIE CYUT 73


4.4. 格 式 化 列 印 CHAPTER 4. 正 規 表 示 法<br />

7. 如 何 以 printf 列 出 數 值 42 代 表 的 字 元 <br />

Sol. printf ’\x42\n’<br />

De-Yu Wang CSIE CYUT 74


CHAPTER 5.<br />

SED 與 AWK 工 具<br />

Chapter 5<br />

sed 與 awk 工 具<br />

5.1 sed 工 具<br />

• sed (stream editor) 可 以 分 析 Standard Input (STDIN) 的 資 料 , 進 行<br />

取 代 、 刪 除 、 新 增 、 擷 取 特 定 行 等 處 理 後 , 再 輸 出 到 standrad out<br />

(STDOUT)。<br />

1. sed 指 令<br />

✞<br />

圱 [root@linux ~]# sed [-nefr] 動 作 [] 選 項 :<br />

圳 -n : 使 用 安 靜 (silent) 模 式 。 在 一 般 sed 的 用 法 中 , 所 有 來<br />

自 STDIN 的 資 料 一 般 都 會 被 列 出 到 螢 幕 上 。 但 如 果 加 上<br />

-n 參 數 後 , 則 只 有 經 過<br />

圵 sed 特 殊 處 理 的 那 一 行 或 者 動 作 () 才 會 被 列 出 來 。<br />

-e : 直 接 在 指 令 列 模 式 上 進 行 sed 的 動 作 編 輯 ;<br />

圷 -f : -f filename 可 以 執 行 filename 內 的 sed 動 作 ;<br />

-r : sed 的 動 作 支 援 的 是 延 伸 型 正 規 表 示 法 的 語 法 。 預 設 是 基 礎 正 規 表<br />

示 法 語 法 ()<br />

圹 -i : 直 接 修 改 讀 取 的 檔 案 內 容 , 而 不 是 由 螢 幕 輸 出 。 動 作 說 明 :<br />

圱 圱 [n1[,n2]]function<br />

n1, n2 : 選 擇 進 行 動 作 的 行 數 , 例 如 ,『 動 作 行 為 10,20[] 』:<br />

圱 圳<br />

function<br />

圱 圵 a : 新 增 , a 的 後 面 可 以 接 字 串 , 這 些 字 串 會 在 目 前 的 下 一 行 出 現 。<br />

c : 取 代 , c 的 後 面 可 以 接 字 串 , 這 些 字 串 可 以 取 代 n1,n2 之 間 的<br />

圱 圷<br />

行 。<br />

d : 刪 除 , d 後 面 通 常 不 接 任 何 字 串 ;<br />

i : 插 入 , i 的 後 面 可 以 接 字 串 , 這 些 字 串 會 在 目 前 的 上 一 行 出 現 ;<br />

圱 圹 p : 列 印 , 將 某 個 選 擇 的 資 料 印 出 。 通 常 p 會 與 參 數 sed -n 一 起 運<br />

作 。<br />

s : 取 代 ,<br />

✡✝<br />

s 的 動 作 可 以 搭 配 正 規 表 示 法 。 例 如 1,20s/old/new/g 。<br />

✆<br />

2. 列 出 /etc/passwd 的 內 容 , 並 且 列 印 行 號 , 同 時 將 第 2 5 行 刪 除 。<br />

De-Yu Wang CSIE CYUT 75


5.1. SED 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

✞<br />

[root@linux ~]# nl /etc/passwd | sed ’2,5d’<br />

圲 1 root:x:0:0:root:/root:/bin/bash<br />

6 sync:x:5:0:sync:/sbin:/bin/sync<br />

圴 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 後 面 省 略<br />

.....().....<br />

圶 # sed 後 面 接 的 動 作 , 務 必 以 ’’ 兩 個 單 引 號 括 住 。<br />

# 如 果 只 要 刪 除 第 2 行 , 可 以 使 用 nl /etc/passwd | sed ’2d,’<br />

圸 # 刪 除 第 3 到 最 後 一 行 , 則 是 nl /etc/passwd | sed ’3,$d’ 。<br />

✡✝<br />

✆<br />

3. 在 第 二 行 後 加 上 『drink tea』 字 樣 。<br />

✞<br />

[root@linux ~]# nl /etc/passwd | sed ’2a drink tea’<br />

圲 1 root:x:0:0:root:/root:/bin/bash<br />

2 bin:x:1:1:bin:/bin:/sbin/nologin<br />

圴 drink tea<br />

3 daemon:x:2:2:daemon:/sbin:/sbin/nologin<br />

圶 # 如 果 要 在 第 二 行 前 nl /etc/passwd | sed ’2i drink tea。’<br />

✡✝<br />

✆<br />

4. 在 第 二 行 後 面 加 入 兩 行 字 , 例 如 『Drink tea or .....』 『drink<br />

beer』<br />

✞<br />

[root@linux ~]# nl /etc/passwd | sed ’2a Drink tea or ......\<br />

圲 > drink beer ’<br />

1 root:x:0:0:root:/root:/bin/bash<br />

圴 2 bin:x:1:1:bin:/bin:/sbin/nologin<br />

Drink tea or ......<br />

圶 drink beer <br />

3 daemon:x:2:2:daemon:/sbin:/sbin/nologin<br />

圸 # 可 以 新 增 好 幾 行 , 但 每 一 行 之 間 都 必 須 要 以 反 斜 線 \ 來 進 行 新 行 的 增<br />

✡✝ 加 。<br />

✆<br />

5. 將 第 2-5 行 的 內 容 取 代 成 為 『No 2-5 number』<br />

✞<br />

[root@linux ~]# nl /etc/passwd | sed ’2,5c No 2-5 number’<br />

圲 1 root:x:0:0:root:/root:/bin/bash<br />

No 2-5 number<br />

圴 6 sync:x:5:0:sync:/sbin:/bin/sync<br />

✡✝<br />

✆<br />

6. 僅 列 出 第 5-7 行<br />

✞<br />

[root@linux ~]# nl /etc/passwd | sed -n ’5,7p’<br />

圲 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin<br />

De-Yu Wang CSIE CYUT 76


5.1. SED 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

6 sync:x:5:0:sync:/sbin:/bin/sync<br />

圴 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown<br />

# 沒 有 加 -n 參 數 時 sed ’5,7p’ , 行 會 重 複 輸 出 。5-7<br />

✡✝<br />

✆<br />

7. 使 用 ifconfig 列 出 IP , 若 僅 要 eth0 的 IP<br />

✞<br />

圱 [root@linux ~]# ifconfig eth0<br />

eth0 Link encap:Ethernet HWaddr 00:51:FD:52:9A:CA<br />

圳 inet addr:192.168.1.12 Bcast:192.168.1.255 Mask<br />

:255.255.255.0<br />

inet6 addr: fe80::250:fcff:fe22:9acb/64 Scope:Link<br />

圵 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1<br />

以 下 省<br />

.....().....<br />

略<br />

圷 # 只 是 inet addr 那 一 行 , 利 用 :.. grep 與 sed 來 取<br />

[root@linux ~]# ifconfig eth0 | grep ’inet ’ | sed ’s/^.*addr<br />

://g’ | \<br />

圹 > sed ’s/Bcast.*$//g’<br />

✡✝<br />

✆<br />

8. 將 /etc/man.config 檔 案 的 內 容 中 , 有 MAN 的 設 定 取 出 , 且 刪 除 註 解<br />

說 明 。<br />

✞<br />

圱 [root@linux ~]# cat /etc/man.config | grep ’MAN’| sed ’s/#.*$<br />

//g’ | \<br />

> sed ’/^$/d’<br />

圳 # 註 解 以 ( # 開 頭 ) 不 一 定 寫 在 第 一 個 字 元 , 所 以 必 須 使 用 正 規 表 示<br />

法 #.*$ 。<br />

✡✝<br />

✆<br />

9. 利 用 sed 直 接 在 ~/.bashrc 最 後 一 行 加 入 # This is a test<br />

✞<br />

圱 [root@linux ~]# sed -i ’$a # This is a test’ ~/.bashrc<br />

# -i 參 數 可 以 讓 sed 直 接 去 修 改 後 面 接 的 檔 案 內 容 , 而 不 是 由 螢 幕 輸<br />

出 。<br />

圳 # $a 則 代 表 最 後 一 行 才 新 增 。<br />

✡✝<br />

✆<br />

10. 利 用 sed 刪 除 檔 案 /tmp/man.config 第 10 行 至 最 後 一 行 , 且 將 字 串<br />

man 改 成 MAN。<br />

✞<br />

圱 [root@dywHome2 tmp]# sed -e ’10,$d’ -e ’s/man/MAN/g’ man.<br />

config<br />

#<br />

圳 # Generated automatically from MAN.conf.in by the<br />

De-Yu Wang CSIE CYUT 77


5.1. SED 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

# configure script.<br />

圵 #<br />

# MAN.conf from MAN-1.5m<br />

圷 #<br />

# For more information about this file, see the MAN pages MAN<br />

(1)<br />

圹 # and MAN.conf(5).<br />

#<br />

圱 圱<br />

# 如 果 不 加 參 數 -, 則 無 法 同 時 完 成 上 述 刪 除 與 取 代 命 令 。e<br />

✡✝<br />

✆<br />

11. 若 將 上 例 刪 除 與 取 代 命 令 編 輯 至 檔 案 ds.src, 如 何 利 用 sed 及 檔 案<br />

ds.src, 執 行 同 樣 的 命 令 <br />

✞<br />

[root@dywHome2 tmp]# vi ds.src<br />

圲 [root@dywHome2 tmp]# cat ds.src<br />

10,$d<br />

圴 s/man/MAN/g<br />

[root@dywHome2 tmp]# sed -f ds.src man.config<br />

圶 #<br />

# Generated automatically from MAN.conf.in by the<br />

圸 # configure script.<br />

#<br />

圱 地 # MAN.conf from MAN-1.5m<br />

#<br />

圱 圲 # For more information about this file, see the MAN pages MAN<br />

(1)<br />

# and MAN.conf(5).<br />

圱 圴 #<br />

✡✝<br />

✆<br />

12. 關 鍵 符 號 + - * / 的 取 代<br />

圲<br />

圴<br />

✞<br />

[dywang@deyu moodle]$ echo ’+-*/+-*/’ | sed "s/\([+\\-*/]\)<br />

/\1A/g"<br />

sed: -e expression #1, char 19: Invalid range end<br />

[dywang@deyu moodle]$ echo ’+-*/+-*/’ | sed "s/\([+*/\\-]\)<br />

/\1A/g"<br />

+A-A*A/A+A-A*A/A<br />

✡✝<br />

✆<br />

練 習 題<br />

1. sed 之 功 能 為 何 <br />

Sol. 分 析 STDIN 的 資 料 , 進 行 取 代 、 刪 除 、 新 增 、 擷 取 特 定 行 等 處 理<br />

後 , 再 輸 出 到 STDOUT。<br />

De-Yu Wang CSIE CYUT 78


5.1. SED 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

2. 如 何 以 nl 列 出 /etc/passwd 的 內 容 , 同 時 將 第 2 至 5 行 刪 除 <br />

Sol. nl /etc/passwd | sed ’2,5d’<br />

3. 如 何 以 nl 列 出 /etc/passwd 的 內 容 , 同 時 將 第 2 行 刪 除 <br />

Sol. nl /etc/passwd | sed ’2d’<br />

4. 如 何 以 nl 列 出 /etc/passwd 的 內 容 , 同 時 將 第 5 至 最 後 一 行 刪 除 <br />

Sol. nl /etc/passwd | sed ’5,$d’<br />

5. 如 何 以 nl 列 出 /etc/passwd 的 內 容 , 同 時 在 第 五 行 後 加 上 『new line』<br />

字 樣 <br />

Sol. nl /etc/passwd | sed ’5a new line’<br />

6. 如 何 以 nl 列 出 /etc/passwd 的 內 容 , 同 時 在 第 五 行 前 加 上 『new line』<br />

字 樣 <br />

Sol. nl /etc/passwd | sed ’5i new line’<br />

7. 若 要 以 nl 列 出 /etc/passwd 的 內 容 , 同 時 在 第 五 行 後 加 上 多 行 字 , 則 行<br />

間 必 須 如 何 區 隔 <br />

Sol. 以 反 斜 線 \ 來 進 行 新 行 的 增 加 。<br />

8. 如 何 以 nl 列 出 /etc/passwd 的 內 容 , 同 時 將 第 2-5 行 的 內 容 取 代 成 為<br />

『No 2-5 number』<br />

Sol. nl /etc/passwd | sed ’2,5c No 2-5 number’<br />

9. 如 何 以 nl 列 出 /etc/passwd 的 內 容 , 同 時 僅 列 出 第 5-7 行 <br />

Sol. nl /etc/passwd | sed -n ’5,7p’<br />

10. 若 下 指 令 nl /etc/passwd | sed ’5,7p’, 則 第 5-7 行 會 如 何 顯 示 <br />

Sol. sed 沒 有 加 -n 參 數 時 ,5-7 行 會 重 複 輸 出 。<br />

11. 如 何 使 用 ifconfig 列 出 IP, 同 時 以 gerp 取 出 含 有 inet 的 行 , 再 以<br />

sed 將 其 他 字 串 取 代 為 空 白 字 元 , 而 僅 留 下 eth0 的 IP<br />

Sol. ifconfig eth0 | grep ’inet ’ | sed ’s/^.*addr://g’ |<br />

sed ’s/Bcast.*$//g’<br />

12. 如 何 將 /etc/man.config 檔 案 的 內 容 中 , 有 MAN 的 設 定 取 出 , 且 刪 除 註 解<br />

說 明 <br />

Sol. cat /etc/man.config | grep ’MAN’| sed ’s/#.*$//g’ |<br />

sed ’/^$/d’<br />

13. 如 何 利 用 sed 直 接 在 ~/.bashrc 最 後 一 行 加 入 『# This is a test』<br />

Sol. sed -i ’$a # This is a test’ ~/.bashrc<br />

14. 利 用 sed 刪 除 檔 案 /tmp/man.config 第 10 行 至 最 後 一 行 , 且 將 字 串 man<br />

改 成 MAN。<br />

Sol. sed -e ’10,$d’ -e ’s/man/MAN/g’ man.config<br />

De-Yu Wang CSIE CYUT 79


5.2. AWK 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

15. 檔 案 ds.src 中 有 sed 編 輯 命 令 , 如 何 利 用 ds.src 對 檔 案<br />

/tmp/man.config, 執 行 sed 編 輯 <br />

Sol. sed -f ds.src man.config<br />

5.2 awk 工 具<br />

• awk 工 具 : 相 較 於 sed 作 用 於 一 整 個 行 的 處 理 ,awk 是 『 以 行 為 一 次 處 理<br />

的 單 位 』, 而 『 以 欄 位 為 最 小 的 處 理 單 位 』。<br />

1. awk 指 令<br />

✞<br />

[root@linux ~]# awk 條 件 類 型 動 作 ’1{1} 條 件 類 型 動<br />

作 2{2} ...’ filename<br />

✡✝<br />

✆<br />

2. 取 出 帳 號 與 登 入 者 的 IP: 欄 位 的 分 隔 符 號 為 空 白 鍵 或 [tab] 鍵<br />

✞<br />

圱 [root@linux ~]# last<br />

csie pts/0 192.168.1.12 Mon Aug 22 09:40 still<br />

logged in<br />

圳 root tty1 Mon Aug 15 11:38 -<br />

11:39 (00:01)<br />

reboot system boot 2.6.11 Sun Aug 14 18:18<br />

(7+15:41)<br />

圵 csie pts/0 192.168.1.12 Fri Aug 12 12:07 - 12:08<br />

✡✝<br />

(00:01)<br />

✆<br />

3. 取 出 帳 號 與 登 入 者 的 IP, 且 帳 號 與 IP 之 間 以 [tab] 隔 開 :<br />

✞<br />

圱 [root@linux ~]# last | awk ’{print $1 "\t" $3}’<br />

csie 192.168.1.12<br />

圳 root Mon<br />

reboot boot<br />

圵 csie 192.168.1.12<br />

# 變 數 $0 代 表 『 一 整 列 資 料 』, 第 一 行 的 $0 代 表 的 就 是<br />

✡✝<br />

『csie pts/0.... 』。<br />

✆<br />

• awk 的 內 建 變 數<br />

1. 變 數<br />

變 數 名 稱<br />

NF<br />

NR<br />

FS<br />

代 表 意 義<br />

每 一 行 ($0) 擁 有 的 欄 位 總 數<br />

目 前 awk 所 處 理 的 是 『 第 幾 行 』 資 料<br />

目 前 的 分 隔 字 元 , 預 設 是 空 白 鍵<br />

De-Yu Wang CSIE CYUT 80


5.2. AWK 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

2. 承 上 例 : 列 出 每 一 行 的 帳 號 , 並 列 出 目 前 處 理 的 行 數 及 該 行 有 多 少 欄<br />

位 。<br />

✞<br />

[root@linux ~]# last | awk ’{print $1 "\t lines: " NR "\t<br />

columes: " NF}’<br />

圲 csie lines: 1 columes: 10<br />

root lines: 2 columes: 9<br />

圴 reboot lines: 3 columes: 9<br />

csie<br />

✡✝<br />

lines: 4 columes: 10<br />

✆<br />

• awk 的 邏 輯 運 算<br />

1. 邏 輯 運 算 字 元<br />

運 算 單 元 代 表 意 義<br />

> 大 於<br />

< 小 於<br />

>= 大 於 或 等 於<br />

awk ’{FS=":"} $3 < 10 {print $1 "\t " $3}’<br />

圳<br />

root:x:0:0:root:/root:/bin/bash<br />

bin 1<br />

圵 daemon 2 以 下 省 略<br />

......()......<br />

圷 # 因 讀 入 第 一 行 時 , 變 數 $1, $2... 預 設 還 是 以 空 白 鍵 為 分 隔 。 因 此 ,<br />

第 一 行 沒 有 正 確 的 顯 示 。<br />

✡✝<br />

✆<br />

3. 承 上 例 , 利 用 關 鍵 字 BEGIN 讓 第 一 行 正 確 顯 示 。<br />

✞<br />

圱 [root@linux ~]# cat /etc/passwd | \<br />

> awk ’BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}’<br />

圳 root 0<br />

bin 1<br />

圵 daemon 2 以 下 省 略<br />

......()......<br />

✡✝<br />

✆<br />

4. 計 算 每 個 人 薪 資 總 額 並 且 格 式 化 輸 出 , 薪 資 資 料 表 pay.txt 如 下 :<br />

De-Yu Wang CSIE CYUT 81


5.2. AWK 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

✞<br />

Name 1st 2nd 3th<br />

圲 csie 23000 24000 25000<br />

Wang 21000 20000 23000<br />

圴 Lin 43000 42000 41000<br />

圶<br />

[root@linux ~]# cat pay.txt | \<br />

圸 > awk ’NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,<br />

"Total" }<br />

NR>=2{total = $2 + $3 + $4<br />

圱 地 printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total<br />

}’<br />

Name 1st 2nd 3th Total<br />

圱 圲 csie 23000 24000 25000 72000.00<br />

Wang 21000 20000 23000 64000.00<br />

圱 圴 Lin 43000 42000 41000 126000.00<br />

圱 圶<br />

# 在 {} 內 的 有 多 個 指 令 時 , 可 利 用 分 號 『』, 或 ; [Enter] 按 鍵 來 隔<br />

開 指 令 。<br />

# 與 bash shell 的 變 數 不 同 , 在 awk 當 中 , 變 數 可 以 直 接 使 用 , 不 需<br />

加 上 $ 符 號 。<br />

✡✝<br />

✆<br />

5. awk 的 動 作 內 { } 支 援 if ( 條 件 ):<br />

✞<br />

圱 [root@linux ~]# cat pay.txt | \<br />

> awk ’{if(NR==1) printf "%10s %10s %10s %10s %10s\n",$1,$2,<br />

$3,$4,"Total"}<br />

圳 NR>=2{total = $2 + $3 + $4<br />

printf "%10s %10d %10d %10d %10.2f\n", $1, $2, $3, $4, total<br />

}’<br />

✡✝<br />

✆<br />

6. 例 題 : 將 如 下 printf.txt 檔 案 內 容 以 awk 指 令 輸 出 , 格 式 如 下<br />

printf.txt 輸 出 格 式 , 其 中 每 個 欄 位 長 度 為 9 個 字 元 。<br />

✞<br />

## printf.txt 內 容<br />

圲 Name Chinese English Math<br />

DmTsai 80 60 92<br />

圴 csie 75 55 80<br />

Ken 60 90 70<br />

圶 ##printf. 輸 出 格 式 txt<br />

Name Chinese English Math Total<br />

圸 DmTsai 80 60 92 232.00<br />

csie 75 55 80 210.00<br />

圱 地<br />

✡✝<br />

Ken 60 90 70 220.00<br />

✆<br />

De-Yu Wang CSIE CYUT 82


5.2. AWK 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

練 習 題<br />

1. 如 何 利 用 awk 取 出 帳 號 與 登 入 者 的 IP, 且 帳 號 與 IP 之 間 以 [tab] 隔<br />

開 <br />

Sol. last | awk ’{print $1 "\t" $3}’<br />

2. 如 何 利 用 awk 取 出 帳 號 , 並 列 出 目 前 處 理 的 行 數 及 該 行 有 多 少 欄 位 , 且 之 間<br />

以 預 設 的 分 隔 字 元 隔 開 <br />

Sol. last | awk ’{print $1 FS NR FS NF}’<br />

3. /etc/passwd 以 冒 號 ":" 作 為 欄 位 的 分 隔 , 如 何 查 閱 第 三 欄 小 於 等 於 50<br />

以 下 的 數 據 , 並 且 僅 列 出 帳 號 與 第 三 欄 <br />

Sol. cat /etc/passwd | awk ’BEGIN {FS=":"}<br />

$3 %*=2{total=$2+$3+$4; printf "%8s<br />

%8d %8d %8d %8.2f\n",$1,$2,$3,$4,total}’<br />

5. 如 何 輸 出 /etc/man.config 至 印 表 機 <br />

Sol. pr /etc/man.config<br />

De-Yu Wang CSIE CYUT 83


5.2. AWK 工 具 CHAPTER 5. SED 與 AWK 工 具<br />

De-Yu Wang CSIE CYUT 84


CHAPTER 6.<br />

SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

Chapter 6<br />

Shell Scripts – 簡 介 與 test 功 能<br />

6.1 前 言<br />

• 何 謂 Shell Script<br />

1. 文 字 介 面 下 讓 使 用 者 與 系 統 溝 通 的 一 個 工 具 介 面 。<br />

2. 利 用 shell 的 功 能 所 寫 的 一 支 『 程 式 (program)』。<br />

3. 將 一 些 shell 的 語 法 與 指 令 寫 成 純 文 字 檔 ;<br />

4. 可 搭 配 正 規 表 示 法 、 管 線 命 令 與 資 料 流 重 導 向 等 功 能 ;<br />

5. shell script 更 提 供 陣 列 、 迴 圈 、 條 件 與 邏 輯 判 斷 等 重 要 功 能 ;<br />

6. 使 用 者 也 可 以 直 接 以 shell 來 撰 寫 程 式 。<br />

• Shell scripts 執 行 流 程 :<br />

逐 行 直 譯<br />

❄<br />

逐 行 執 行<br />

✛<br />

Shell scripts<br />

✻<br />

❄<br />

✏ ✏✏✏✏ ✏<br />

✏ 是 否 結 束 <br />

✏ ✏ ✏<br />

❄Yes<br />

執 行 結 果<br />

No<br />

• 為 什 麼 要 學 習 shell scripts<br />

1. 自 動 化 管 理 的 重 要 依 據 : 自 動 處 理 分 析 主 機 狀 態 , 若 有 問 題 才 通 知 。<br />

2. 追 蹤 與 管 理 系 統 的 重 要 工 作 :<strong>Linux</strong> 系 統 的 服 務 ( services ) 啟 動 的 介<br />

面 , 在 目 錄 /etc/init.d/ 下 , 所 有 的 檔 案 都 是 scripts。<br />

De-Yu Wang CSIE CYUT 85


6.1. 前 言 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

3. 簡 單 入 侵 偵 測 功 能 : 主 動 分 析 系 統 登 錄 檔 。<br />

4. 連 續 指 令 單 一 化 : 彙 整 在 command line 下 達 的 連 續 指 令 。 例 如 :<br />

/etc/rc.d/rc.local 裡 的 資 料 。<br />

5. 簡 易 的 資 料 處 理 : 處 理 數 據 資 料 的 比 對 , 文 字 資 料 的 處 理 等 。<br />

6. 跨 平 台 支 援 與 學 習 歷 程 較 短 : 幾 乎 所 有 的 <strong>Unix</strong> Like 上 面 都 可 以 跑<br />

shell script 。<br />

7. shell script 是 一 項 很 好 的 系 統 管 理 工 具 , 但 數 值 運 算 的 速 度 較 慢 ,<br />

且 使 用 的 CPU 資 源 較 多 。<br />

• Scripts 撰 寫 注 意 事 項 :<br />

1. 指 令 與 參 數 間 的 多 個 空 白 會 被 忽 略 掉 ;<br />

2. 空 白 行 及 [tab] 不 會 被 理 會 ;<br />

3. 讀 到 [Enter] 符 號 , 就 開 始 執 行 該 行 命 令 ;<br />

4. 一 行 的 內 容 太 多 , 可 以 使 用 \[Enter] 來 延 伸 至 下 一 行 ;<br />

5. 加 在 # 後 面 的 字 , 全 部 被 視 為 註 解 。<br />

• 如 何 執 行 檔 案 shell.sh <br />

1. 將 shell.sh 加 上 可 讀 與 執 行 (rx) 的 權 限 , 就 能 夠 以 ./shell.sh 執<br />

行 ;<br />

2. 直 接 以 sh shell.sh 方 式 執 行 。<br />

• 撰 寫 第 一 支 script<br />

✞<br />

[root@linux ~]# mkdir scripts; cd scripts<br />

圲 [root@linux scripts]# vi sh01.sh<br />

#!/bin/bash<br />

圴 # Program:<br />

# This program is used to show "Hello World !" in screen.<br />

圶 # History:<br />

# 2005/08/23 csie First release<br />

圸<br />

echo -e "Hello World ! \a \n"<br />

圱 地 exit 0<br />

✡✝<br />

✆<br />

1. 程 式 內 容 的 宣 告 :script 當 中 , 除 了 第 一 行 的 #! 是 用 來 宣 告 shell<br />

外 , 其 他 的 # 都 是 『 註 解 』。<br />

2. 主 要 環 境 變 數 的 宣 告 : 例 如 PATH。<br />

3. 主 要 程 式 部 分 : echo 選 項 -e 代 表 解 釋 倒 斜 線 \ 跳 脫 字 元 。 \a 為<br />

警 告 ;\n 為 換 行 。<br />

4. 執 行 成 果 告 知 :<br />

De-Yu Wang CSIE CYUT 86


6.1. 前 言 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

(a) 可 以 利 用 指 令 exit 讓 程 式 中 斷 , 並 且 回 傳 一 個 數 值 給 系 統 。<br />

(b) 在 此 例 中 使 用 exit 0 , 代 表 離 開 script , 並 且 回 傳 0 給 系<br />

統 。<br />

(c) 指 令 執 行 成 功 與 否 , 可 下 達 echo $ 觀 察 回 傳 值 。<br />

(d) 利 用 exit n 的 功 能 , 可 以 自 訂 錯 誤 訊 息 。<br />

5. 執 行 結 果<br />

✞<br />

[root@linux scripts]# sh sh01.sh<br />

圲 Hello World !<br />

✡✝<br />

✆<br />

• 建 立 撰 寫 shell script 的 良 好 習 慣 , 在 每 個 script 的 檔 頭 記 錄 下 列 資<br />

訊 , 以 助 程 式 的 改 寫 與 debug:<br />

練 習 題<br />

1. script 的 功 能 ;<br />

2. script 的 版 本 資 訊 ;<br />

3. script 的 作 者 與 聯 絡 方 式 ;<br />

4. script 的 版 權 宣 告 方 式 ;<br />

5. script 的 History ( 歷 史 紀 錄 );<br />

6. script 內 較 特 殊 的 指 令 , 使 用 絕 對 路 徑 的 方 式 來 下 達 ;<br />

7. script 運 作 時 需 要 的 環 境 變 數 預 先 宣 告 與 設 定 。<br />

1. Shell scripts 是 二 進 位 檔 <br />

Sol. 不 是 , 是 純 文 字 檔<br />

2. Shell scripts 可 提 供 陣 列 、 迴 圈 、 條 件 與 邏 輯 判 斷 等 重 要 功 能 <br />

Sol. 是<br />

3. <strong>Linux</strong> 系 統 的 服 務 是 二 進 位 執 行 檔 <br />

Sol. 不 是 , 是 純 文 字 Shell scripts 檔<br />

4. 只 要 是 <strong>Unix</strong>-like 系 統 , 都 可 以 執 行 Shell scripts<br />

Sol. 是<br />

5. Shell scripts 中 註 解 的 符 號 為 何 <br />

Sol. #<br />

6. 一 般 shell scripts 的 副 檔 名 為 何 <br />

Sol. sh<br />

7. shell script 中 第 一 行 開 頭 , 經 常 出 現 #!, 代 表 註 解 <br />

Sol. 不 是 , 是 用 來 宣 告 用 什 麼 程 式 執 行 script<br />

De-Yu Wang CSIE CYUT 87


6.2. 視 SHELL 為 一 種 程 式 語 CHAPTER 言 6.<br />

SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

8. shell script 中 退 出 指 令 為 何 <br />

Sol. exit<br />

9. shell script 中 exit 0, 執 行 結 果 為 何 <br />

Sol. 離 開 script , 並 且 回 傳 0 給 系 統 。<br />

10. 如 何 觀 察 shell script 執 行 回 傳 值 <br />

Sol. 下 達 echo $<br />

6.2 視 Shell 為 一 種 程 式 語 言<br />

• 撰 寫 shell 程 式 的 方 法 :<br />

1. 互 動 式 (interactive) 程 式 : 輸 入 一 連 串 的 命 令 , 並 允 許 shell 立 即<br />

執 行 。<br />

✞<br />

$ for file in *<br />

圲 > do<br />

> if grep -l POSIX $file<br />

圴 > then<br />

> more $file<br />

圶 > fi<br />

> done<br />

圸 posix<br />

This is a file with POSIX in it - treat it well<br />

圱 地 $<br />

✡✝<br />

✆<br />

(a) 當 輸 入 shell 命 令 後 ,shell 命 令 提 示 符 號 $ 就 變 成 >。<br />

(b) 可 以 不 斷 輸 入 直 到 結 尾 , 再 讓 shell 立 刻 執 行 這 個 script。<br />

(c) 迴 圈 變 數 可 以 使 用 i , 但 file 是 比 較 有 意 義 的 變 數 名 稱 。<br />

(d) 萬 用 字 元 "*" , 用 來 代 表 任 何 吻 合 的 字 串 。<br />

(e) grep -l POSIX: 表 示 若 檔 案 中 包 含 字 串 POSIX 則 顯 示 檔 名 , 而 不<br />

顯 示 內 容 。<br />

(f) 最 後 兩 行 為 執 行 的 結 果 。<br />

2. 將 命 令 存 成 程 式 檔 案 。 使 用 文 字 編 輯 器 產 生 一 個 script, 檔 名<br />

sh02.sh:<br />

✞<br />

#!/bin/sh<br />

圲 # first<br />

# This file looks through all the files in the current<br />

圴 # directory for the string POSIX, and then prints the names<br />

of<br />

# those files to the standard output.<br />

圶 for file in *<br />

do<br />

De-Yu Wang CSIE CYUT 88


6.2. 視 SHELL 為 一 種 程 式 語 CHAPTER 言 6.<br />

SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

圸 if grep -q POSIX $file<br />

then<br />

圱 地 echo $file<br />

fi<br />

圱 圲 done<br />

exit 0<br />

✡✝<br />

✆<br />

1. 可 以 使 用 .sh 或 隨 意 加 上 延 伸 檔 名 ,shell 不 會 在 乎 。<br />

2. 可 以 利 用 file 命 令 來 判 斷 是 否 為 script, 例 如 file sh02.sh 或<br />

file /bin/bash。<br />

✞<br />

圱 [csie@localhost csie]$ file sh02.sh<br />

sh02.sh: Bourne shell script text executable<br />

圳 [csie@localhost csie]$ file /bin/bash<br />

/bin/bash: ELF 32-bit LSB executable, Intel 80386,<br />

圵 version 1 (SYSV), for GNU/<strong>Linux</strong> 2.2.5,<br />

dynamically linked (uses shared libs), stripped<br />

✡✝<br />

✆<br />

• 執 行 script<br />

1. 呼 叫 shell, 將 script 當 成 參 數 (parameter):<br />

✞<br />

$ /bin/sh sh02.sh<br />

✡✝<br />

✆<br />

2. 輸 入 script 名 稱 直 接 執 行<br />

✞<br />

圱 $ chmod +x sh02.sh<br />

$ sh02.sh<br />

圳 bash: sh02.sh: command not found<br />

$ ./sh02.sh<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 請 利 用 第 二 至 四 章 之 shell 功 能 , 撰 寫 一 shell script( 每 一 指 令 或 功 能<br />

皆 註 明 其 在 講 義 之 頁 碼 )<br />

至 少 包 含 註 解 ( 姓 名 、 學 號 、 程 式 功 能 、 日 期 、 版 本 )、 sed、awk、 變 數 使<br />

用 、 管 線 處 理 、 正 規 表 示 法 。<br />

Sol.<br />

2. shell script 中 , 讀 到 什 麼 符 號 , 就 開 始 執 行 該 行 命 令 <br />

Sol. [Enter] 符 號<br />

De-Yu Wang CSIE CYUT 89


6.3. SHELL SCRIPT 練 習 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

3. shell script 中 , 一 行 的 內 容 太 多 , 要 如 何 延 伸 至 下 一 行 <br />

Sol. 使 用 \[Enter]<br />

4. shell script 中 , 如 何 加 入 註 解 <br />

Sol. # 後 面 的 字 , 全 部 被 視 為 註 解<br />

5. 如 何 執 行 shell script 檔 案 shell.sh <br />

Sol. 1. 將 shell.sh 加 上 可 讀 與 執 行 (rx) 的 權 限 , 就 能 夠 以<br />

./shell.sh 執 行 ; 2. 直 接 以 sh shell.sh 方 式 執 行 。<br />

6. shell script 中 , 第 一 行 出 現 #!/bin/bash , 代 表 意 義 為 何 <br />

Sol. 宣 告 使 用 /bin/bash 執 行 這 個 script<br />

7. shell script 中 , 最 後 出 現 exit 0 , 代 表 意 義 為 何 <br />

Sol. 離 開 script , 並 且 回 傳 0 給 系 統<br />

8. 撰 寫 shell script 有 那 兩 種 方 式 <br />

Sol. 1. 輸 入 一 連 串 的 命 令 後 立 即 執 行 ;2. 將 命 令 存 在 一 個 檔 案 中 , 隨 後 當<br />

成 一 個 程 式 來 執 行 。<br />

6.3 shell script 練 習<br />

• 變 數 內 容 由 使 用 者 決 定 : 請 以 read 指 令 , 撰 寫 一 個 script 讓 使 用 者<br />

輸 入 :1. first name 與 2. last name, 最 後 在 螢 幕 上 顯 示 :『Your<br />

full name is: 』 的 內 容 :<br />

✞<br />

[root@linux scripts]# vi sh03.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # Let user keyin their first and last name, and show their<br />

full name.<br />

# History:<br />

圶 # 2005/08/23 csie First release<br />

圸 read -p "Please input your first name: " firstname<br />

read -p "Please input your last name: " lastname<br />

圱 地 # read -p 後 面 接 提 示 字 元<br />

echo -e "\nYour full name is: $firstname $lastname"<br />

圱 圲 # echo -e enable interpretation of backslash escapes 解<br />

釋 ( \n 為 new line)<br />

✡✝<br />

✆<br />

• 利 用 date 進 行 檔 案 的 建 立 : 建 立 三 個 空 的 檔 案 , 檔 名 最 開 頭 由 使<br />

用 者 輸 入 決 定 , 後 接 前 天 、 昨 天 、 今 天 日 期 。 例 如 : 若 使 用 者 輸 入<br />

filename, 今 天 日 期 是 2005/08/23, 則 建 立 的 檔 案 為 filename20050821,<br />

filename20050822, filename20050823。<br />

De-Yu Wang CSIE CYUT 90


6.3. SHELL SCRIPT 練 習 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

✞<br />

[root@linux scripts]# vi sh04.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # User can keyin filename to touch 3 new files.<br />

# History:<br />

圶 # 2005/08/23 csie First release<br />

圸 # 1. 讓 使 用 者 輸 入 檔 案 名 稱 , 並 取 得 fileuser 這 個 變 數 ;<br />

echo -e "I will use ’touch’ command to create 3 files."<br />

圱 地 read -p "Please input the filename what you want: " fileuser<br />

圱 圲 # 2. 為 了 避 免 使 用 者 隨 意 按 Enter , 利 用 變 數 功 能 分 析 檔 名 是 否 有 設 定 <br />

filename=${fileuser:-"filename"}<br />

圱 圴<br />

# 3. 開 始 利 用 date 指 令 來 取 得 所 需 要 的 檔 名 了 ;<br />

圱 圶 date1=‘date --date=’2 days ago’ +%Y%m%d‘<br />

date2=‘date --date=’1 days ago’ +%Y%m%d‘<br />

圱 圸 date3=‘date +%Y%m%d‘<br />

file1="$filename""$date1"<br />

圲 地 file2="$filename""$date2"<br />

file3="$filename""$date3"<br />

圲 圲<br />

# 4. 將 檔 名 建 立<br />

圲 圴 touch $file1<br />

touch $file2<br />

圲 圶 touch $file3<br />

✡✝<br />

✆<br />

• 數 值 運 算 的 方 法 : 使 用 者 輸 入 兩 個 變 數 , 將 兩 個 變 數 的 內 容 相 乘 , 並 輸 出 相<br />

乘 的 結 果 。<br />

✞<br />

[root@linux scripts]# vi sh05.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # User can input 2 integer to cross by!<br />

# History:<br />

圶 # 2005/08/23 csie First release<br />

圸 echo -e "You SHOULD input 2 number, I will cross they! \n"<br />

read -p "first number: " firstnu<br />

圱 地 read -p "second number: " secnu<br />

total=$(($firstnu*$secnu))<br />

圱 圲 echo -e "\nThe number $firstnu x $secnu is ==> $total"<br />

✡✝<br />

✆<br />

• 數 值 運 算 有 :+, -, *, /, % 等 。 其 中 % 是 取 餘 數 13 對 3 取 餘 數 , 例<br />

如 :<br />

De-Yu Wang CSIE CYUT 91


6.4. 善 用 判 斷 式 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

✞<br />

[root@linux scripts]# nu=$((13%3)); echo $nu<br />

圲 1<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 撰 寫 shell script, 如 何 以 read 指 令 , 讓 使 用 者 輸 入 變 數 var 的 內 容 ,<br />

且 提 示 Please input var: <br />

Sol. read -p "Please input var: " var<br />

2. 撰 寫 shell script, 如 何 以 echo 指 令 , 先 換 行 後 讓 變 數 var 的 內 容 顯 示<br />

在 螢 幕 上 , 且 提 示 var= <br />

Sol. echo -e "\nvar= " var<br />

3. 撰 寫 shell script, 如 何 讓 變 數 date1 的 內 容 為 昨 日 , 且 格 式 為<br />

yyyymmdd<br />

Sol. date1=‘date --date=’1 days ago’ +%Y%m%d‘<br />

4. 撰 寫 shell script, 如 何 讓 變 數 nu 的 內 容 為 變 數 nu1 與 nu2 相 乘 的 結<br />

果 <br />

Sol. nu=$(($nu1*$nu2))<br />

5. 撰 寫 shell script, 如 何 讓 變 數 nu 的 內 容 為 變 數 nu1 除 以 nu2 的 結<br />

果 <br />

Sol. nu=$(($nu1/$nu2))<br />

6. 撰 寫 shell script, 如 何 讓 變 數 nu 的 內 容 為 變 數 nu1 除 nu2 取 餘 數 的<br />

結 果 <br />

Sol. nu=$(($nu1%$nu2))<br />

6.4 善 用 判 斷 式<br />

• 利 用 test 指 令 的 測 試 功 能<br />

1. 指 令 test 測 試 的 標 誌<br />

測 試 的 標 誌<br />

代 表 意 義<br />

1. 關 於 某 個 檔 名 的 『 類 型 』 偵 測 ( 存 在 與 否 ), 如 test -e filename<br />

-e 該 『 檔 名 』 是 否 存 在 ( 常 用 )<br />

-f 該 『 檔 名 』 是 否 為 檔 案 (file)( 常 用 )<br />

-d 該 『 檔 名 』 是 否 為 目 錄 (directory)( 常 用 )<br />

-b 該 『 檔 名 』 是 否 為 一 個 block device 裝 置 <br />

-c 該 『 檔 名 』 是 否 為 一 個 character device 裝 置 <br />

-S 該 『 檔 名 』 是 否 為 一 個 Socket 檔 案 <br />

-p 該 『 檔 名 』 是 否 為 一 個 FIFO (pipe) 檔 案 <br />

-L 該 『 檔 名 』 是 否 為 一 個 連 結 檔 <br />

De-Yu Wang CSIE CYUT 92


6.4. 善 用 判 斷 式 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

2. 關 於 檔 案 的 權 限 偵 測 , 如 test -r filename<br />

-r 偵 測 該 檔 名 是 否 具 有 『 可 讀 』 的 屬 性 <br />

-w 偵 測 該 檔 名 是 否 具 有 『 可 寫 』 的 屬 性 <br />

-x 偵 測 該 檔 名 是 否 具 有 『 可 執 行 』 的 屬 性 <br />

-u 偵 測 該 檔 名 是 否 具 有 『SUID』 的 屬 性 <br />

-g 偵 測 該 檔 名 是 否 具 有 『SGID』 的 屬 性 <br />

-k 偵 測 該 檔 名 是 否 具 有 『Sticky bit』 的 屬 性 <br />

-s 偵 測 該 檔 名 是 否 為 『 非 空 白 檔 案 』<br />

3. 兩 個 檔 案 之 間 的 比 較 , 如 : test file1 -nt file2<br />

-nt<br />

(newer than) 判 斷 file1 是 否 比 file2 新<br />

-ot<br />

(older than) 判 斷 file1 是 否 比 file2 舊<br />

-ef 判 斷 file1 與 file2 是 否 為 同 一 檔 案 。<br />

4. 關 於 兩 個 整 數 之 間 的 判 定 , 例 如 test n1 -eq n2<br />

-eq<br />

兩 數 值 相 等 (equal)<br />

-ne<br />

兩 數 值 不 等 (not equal)<br />

-gt<br />

n1 大 於 n2 (greater than)<br />

-lt<br />

n1 小 於 n2 (less than)<br />

-ge<br />

n1 大 於 等 於 n2 (greater than or equal)<br />

-le<br />

n1 小 於 等 於 n2 (less than or equal)<br />

5. 判 定 字 串 的 資 料<br />

test -z string 判 定 字 串 是 否 為 0 若 string 為 空 字 串 , 則 為 true<br />

test -n string 判 定 字 串 是 否 非 為 0 若 string 為 空 字 串 , 則 為 false。<br />

test str1 = str2 判 定 str1 是 否 等 於 str2 , 若 相 等 回 傳 true<br />

test str1 != str2 判 定 str1 是 否 不 等 於 str2 , 若 相 等 回 傳 false<br />

6. 多 重 條 件 判 定 , 例 如 : test -r filename -a -x filename<br />

-a (and) 兩 狀 況 同 時 成 立 。 例 如 test -r file -a -x file,<br />

則 file 同 時 具 有 r 與 x 權 限 時 , 才 回 傳 true。<br />

-o (or) 兩 狀 況 任 何 一 個 成 立 。 例 如 test -r file -o -x file,<br />

則 file 具 有 r 或 x 權 限 時 , 就 可 回 傳 true。<br />

! 反 相 狀 態 , 如 test ! -x file , 當 file 不 具 有 x 時 , 回 傳 true<br />

2. 例 題 : 檢 查 /csie 是 否 存 在 :<br />

✞<br />

[root@linux ~]# test -e /csie && echo "exist" || echo "Not<br />

exist"<br />

✡✝<br />

✆<br />

3. 例 題 : 讓 使 用 者 輸 入 一 個 檔 名 , 並 判 斷 其 是 否 存 在 :<br />

(a) 若 不 存 在 則 給 予 一 個 『Filename does not exist』 的 訊 息 , 並 中<br />

斷 程 式 ;<br />

(b) 若 存 在 , 則 判 斷 是 檔 案 或 目 錄 , 並 果 輸 出 『Filename is regular<br />

file』 或 『Filename is directory』;<br />

(c) 判 斷 執 行 者 對 該 檔 案 或 目 錄 擁 有 的 權 限 , 並 輸 出 權 限 資 料 。<br />

✞<br />

De-Yu Wang CSIE CYUT 93


6.4. 善 用 判 斷 式 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

圱 [root@linux scripts]# vi sh06.sh<br />

#!/bin/bash<br />

圳 # Program:<br />

# Let user input a filename, the program will search<br />

the filename<br />

圵 # 1.) exist 2.) file/directory 3.) file permissions<br />

# History:<br />

圷 # 2005/08/25 csie First release<br />

圹 # 1. 讓 使 用 者 輸 入 檔 名 , 並 且 判 斷 使 用 者 是 否 真 的 有 輸 入 字 串 <br />

echo -e "The program will show you that filename<br />

圱 圱 is exist which input by you.\n\n"<br />

read -p "Input a filename : " filename<br />

圱 圳 test -z $filename && echo "You MUST input a filename." &&<br />

exit 0<br />

# 2. 判 斷 檔 案 是 否 存 在 <br />

圱 圵 test ! -e $filename && echo "The filename $filename DO NOT<br />

exist" && exit 0<br />

# 3. 開 始 判 斷 檔 案 類 型 與 屬 性<br />

圱 圷 test -f $filename && filetype="regulare file"<br />

test -d $filename && filetype="directory"<br />

圱 圹 test -r $filename && perm="readable"<br />

test -w $filename && perm="$perm writable"<br />

圲 圱 test -x $filename && perm="$perm executable"<br />

# 4. 開 始 輸 出 資 訊<br />

圲 圳 echo "The filename: $filename is a $filetype"<br />

echo "And the permission are : $perm"<br />

✡✝<br />

✆<br />

• 利 用 判 斷 符 號 [ ]<br />

1. 判 斷 變 數 $HOME 是 否 為 空 的 :<br />

✞<br />

[root@linux ~]# [ -z "$HOME" ]<br />

✡✝<br />

✆<br />

2. 在 中 括 號 [ ] 內 的 每 個 元 件 都 需 要 有 空 白 鍵 來 分 隔 ;<br />

✞<br />

圱 # 假 設 空 白 鍵 使 用 『□』 來 表 示 , 則 :<br />

[ "$HOME" == "$MAIL" ]□<br />

圳 ["$HOME"□□=="$MAIL"□]↑↑↑↑<br />

✡✝<br />

✆<br />

3. 在 中 括 號 內 , 變 數 要 以 雙 引 號 來 設 定 ; 常 數 要 以 單 或 雙 引 號 來 設 定 。<br />

✞<br />

# 設 定 name="csie Tsai" :<br />

圲 [root@linux ~]# name="csie Tsai"<br />

[root@linux ~]# [ $name == "csie" ]<br />

De-Yu Wang CSIE CYUT 94


6.4. 善 用 判 斷 式 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

圴<br />

bash: [: too many arguments<br />

圶 # 因 為 $name 沒 有 使 用 雙 引 號 刮 起 來 , 判 定 式 會 變 成 :<br />

[ csie Tsai == "csie" ]<br />

圸 # 而 不 是 :<br />

[ "csie Tsai" == "csie" ]<br />

✡✝<br />

✆<br />

4. 例 題 : 使 用 中 括 號 [ ]、&& 與 || 讓 使 用 者 選 擇 Y 或 N ,<br />

(a) 如 果 使 用 者 輸 入 Y 或 y 時 , 就 顯 示 『 OK, continue 』<br />

(b) 如 果 使 用 者 輸 入 n 或 N 時 , 就 顯 示 『 Oh, interrupt 。』<br />

(c) 如 果 不 是 Y/y/N/n 之 內 的 其 他 字 元 , 就 顯 示 『I don’t know what<br />

is your choise』<br />

✞<br />

圱 [root@linux scripts]# vi sh07.sh<br />

#!/bin/bash<br />

圳 # Program:<br />

# This program will show the user’s choice<br />

圵 # History:<br />

# 2005/08/25 csie First release<br />

圷<br />

read -p "Please input (Y/N): " yn<br />

圹 [ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" &&<br />

exit 0<br />

[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" &&<br />

exit 0<br />

圱 圱 echo "I don’t know what is your choise" && exit 0<br />

✡✝<br />

✆<br />

• Shell script 的 預 設 變 數 ($0, $1, ...)<br />

1. 變 數 的 對 應 :<br />

✞<br />

圱 /path/to/scriptname opt1 opt2 opt3 opt4 ...<br />

$0 $1 $2 $3 $4 ...<br />

圳<br />

[root@linux ~]# /etc/init.d/crond restart<br />

圵 ## $0 為 /etc/init.d/,crond $1 為 restart<br />

✡✝<br />

✆<br />

2. 例 題 : 執 行 一 個 script , 自 動 列 出 自 己 的 檔 名 , 後 面 接 前 三 個 參 數 :<br />

✞<br />

圱 [root@linux scripts]# vi sh08.sh<br />

#!/bin/bash<br />

圳 # Program:<br />

# The program will show it’s name and first 3<br />

parameters.<br />

De-Yu Wang CSIE CYUT 95


6.4. 善 用 判 斷 式 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

圵 # History:<br />

# 2005/08/25 csie First release<br />

圷<br />

echo "The script name is ==> $0"<br />

圹 [ -n "$1" ] && echo "The 1st paramter is ==> $1" || exit 0<br />

[ -n "$2" ] && echo "The 2nd paramter is ==> $2" || exit 0<br />

圱 圱 [ -n "$3" ] && echo "The 3th paramter is ==> $3" || exit 0<br />

圱 圳 # 執 行 結 果 :<br />

[root@linux scripts]# sh sh08.sh theone haha quot<br />

圱 圵 The script name is ==> sh08.sh<br />

The 1st paramter is ==> theone<br />

圱 圷 The 2nd paramter is ==> haha<br />

The 3th paramter is ==> quot<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 如 何 利 用 test 指 令 檢 查 檔 名 filename 是 否 存 在 <br />

Sol. test -e filename<br />

2. 如 何 利 用 test 指 令 檢 查 檔 名 filename 是 否 為 檔 案 <br />

Sol. test -f filename<br />

3. 如 何 利 用 test 指 令 檢 查 檔 名 filename 是 否 為 目 錄 <br />

Sol. test -d filename<br />

4. 如 何 利 用 test 指 令 檢 查 檔 名 filename 是 否 為 連 結 檔 <br />

Sol. test -L filename<br />

5. 如 何 利 用 test 指 令 檢 查 檔 名 filename 是 否 具 有 『 可 讀 』 的 屬 性 <br />

Sol. test -r filename<br />

6. 如 何 利 用 test 指 令 檢 查 檔 名 filename 是 否 具 有 『 可 寫 』 的 屬 性 <br />

Sol. test -w filename<br />

7. 如 何 利 用 test 指 令 檢 查 檔 名 filename 是 否 具 有 『 可 執 行 』 的 屬 性 <br />

Sol. test -x filename<br />

8. 如 何 利 用 test 指 令 比 較 檔 案 file1 是 否 比 file2 新 <br />

Sol. test file1 -nt file2<br />

9. 如 何 利 用 test 指 令 比 較 檔 案 file1 是 否 比 file2 舊 <br />

Sol. test file1 -ot file2<br />

10. 如 何 利 用 test 指 令 判 斷 file1 與 file2 是 否 為 同 一 檔 案 <br />

Sol. test file1 -of file2<br />

11. 如 何 利 用 test 指 令 比 較 兩 個 整 數 n1 與 n2 是 否 相 等 <br />

Sol. test n1 -eq n2<br />

De-Yu Wang CSIE CYUT 96


6.4. 善 用 判 斷 式 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

12. 如 何 利 用 test 指 令 比 較 兩 個 整 數 n1 與 n2 是 否 不 相 等 <br />

Sol. test n1 -ne n2<br />

13. 如 何 利 用 test 指 令 比 較 整 數 n1 是 否 大 於 n2<br />

Sol. test n1 -gt n2<br />

14. 如 何 利 用 test 指 令 比 較 整 數 n1 是 否 小 於 n2<br />

Sol. test n1 -lt n2<br />

15. 如 何 利 用 test 指 令 比 較 整 數 n1 是 否 大 於 等 於 n2<br />

Sol. test n1 -ge n2<br />

16. 如 何 利 用 test 指 令 判 定 字 串 str1 是 否 為 空 字 串 <br />

Sol. test -z str1<br />

17. 如 何 利 用 test 指 令 判 定 字 串 str1 是 否 非 為 空 字 串 <br />

Sol. test -n str1 或 test str1<br />

18. 如 何 利 用 test 指 令 判 定 字 串 str1 是 否 等 於 str2<br />

Sol. test str1 = str2<br />

19. 如 何 利 用 test 指 令 判 定 字 串 str1 是 否 不 等 於 str2<br />

Sol. test str1 != str2<br />

20. 如 何 利 用 test 指 令 判 斷 檔 案 file1 是 否 為 具 有 『 可 讀 』 且 『 可 執 行 』 的<br />

屬 性 <br />

Sol. test -r file1 -a -x file1<br />

21. 如 何 利 用 test 指 令 判 斷 檔 案 file1 是 否 為 具 有 『 可 讀 』 或 『 可 執 行 』 的<br />

屬 性 <br />

Sol. test -r file1 -o -x file1<br />

22. 如 何 利 用 test 指 令 判 斷 檔 案 file1 是 否 為 不 具 有 『 可 執 行 』 的 屬 性 <br />

Sol. test ! -x file1<br />

23. 如 何 利 用 判 斷 符 號 [ ], 判 斷 變 數 $HOME 是 否 為 空 的 <br />

Sol. [ -z "$HOME" ]<br />

24. 指 令 ["$HOME"=="$MAIL"], 判 斷 變 數 $HOME 是 否 等 於 變 數 $MAIL, 是 否 有<br />

錯 , 若 有 , 請 說 明 。<br />

Sol. 有 錯 , 在 中 括 號 [ ] 內 的 每 個 元 件 都 需 要 有 空 白 鍵 來 分 隔 。<br />

25. 指 令 [ $name == "csie" ], 判 斷 變 數 $name 是 否 等 於 字 串 csie, 是 否 有<br />

錯 , 若 有 , 請 說 明 。<br />

Sol. 有 錯 , 在 中 括 號 [ ] 內 的 $name 沒 有 使 用 雙 引 號 刮 起 來 。<br />

26. 執 行 shell script 『sh sh07.sh theone haha quot』, 則 預 設 變 數 $0,<br />

$1, $2, $3 分 別 為 何 <br />

Sol. $0="sh07.sh",$1="theone",$2="haha",$3="quot"。<br />

De-Yu Wang CSIE CYUT 97


6.4. 善 用 判 斷 式 CHAPTER 6. SHELL SCRIPTS – 簡 介 與 TEST 功 能<br />

De-Yu Wang CSIE CYUT 98


CHAPTER 7.<br />

SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

Chapter 7<br />

Shell scripts – 條 件 判 斷 與 迴 圈<br />

7.1 條 件 判 斷 式<br />

• if .... then: 當 符 合 條 件 判 斷 時 , 就 進 行 某 項 工 作 。<br />

1. 語 法 一 :<br />

圲<br />

✞<br />

if [ 條 件 判 斷 式 ]; then 當 條 件 判 斷 式 成 立 時 , 可 以 進 行 的 指 令 工 作 內<br />

容 ;<br />

fi<br />

✡✝<br />

✆<br />

2. 條 件 判 斷 式 的 判 斷 方 法 :<br />

✞<br />

圱 && 代 表 ; AND<br />

|| 代 表 ; OR<br />

圳<br />

[root@linux scripts]# vi sh06-2.sh<br />

圵 #!/bin/bash<br />

# Program:<br />

圷 # This program will show the user’s choice<br />

# History:<br />

圹 # 2005/08/25 csie First release<br />

圱 圱<br />

read -p "Please input (Y/N): " yn<br />

圱 圳 if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then<br />

echo "OK, continue"<br />

圱 圵 exit 0<br />

圱 圷<br />

fi<br />

if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then<br />

echo "Oh, interrupt!"<br />

圱 圹 exit 0<br />

fi<br />

圲 圱 echo "I don’t know what is your choise" && exit 0<br />

De-Yu Wang CSIE CYUT 99


7.1. 條 件 判 斷 式 CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

✡✝<br />

✆<br />

3. 語 法 二 :<br />

✞<br />

圱 if [ 條 件 判 斷 式 ]; then 當 條 件 判 斷 式 成 立 時 , 可 以 進 行 的 指 令 工 作 內<br />

容 ;<br />

圳 else 當 條 件 判 斷 式 不 成 立 時 , 可 以 進 行 的 指 令 工 作 內 容 ;<br />

圵<br />

fi<br />

✡✝<br />

✆<br />

4. 語 法 三 :<br />

✞<br />

圱 if [ 條 件 判 斷 式 一 ]; then 當 條 件 判 斷 式 一 成 立 時 , 可 以 進 行 的 指 令 工<br />

作 內 容 ;<br />

圳<br />

elif [ 條 件 判 斷 式 二 ]; then 當 條 件 判 斷 式 二 成 立 時 , 可 以 進 行 的 指 令<br />

工 作 內 容 ;<br />

圵 else 當 條 件 判 斷 式 一 與 二 均 不 成 立 時 , 可 以 進 行 的 指 令 工 作 內 容 ;<br />

圷<br />

fi<br />

✡✝<br />

✆<br />

5. 例 題 : 改 寫 sh06-2.sh:<br />

✞<br />

圱 [root@linux scripts]# vi sh06-3.sh<br />

#!/bin/bash<br />

圳 # Program:<br />

# This program will show the user’s choice<br />

圵 # History:<br />

# 2005/08/25 csie First release<br />

圷<br />

read -p "Please input (Y/N): " yn<br />

圹<br />

if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then<br />

圱 圱<br />

echo "OK, continue"<br />

elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then<br />

圱 圳<br />

echo "Oh, interrupt!"<br />

else<br />

圱 圵<br />

echo "I don’t know what is your choise"<br />

fi<br />

✡✝<br />

✆<br />

6. 例 題 : 偵 測 輸 入 的 參 數 是 否 為 hello。<br />

(a) 如 果 是 , 顯 示 "Hello, how are you ";<br />

De-Yu Wang CSIE CYUT 100


7.1. 條 件 判 斷 式 CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

(b) 如 果 沒 有 加 任 何 參 數 , 提 示 使 用 者 必 須 要 使 用 的 參 數 下 達 法 ;<br />

(c) 而 如 果 加 入 的 參 數 不 是 hello , 就 提 醒 使 用 者 僅 能 使 用 hello 為<br />

參 數 。<br />

✞<br />

[root@linux scripts]# vi sh08.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # Show "Hello" from $1....<br />

# History:<br />

圶 # 2005/08/28 csie First release<br />

圸 if [ "$1" == "hello" ]; then<br />

echo "Hello, how are you "<br />

圱 地 elif [ "$1" == "" ]; then<br />

echo "You MUST input parameters, ex> $0 someword"<br />

圱 圲 else<br />

echo "The only parameter is ’hello’"<br />

圱 圴 fi<br />

✡✝<br />

✆<br />

7. 利 用 『 netstat -tuln 』 可 取 得 目 前 主 機 啟 動 的 服 務 , 其 中 Local<br />

Address 冒 號 ( : ) 後 為 port。<br />

✞<br />

[root@linux ~]# netstat -tuln<br />

圲 Active Internet connections (only servers)<br />

Proto Recv-Q Send-Q Local Address Foreign Address State<br />

圴 tcp 0 0 0.0.0.0:199 0.0.0.0:* LISTEN<br />

tcp 0 0 :::80 :::* LISTEN<br />

圶 tcp 0 0 :::22 :::* LISTEN<br />

tcp 0 0 :::25 :::* LISTEN<br />

圸<br />

# 常 見 的 port 與 相 關 網 路 服 務 的 關 係 :<br />

圱 地 80: WWW<br />

22: ssh<br />

圱 圲 21: ftp<br />

25: mail<br />

圱 圴<br />

# netstat [address_family_options] [--tcp|-t] [--udp|-u]<br />

圱 圶 [--raw|-w] [--listening|-l] [--all|-a] [--numeric|-n]<br />

[--numeric-hosts][--numeric- ports][--numeric-ports]<br />

圱 圸 [--symbolic|-N] [--extend|-e[--extend|-e]] [--timers|-o]<br />

[--program|-p] [--verbose|-v] [--continuous|-c] [delay]<br />

✡✝<br />

✆<br />

8. 例 題 : 如 何 透 過 netstat 偵 測 主 機 是 否 有 開 啟 80: WWW, 22: ssh,<br />

21: ftp, 25: mail 四 個 主 要 的 網 路 服 務 埠 口 <br />

✞<br />

圱 [root@linux scripts]# vi sh09.sh<br />

De-Yu Wang CSIE CYUT 101


7.1. 條 件 判 斷 式 CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

圳<br />

圵<br />

圷<br />

#!/bin/bash<br />

# Program:<br />

# Using netstat and grep to detect WWW,SSH,FTP and Mail<br />

services.<br />

# History:<br />

# 2005/08/28 csie First release<br />

# 1. 先 作 一 些 告 知 的 動 作<br />

圹 echo "Now, the services of your <strong>Linux</strong> system will be detect!"<br />

echo -e "The www, ftp, ssh, and mail will be detect! \n"<br />

圱 圱<br />

# 2. 開 始 進 行 一 些 測 試 的 工 作 , 並 且 也 輸 出 一 些 資 訊 。<br />

圱 圳 testing=‘netstat -tuln | grep ":80 "‘<br />

if [ "$testing" != "" ]; then<br />

圱 圵<br />

echo "WWW is running in your system."<br />

fi<br />

圱 圷 testing=‘netstat -tuln | grep ":22 "‘<br />

if [ "$testing" != "" ]; then<br />

圱 圹<br />

echo "SSH is running in your system."<br />

fi<br />

圲 圱 testing=‘netstat -tuln | grep ":21 "‘<br />

if [ "$testing" != "" ]; then<br />

圲 圳<br />

echo "FTP is running in your system."<br />

fi<br />

圲 圵 testing=‘netstat -tuln | grep ":25 "‘<br />

if [ "$testing" != "" ]; then<br />

圲 圷<br />

fi<br />

✡✝<br />

echo "Mail is running in your system."<br />

✆<br />

9. 例 題 : 計 算 畢 業 日 期 還 剩 幾 天 <br />

(a) 先 讓 使 用 者 輸 入 他 們 的 畢 業 日 期 ;<br />

(b) 再 由 現 在 日 期 比 對 畢 業 日 期 ;<br />

(c) 由 兩 個 日 期 的 比 較 來 顯 示 『 還 需 要 幾 天 』 才 能 夠 畢 業 的 字 樣 。<br />

✞<br />

[root@linux scripts]# vi sh10.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # Tring to calculate your graduation date at how many<br />

days<br />

# later...<br />

圶 # History:<br />

# 2005/08/29 csie First release<br />

圸<br />

# 1. 告 知 使 用 者 這 支 程 式 的 用 途 , 並 且 告 知 應 該 如 何 輸 入 日 期 格 式 <br />

圱 地 echo "This program will try to calculate :"<br />

echo "How many days about your graduation date..."<br />

圱 圲 read -p "Please input your graduation date (YYYYMMDD ex<br />

>20050401): " date2<br />

De-Yu Wang CSIE CYUT 102


7.1. 條 件 判 斷 式 CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

圱 圴 # 2. 測 試 輸 入 的 內 容 是 否 正 確 利 用 正 規 表 示 法<br />

date_d=‘echo $date2 |grep ’[0-9]\{8\}’‘<br />

圱 圶 if [ "$date_d" == "" ]; then<br />

echo "You input the wrong format of date...."<br />

圱 圸 exit 1<br />

fi<br />

圲 地<br />

# 3. 開 始 計 算 日 期<br />

圲 圲 declare -i date_dem=‘date --date="$date2" +%s‘<br />

declare -i date_now=‘date +%s‘<br />

圲 圴 declare -i date_total_s=$(($date_dem-$date_now))<br />

declare -i date_d=$(($date_total_s/60/60/24))<br />

圲 圶 if [ "$date_total_s" -lt "0" ]; then<br />

echo "You had been graduation before: " $((-1*$date_d<br />

)) " ago"<br />

圲 圸 else<br />

declare -i date_h=$(($(($date_total_s-$date_d<br />

圳 地<br />

fi<br />

✡✝<br />

*60*60*24))/60/60))<br />

echo "You will be demobilized after $date_d days and<br />

$date_h hours."<br />

✆<br />

• case .....<br />

esac 判 斷<br />

1. 語 法 :<br />

✞<br />

圱 case 變 數 名 稱 $ in<br />

" 第 一 個 變 數 內 容 ") 程 式 段<br />

圳<br />

;; # 兩 個 分 號 ## (;;) 來 代 表 該 程 式 段 落 的 結 束<br />

圵 " 第 二 個 變 數 內 容 ") 程 式 段<br />

圷 ;;<br />

*) 不 包 含 第 一 個 變 數 內 容 與 第 二 個 變 數 內 容 的 其 他 程 式 執 行 段<br />

圹<br />

exit 1<br />

圱 圱 ;;<br />

esac<br />

✡✝<br />

✆<br />

2. 改 寫 sh08.sh<br />

✞<br />

[root@linux scripts]# vi sh08-2.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # Show "Hello" from $1.... by using case .... esac<br />

# History:<br />

De-Yu Wang CSIE CYUT 103


7.1. 條 件 判 斷 式 CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

圶 # 2005/08/29 csie First release<br />

圸 case $1 in<br />

"hello")<br />

圱 地 echo "Hello, how are you "<br />

;;<br />

圱 圲 "")<br />

echo "You MUST input parameters, ex> $0 someword"<br />

圱 圴 ;;<br />

圱 圶<br />

圱 圸<br />

*)<br />

esac<br />

✡✝<br />

echo "Usage $0 {hello}"<br />

;;<br />

✆<br />

3. 例 題 : 讓 使 用 者 能 夠 輸 入 one, two, three, 並 且 將 使 用 者 的 變 數 顯 示<br />

到 螢 幕 上 , 如 果 不 是 one, two, three 時 , 就 告 知 使 用 者 僅 有 這 三 種<br />

選 擇 。<br />

✞<br />

[root@linux scripts]# vi sh11.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # Let user input one, two, three and show in screen.<br />

# History:<br />

圶 # 2005/08/29 csie First release<br />

圸 echo "This program will print your selection !"<br />

# read -p "Input your choice: " choice<br />

圱 地 # case $choice in<br />

case $1 in<br />

圱 圲 "one")<br />

echo "Your choice is ONE"<br />

圱 圴 ;;<br />

"two")<br />

圱 圶<br />

echo "Your choice is TWO"<br />

;;<br />

圱 圸 "three")<br />

echo "Your choice is THREE"<br />

圲 地 ;;<br />

*)<br />

圲 圲<br />

echo "Usage {one|two|three}"<br />

;;<br />

圲 圴 esac<br />

✡✝<br />

✆<br />

• 利 用 function 功 能<br />

1. 語 法 :<br />

De-Yu Wang CSIE CYUT 104


7.1. 條 件 判 斷 式 CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

圲<br />

✞<br />

function fname() { 程 式 段<br />

}<br />

✡✝<br />

✆<br />

2. 在 shell script 中 ,function 的 設 定 一 定 要 在 程 式 的 最 前 面 , 才 能<br />

在 執 行 時 被 找 到 可 用 的 程 式 。 改 寫 sh11.sh:<br />

✞<br />

圱 [root@linux scripts]# vi sh11-2.sh<br />

#!/bin/bash<br />

圳 # Program:<br />

# Let user input one, two, three and show in screen.<br />

圵 # History:<br />

# 2005/08/29 csie First release<br />

圷<br />

function printit(){<br />

圹 echo -n "Your choice is "<br />

}<br />

圱 圱<br />

echo "This program will print your selection !"<br />

圱 圳 case $1 in<br />

"one")<br />

圱 圵<br />

printit; echo $1 | tr ’a-z’ ’A-Z’<br />

;;<br />

圱 圷 "two")<br />

printit; echo $1 | tr ’a-z’ ’A-Z’<br />

圱 圹 ;;<br />

"three")<br />

圲 圱<br />

printit; echo $1 | tr ’a-z’ ’A-Z’<br />

;;<br />

圲 圳 *)<br />

echo "Usage {one|two|three}"<br />

圲 圵 ;;<br />

esac<br />

✡✝<br />

✆<br />

3. function 也 擁 有 內 建 變 數 :$0 代 表 函 式 名 稱 , 後 續 接 的 變 數 以<br />

$1, $2,... 取 代 。 改 寫 上 例 :<br />

✞<br />

[root@linux scripts]# vi sh11-3.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # Let user input one, two, three and show in screen.<br />

# History:<br />

圶 # 2005/08/29 csie First release<br />

圸<br />

function printit(){<br />

echo "Your choice is $1"<br />

De-Yu Wang CSIE CYUT 105


7.1. 條 件 判 斷 式 CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

圱 地 }<br />

圱 圲 echo "This program will print your selection !"<br />

case $1 in<br />

圱 圴 "one")<br />

printit 1<br />

圱 圶 ;;<br />

"two")<br />

圱 圸 printit 2<br />

;;<br />

圲 地 "three")<br />

printit 3<br />

圲 圲 ;;<br />

圲 圴<br />

圲 圶<br />

*)<br />

esac<br />

✡✝<br />

echo "Usage {one|two|three}"<br />

;;<br />

✆<br />

練 習 題<br />

1. 使 用 if 語 法 , 撰 寫 一 shell script, 偵 測 輸 入 的 參 數 是 否 為 hello。 如<br />

果 是 , 顯 示 "Hello, how are you "; 如 果 沒 有 加 任 何 參 數 , 提 示 使 用 者<br />

必 須 要 使 用 的 參 數 下 達 法 ; 而 如 果 加 入 的 參 數 不 是 hello , 就 提 醒 使 用 者 僅<br />

能 使 用 hello 為 參 數 。<br />

Sol.<br />

if [ "$1" == "hello" ]; then<br />

echo "Hello, how are you "<br />

elif [ "$1" == "" ]; then<br />

echo "You MUST input parameters, ex> $0 someword"<br />

else<br />

echo "The only parameter is ’hello’"<br />

fi<br />

2. 使 用 case 語 法 , 撰 寫 一 shell script, 偵 測 輸 入 的 參 數 是 否 為 hello。<br />

如 果 是 , 顯 示 "Hello, how are you "; 如 果 沒 有 加 任 何 參 數 , 提 示 使 用<br />

者 必 須 要 使 用 的 參 數 下 達 法 ; 而 如 果 加 入 的 參 數 不 是 hello , 就 提 醒 使 用 者<br />

僅 能 使 用 hello 為 參 數 。<br />

Sol.<br />

case $1 in<br />

"hello")<br />

echo "Hello, how are you "<br />

;;<br />

"")<br />

echo "You MUST input parameters, ex> $0 someword"<br />

;;<br />

*)<br />

echo "Usage $0 {hello}"<br />

;;<br />

esac<br />

De-Yu Wang CSIE CYUT 106


7.1. 條 件 判 斷 式 CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

3. 撰 寫 一 shell script, 透 過 netstat 偵 測 主 機 是 否 有 開 啟 ftp 網 路 服<br />

務 , 其 埠 口 為 21。<br />

Sol.<br />

testing=‘netstat -tuln | grep ":21 "‘<br />

if [ "$testing" != "" ]; then<br />

echo "FTP is running in your system."<br />

fi<br />

4. 撰 寫 一 shell script, 讓 使 用 者 輸 入 畢 業 日 期 ; 再 由 現 在 日 期 比 對 畢 業 日<br />

期 ; 由 兩 個 日 期 的 比 較 來 顯 示 『 還 需 要 幾 天 』 才 能 夠 畢 業 的 字 樣 。<br />

Sol.<br />

read -p "Please input your graduation date (YYYYMMDD ex>20050401): " date2<br />

date_d=‘echo $date2 |grep ’[0-9]\{8\}’‘<br />

if [ "$date_d" == "" ]; then<br />

echo "You input the wrong format of date...."<br />

exit 1<br />

fi<br />

declare -i date_dem=‘date --date="$date2" +%s‘<br />

declare -i date_now=‘date +%s‘<br />

declare -i date_total_s=$(($date_dem-$date_now))<br />

declare -i date_d=$(($date_total_s/60/60/24))<br />

if [ "$date_total_s" -lt "0" ]; then<br />

echo "You had been graduation before: " $((-1*$date_d)) " ago"<br />

else<br />

declare -i date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60))<br />

echo "You will be demobilized after $date_d days and $date_h hours."<br />

fi<br />

5. 使 用 case 語 法 , 撰 寫 一 shell script, 讓 使 用 者 能 夠 輸 入 one, two,<br />

three, 並 且 將 使 用 者 的 變 數 顯 示 到 螢 幕 上 , 如 果 不 是 one, two, three<br />

時 , 就 告 知 使 用 者 僅 有 這 三 種 選 擇 。<br />

Sol.<br />

case $1 in<br />

"one")<br />

echo "Your choice is ONE"<br />

;;<br />

"two")<br />

echo "Your choice is TWO"<br />

;;<br />

"three")<br />

echo "Your choice is THREE"<br />

;;<br />

*)<br />

echo "Usage {one|two|three}"<br />

;;<br />

esac<br />

De-Yu Wang CSIE CYUT 107


7.2. 迴 圈 (LOOP) CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

6. 使 用 function 功 能 及 case 語 法 , 撰 寫 一 shell script, 讓 使 用 者 能 夠<br />

輸 入 one, two, three, 並 且 將 使 用 者 的 變 數 顯 示 到 螢 幕 上 , 如 果 不 是<br />

one, two, three 時 , 就 告 知 使 用 者 僅 有 這 三 種 選 擇 。<br />

Sol.<br />

function printit(){<br />

echo -n "Your choice is "<br />

}<br />

case $1 in<br />

"one")<br />

printit; echo $1 | tr ’a-z’ ’A-Z’<br />

;;<br />

"two")<br />

printit; echo $1 | tr ’a-z’ ’A-Z’<br />

;;<br />

"three")<br />

printit; echo $1 | tr ’a-z’ ’A-Z’<br />

;;<br />

*)<br />

echo "Usage {one|two|three}"<br />

;;<br />

esac<br />

7. 使 用 function 與 變 數 $1 功 能 及 case 語 法 , 撰 寫 一 shell script, 讓<br />

使 用 者 能 夠 輸 入 one, two, three, 並 且 將 使 用 者 的 變 數 顯 示 到 螢 幕 上 , 如<br />

果 不 是 one, two, three 時 , 就 告 知 使 用 者 僅 有 這 三 種 選 擇 。<br />

Sol.<br />

function printit(){<br />

echo "Your choice is $1"<br />

}<br />

case $1 in<br />

"one")<br />

printit 1<br />

;;<br />

"two")<br />

printit 2<br />

;;<br />

"three")<br />

printit 3<br />

;;<br />

*)<br />

echo "Usage {one|two|three}"<br />

;;<br />

esac<br />

7.2 迴 圈 (loop)<br />

• while....do....done, until....do....done<br />

De-Yu Wang CSIE CYUT 108


7.2. 迴 圈 (LOOP) CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

1. 語 法 一 : 當 condition 條 件 成 立 時 , 進 行 迴 圈 , 直 到 condition 條 件<br />

不 成 立 才 停 止 。<br />

✞<br />

while [ condition ]<br />

圲 do 程 式 段 落<br />

圴<br />

done<br />

✡✝<br />

✆<br />

2. 語 法 二 : 當 condition 條 件 成 立 時 , 終 止 迴 圈 , 否 則 持 續 進 行 迴 圈 的<br />

程 式 段 。<br />

✞<br />

until [ condition ]<br />

圲 do 程 式 段 落<br />

圴<br />

done<br />

✡✝<br />

✆<br />

3. 例 題 : 使 用 while 語 法 , 讓 使 用 者 輸 入 yes 或 者 是 YES 才 結 束 程 式<br />

的 執 行 , 否 則 就 一 直 進 行 告 知 使 用 者 輸 入 字 串 。<br />

✞<br />

[root@linux scripts]# vi sh12.sh<br />

圲 #!/bin/bash<br />

# Program:<br />

圴 # Use loop to try find your input.<br />

# History:<br />

圶 # 2005/08/29 csie First release<br />

圸 while [ "$yn" != "yes" ] && [ "$yn" != "YES" ]<br />

do<br />

圱 地 read -p "Please input yes/YES to stop this program: "<br />

yn<br />

done<br />

✡✝<br />

✆<br />

4. 例 題 : 使 用 until 語 法 , 讓 使 用 者 輸 入 yes 或 者 是 YES 才 結 束 程 式<br />

的 執 行 , 否 則 就 一 直 進 行 告 知 使 用 者 輸 入 字 串 。<br />

✞<br />

圱 [root@linux scripts]# vi sh12-2.sh<br />

#!/bin/bash<br />

圳 # Program:<br />

# Use loop to try find your input.<br />

圵 # History:<br />

# 2005/08/29 csie First release<br />

圷<br />

until [ "$yn" == "yes" ] || [ "$yn" == "YES" ]<br />

圹 do<br />

De-Yu Wang CSIE CYUT 109


7.2. 迴 圈 (LOOP) CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

圱 圱<br />

done<br />

✡✝<br />

read -p "Please input yes/YES to stop this program: "<br />

yn<br />

✆<br />

5. 例 題 : 計 算 1+2+3+....+100:<br />

✞<br />

圱 [root@linux scripts]# vi sh13.sh<br />

#!/bin/bash<br />

圳 # Program:<br />

# Try to use loop to calculate the result<br />

"1+2+3...+100"<br />

圵 # History:<br />

# 2005/08/29 csie First release<br />

圷<br />

s=0<br />

圹 i=0<br />

while [ "$i" != "100" ]<br />

圱 圱 do<br />

i=$(($i+1))<br />

圱 圳<br />

s=$(($s+$i))<br />

done<br />

圱 圵 echo "The result of ’1+2+3+...+100’ is ==> $s"<br />

✡✝<br />

✆<br />

• 已 知 進 行 迴 圈 次 數 :for...do...done<br />

1. 語 法 :<br />

✞<br />

圱 for (( 初 始 值 ; 限 制 值 ; 執 行 步 階 ))<br />

do 程 式 段<br />

圳<br />

done<br />

✡✝<br />

✆<br />

2. for 括 號 內 的 三 串 內 容 意 義 為 :<br />

(a) 初 始 值 : 某 個 變 數 在 迴 圈 當 中 的 起 始 值 , 直 接 以 類 似 i=1 設 定 ;<br />

(b) 限 制 值 : 當 變 數 的 值 在 這 個 限 制 值 的 範 圍 內 , 就 繼 續 進 行 迴 圈 。 例<br />

如 i


7.2. 迴 圈 (LOOP) CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

# History:<br />

圶 # 2005/08/29 csie First release<br />

圸 s=0<br />

for (( i=1; i


7.2. 迴 圈 (LOOP) CHAPTER 7. SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

圷<br />

圹<br />

圱 圱<br />

圱 圳<br />

# 2005/08/29 csie First release<br />

# 1. 先 看 目 錄 是 否 存 在 <br />

read -p "Please input a directory: " dir<br />

if [ "$dir" == "" ] || [ ! -d "$dir" ]; then<br />

echo "The $dir is NOT exist in your system."<br />

exit 1<br />

fi<br />

圱 圵 # 2. 開 始 測 試 檔 案<br />

filelist=‘ls $dir‘<br />

圱 圷 for filename in $filelist<br />

do<br />

圱 圹<br />

perm=""<br />

test -r "$dir/$filename" && perm="$perm readable"<br />

圲 圱<br />

test -w "$dir/$filename" && perm="$perm writable"<br />

test -x "$dir/$filename" && perm="$perm executable"<br />

圲 圳 echo "The file $dir/$filename’s permission is $perm "<br />

done<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 使 用 while 語 法 , 撰 寫 一 shell script, 讓 使 用 者 輸 入 yes 或 者 是 YES<br />

才 結 束 程 式 的 執 行 , 否 則 就 一 直 進 行 告 知 使 用 者 輸 入 字 串 。<br />

Sol.<br />

while [ "$yn" != "yes" ] && [ "$yn" != "YES" ]<br />

do<br />

read -p "Please input yes/YES to stop this program: " yn<br />

done<br />

2. 使 用 until 語 法 , 撰 寫 一 shell script, 讓 使 用 者 輸 入 yes 或 者 是 YES<br />

才 結 束 程 式 的 執 行 , 否 則 就 一 直 進 行 告 知 使 用 者 輸 入 字 串 。<br />

Sol.<br />

until [ "$yn" == "yes" ] || [ "$yn" == "YES" ]<br />

do<br />

read -p "Please input yes/YES to stop this program: " yn<br />

done<br />

3. 使 用 while 語 法 , 撰 寫 一 shell script, 計 算 1 累 加 到 100。<br />

Sol.<br />

s=0<br />

i=0<br />

while [ "$i" != "100" ]<br />

do<br />

i=$(($i+1))<br />

s=$(($s+$i))<br />

done<br />

echo "The result of ’1+2+3+...+100’ is ==> $s"<br />

De-Yu Wang CSIE CYUT 112


7.3. SHELL SCRIPT 的 追 蹤 與 CHAPTER DEBUG 7.<br />

SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

4. 使 用 for 語 法 , 撰 寫 一 shell script, 計 算 1 累 加 到 100。<br />

Sol.<br />

s=0<br />

for (( i=1; i


7.3. SHELL SCRIPT 的 追 蹤 與 CHAPTER DEBUG 7.<br />

SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

2. 測 試 sh16.sh 有 無 語 法 的 問 題 <br />

✞<br />

圱 [root@linux ~]# sh -n sh16.sh<br />

# 若 語 法 沒 有 問 題 , 則 不 會 顯 示 任 何 資 訊 。<br />

圳<br />

[dywang@dywOffice ~]$ vi sh015.sh<br />

圵 1 #!/bin/bash<br />

2 # Program:<br />

圷 3 # Using for .... loop to print 3 animal<br />

4 # History:<br />

圹 5 # 2005/08/29 csie First release<br />

6 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/<br />

local/sbin:~/bin<br />

圱 圱 7 export PATH<br />

8<br />

圱 圳 9 for animal in dog cat elephant<br />

10 do<br />

圱 圵 11 echo "There are ""$animal""s....<br />

12 done<br />

圱 圷 [dywang@dywOffice ~]$ sh -n sh015.sh<br />

sh015.sh: line 11: unexpected EOF while looking for matching<br />

‘"’<br />

圱 圹 sh015.sh: line 13: syntax error: unexpected end of file<br />

✡✝<br />

✆<br />

3. 執 行 sh15.sh 前 , 先 將 scripts 的 內 容 輸 出 到 螢 幕 上 。<br />

✞<br />

圱 [dywang@dywOffice ~]$ sh -v sh015.sh<br />

#!/bin/bash<br />

圳 # Program:<br />

# Using for .... loop to print 3 animal<br />

圵 # History:<br />

# 2005/08/29 csie First release<br />

圷<br />

for animal in dog cat elephant<br />

圹 do<br />

echo "There are ""$animal""s...."<br />

圱 圱 done<br />

There are dogs....<br />

圱 圳 There are cats....<br />

There are elephants....<br />

✡✝<br />

✆<br />

4. 將 sh15.sh 的 執 行 過 程 全 部 列 出 來<br />

✞<br />

[root@linux ~]# sh -x sh15.sh<br />

圲 + PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/<br />

local/sbin:/home/csie/bin<br />

+ export PATH<br />

De-Yu Wang CSIE CYUT 114


7.3. SHELL SCRIPT 的 追 蹤 與 CHAPTER DEBUG 7.<br />

SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

圴 + for animal in dog cat elephant<br />

+ echo ’There are dogs.... ’<br />

圶 There are dogs....<br />

+ for animal in dog cat elephant<br />

圸 + echo ’There are cats.... ’<br />

There are cats....<br />

圱 地 + for animal in dog cat elephant<br />

+ echo ’There are elephants.... ’<br />

圱 圲 There are elephants....<br />

圱 圴 # 最 前 面 會 加 上 + 字 號 表 示 程 式 段 落 。<br />

✡✝<br />

✆<br />

• <strong>Linux</strong> 系 統 有 很 多 啟 動 的 script, 想 要 知 道 每 個 script 的 功 能 , 可 以 直<br />

接 以 cat, more, less 或 vi 進 入 該 script 查 閱 。 例 如 : 查 閱 script<br />

/etc/init.d/xfs:<br />

✞<br />

[root@dywHome ~]# cat /etc/init.d/xfs<br />

圲 #!/bin/sh<br />

#<br />

圴 # xfs: Starts the X Font Server<br />

#<br />

圶 # Version: @(#) /etc/rc.d/init.d/xfs 1.4<br />

#<br />

圸 # chkconfig: 2345 20 10<br />

# description: Starts and stops the X Font Server at boot time<br />

and shutdown.<br />

圱 地 #<br />

# processname: xfs<br />

圱 圲 # config: /etc/X11/fs/config<br />

# hide: true<br />

圱 圴 #<br />

### BEGIN INIT INFO<br />

圱 圶 # Provides: xfs<br />

# Required-Start: $network<br />

圱 圸 # Required-Stop: $network<br />

# Default-Start: 2 3 4 5<br />

圲 地 # Short-Description: X Font Server<br />

# Description: X Font Server<br />

圲 圲 ### END INIT INFO<br />

圲 圴 # Source function library.<br />

. /etc/rc.d/init.d/functions<br />

圲 圶<br />

RETVAL=0<br />

圲 圸<br />

# See how we were called.<br />

圳 地 case "$1" in<br />

start)<br />

圳 圲 gprintf "Starting X Font Server: "<br />

De-Yu Wang CSIE CYUT 115


7.3. SHELL SCRIPT 的 追 蹤 與 CHAPTER DEBUG 7.<br />

SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

mkdir -p /tmp<br />

圳 圴<br />

chmod a+w,+t /tmp<br />

# sticky(+t) 僅 有 該 檔 案 目 錄 建 立 者 與 :/ root 能 刪 除 它 。<br />

圳 圶<br />

rm -fr /tmp/.font-unix<br />

daemon --check xfs xfs -port -1 -daemon -droppriv -user<br />

xfs<br />

圳 圸<br />

touch /var/lock/subsys/xfs<br />

echo<br />

圴 地 ;;<br />

stop)<br />

圴 圲 gprintf "Shutting down X Font Server: "<br />

killproc xfs<br />

圴 圴<br />

rm -f /var/lock/subsys/xfs<br />

echo<br />

圴 圶 ;;<br />

status)<br />

圴 圸<br />

status xfs<br />

RETVAL=$<br />

圵 地 ;;<br />

restart)<br />

圵 圲 gprintf "Restarting X Font Server. "<br />

if [ -f /var/lock/subsys/xfs -a ! -z "‘pidof xfs‘" ];<br />

then<br />

圵 圴<br />

killproc xfs -USR1<br />

else<br />

圵 圶<br />

rm -fr /tmp/.font-unix<br />

daemon --check xfs xfs -port -1 -daemon -droppriv -<br />

user xfs<br />

圵 圸<br />

touch /var/lock/subsys/xfs<br />

fi<br />

圶 地<br />

echo<br />

;;<br />

圶 圲 *)<br />

gprintf "*** Usage: xfs {start|stop|status|restart}\n"<br />

圶 圴 exit 1<br />

esac<br />

圶 圶<br />

exit $RETVAL<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 如 何 僅 測 試 shell script testsh.sh 有 無 語 法 的 問 題 , 而 不 要 執 行<br />

script<br />

Sol. sh -n testsh.sh<br />

2. 如 何 在 執 行 shell script testsh.sh 前 , 先 將 script 的 內 容 輸 出 到 螢 幕<br />

上 <br />

Sol. sh -v testsh.sh<br />

De-Yu Wang CSIE CYUT 116


7.3. SHELL SCRIPT 的 追 蹤 與 CHAPTER DEBUG 7.<br />

SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

3. 如 何 在 執 行 shell script testsh.sh 時 , 將 script 的 執 行 過 程 全 部 列 出<br />

來 <br />

Sol. sh -x testsh.sh<br />

4. 如 何 查 閱 系 統 script /etc/init.d/network 的 內 容 <br />

Sol. cat /etc/init.d/network (cat , more, less 或 vi 皆 可 )<br />

De-Yu Wang CSIE CYUT 117


7.3. SHELL SCRIPT 的 追 蹤 與 CHAPTER DEBUG 7.<br />

SHELL SCRIPTS – 條 件 判 斷 與 迴 圈<br />

De-Yu Wang CSIE CYUT 118


CHAPTER 8.<br />

開 發 工 具 – MAKE 與 MAKEFILE<br />

Chapter 8<br />

開 發 工 具 – make 與 makefile<br />

8.1 編 譯 器 與 可 執 行 檔<br />

• 為 何 編 譯 <br />

1. <strong>Linux</strong> 系 統 上 真 正 認 識 的 可 執 行 檔 其 實 是 二 進 位 檔 案 (binary file),<br />

例 如 /usr/bin/passwd, /bin/touch。<br />

2. 寫 一 個 C/C++ 程 式 , 要 有 C/C++ 的 編 譯 器 ( 例 如 :gcc/g++), 將 原 始<br />

碼 (source code) 翻 譯 成 機 器 可 以 執 行 的 程 式 碼 。<br />

3. Shell scripts 只 是 利 用 shell ( 例 如 bash) 程 式 的 功 能 進 行 一 些 判<br />

斷 式 , 及 呼 叫 一 些 已 經 編 譯 好 的 binary 檔 案 來 執 行 。<br />

4. 以 file 命 令 查 看 檔 案 型 態 :<br />

✞<br />

圱 #binary file 之 可 執 行 檔 , 顯 示 執 行 檔 類<br />

別 ( ELF 32-bit LSB executable ),<br />

# 同 時 說 明 是 否 使 用 動 態 函 式 庫 ( shared libs )<br />

圳 ## ELF: Extensible Linking Format<br />

## LSB: <strong>Linux</strong> Standard Base<br />

圵<br />

[root@test root]# file /bin/bash<br />

圷 /bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1<br />

(SYSV),<br />

for GNU/<strong>Linux</strong> 2.2.5, dynamically linked (uses shared libs),<br />

stripped<br />

圹<br />

# shell script test01-hello.sh 檔 案<br />

圱 圱 [root@test root]# file test01-hello.sh<br />

test01-hello.sh: Bourne-Again shell script text executable<br />

✡✝<br />

✆<br />

• 編 譯 步 驟 :<br />

1. 使 用 任 何 的 文 字 編 輯 器 產 生 C/C++ 原 始 碼 (source code);<br />

De-Yu Wang CSIE CYUT 119


8.1. 編 譯 器 與 可 執 行 檔 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

2. 編 譯 器 gcc/g++ 將 C/C++ 的 原 始 碼 編 譯 成 目 的 檔 (object file), 目<br />

的 檔 為 機 器 可 了 解 的 機 器 語 言 但 還 無 法 執 行 ;<br />

3. 將 目 的 檔 和 函 式 庫 中 的 程 式 連 結 成 可 執 行 檔 , 函 式 庫 存 放 一 些 C/C++<br />

常 用 的 function, 可 執 行 檔 為 機 器 可 執 行 的 程 式 ;<br />

4. 執 行 可 執 行 檔 ;<br />

純 文 字 之<br />

原 始 程 式 檔<br />

❄<br />

gcc/g++ 編 譯<br />

❄<br />

目 的 檔<br />

(Object file)<br />

❄<br />

連 結 ✛<br />

其 他 目 的 檔 + 函 式 庫<br />

❄<br />

可 執 行 檔<br />

❄<br />

執 行<br />

5. 程 式 執 行 引 用 函 式 庫 流 程<br />

使 用 者 執 行 程 式<br />

❄<br />

執 行 程 式 過 程<br />

❄<br />

執 行 結 果<br />

呼 叫 ✲<br />

✛<br />

回 傳<br />

外 部 函 式 庫<br />

• 編 譯 器 gcc 的 用 法<br />

1. 以 vi 編 輯 程 式 檔 hello.c<br />

✞<br />

[dywang@dywOffice test]$ vi hello.c<br />

圲 #include <br />

main()<br />

圴 {<br />

De-Yu Wang CSIE CYUT 120


8.1. 編 譯 器 與 可 執 行 檔 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

圶 }<br />

✡✝<br />

printf("Hello!\n");<br />

✆<br />

2. 僅 將 原 始 碼 編 譯 成 為 目 標 檔 , 並 不 製 作 連 結 等 功 能 :<br />

✞<br />

[guest@test guest]# gcc -c hello.c<br />

圲 # 會 自 動 的 產 生 hello.o 這 個 檔 案 , 但 是 並 不 會 產 生 binary 執 行 檔 。<br />

✡✝<br />

✆<br />

3. 在 編 譯 的 時 候 , 依 據 作 業 環 境 給 予 最 佳 化 執 行 速 度 :<br />

✞<br />

[guest@test guest]# gcc -O hello.c -c<br />

圲 # 會 自 動 的 產 生 hello.o 這 個 檔 案 , 並 且 進 行 最 佳 化 。<br />

✡✝<br />

✆<br />

4. 在 進 行 binary file 製 作 時 , 將 連 結 的 函 式 庫 與 相 關 的 路 徑 填 入 :<br />

✞<br />

[guest@test guest]# gcc sin.c -lm -L/usr/lib -I/usr/include<br />

圲 # 這 個 指 令 較 常 下 達 在 最 終 連 結 成 binary file 的 時 候 ,<br />

# -lm 指 的 是 函 式 庫 檔 案 libm.so 或 libm.a;<br />

圴 # -L 後 面 接 函 式 庫 的 搜 尋 目 錄 路 徑 ;<br />

# -I 後 面 接 原 始 碼 內 的 include 檔 案 之 所 在 目 錄 。<br />

✡✝<br />

✆<br />

5. 將 編 譯 的 結 果 輸 出 成 某 個 特 定 檔 名 :<br />

✞<br />

圱 [guest@test guest]# gcc -o hello hello.c<br />

# -o 後 接 的 是 要 輸 出 的 binary file 檔 名<br />

✡✝<br />

✆<br />

6. 在 編 譯 的 時 候 , 輸 出 較 多 的 訊 息 說 明 :<br />

✞<br />

[guest@test guest]# gcc -o hello hello.c -Wall<br />

圲 # 加 入 -Wall , 程 式 的 編 譯 時 會 顯 示 警 告 訊 息 。<br />

# -Wall 或 -O 等 參 數 為 旗 標 ( FLAGS ), 簡 稱 這 些 旗 標 為 CCFLAGS。<br />

✡✝<br />

✆<br />

練 習 題<br />

1. <strong>Linux</strong> 系 統 上 機 器 認 識 的 可 執 行 檔 , 格 式 為 何 <br />

Sol. 二 進 位 檔 案 (binary file)<br />

2. 程 式 編 譯 目 的 為 何 <br />

Sol. 將 原 始 碼 (source code) 翻 譯 成 機 器 可 以 執 行 的 程 式 碼 。<br />

De-Yu Wang CSIE CYUT 121


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

3. 如 何 查 詢 檔 案 /bin/touch 之 型 態 <br />

Sol. file /bin/touch<br />

4. 執 行 file /bin/bash, 出 現 ELF 32-bit LSB executable 訊 息 , 則<br />

/bin/bash 檔 案 型 態 為 何 <br />

Sol. 二 進 位 可 執 行 檔<br />

5. 執 行 file /etc/init.d/xfs, 出 現 Bourne shell script text<br />

executable 訊 息 , 則 /etc/init.d/xfs 檔 案 型 態 為 何 <br />

Sol. Bourne shell script 文 字 型 態 的 可 執 行 檔<br />

6. 請 簡 述 程 式 編 譯 執 行 步 驟 <br />

Sol. 1. 編 輯 原 始 碼 ;2. 將 原 始 碼 編 譯 成 目 的 檔 ;3. 將 目 的 檔 和 函 式 庫 中 的<br />

程 式 連 結 成 可 執 行 檔 ;4. 執 行 。<br />

7. 如 何 僅 將 原 始 碼 hello.c 編 譯 成 為 目 標 檔 , 並 不 製 作 連 結 等 功 能 <br />

Sol. gcc -c hello.c<br />

8. 如 何 在 編 譯 hello.c 時 , 依 據 作 業 環 境 給 予 最 佳 化 執 行 速 度 <br />

Sol. gcc -O hello.c -c<br />

9. 如 何 在 編 譯 hello.c 成 可 執 行 檔 時 , 連 結 函 式 庫 檔 案 libm.so 或 libm.a<br />

<br />

Sol. gcc hello.c -lm<br />

10. 如 何 在 編 譯 hello.c 成 可 執 行 檔 時 , 指 定 函 式 庫 的 搜 尋 目 錄 為 /usr/lib<br />

Sol. gcc hello.c -L/usr/lib<br />

11. 如 何 在 編 譯 hello.c 成 可 執 行 檔 時 , 指 定 原 始 碼 內 的 include 檔 案 所 在 目<br />

錄 為 /usr/include<br />

Sol. gcc hello.c -I/usr/include<br />

12. 如 何 在 編 譯 hello.c 時 , 指 定 可 執 行 檔 名 稱 為 hello<br />

Sol. gcc -o hello hello.c<br />

13. 如 何 在 編 譯 hello.c 時 , 指 定 可 執 行 檔 名 稱 為 hello, 且 於 程 式 的 編 譯 時<br />

會 顯 示 警 告 訊 息 <br />

Sol. gcc -o hello hello.c -Wall<br />

8.2 make 命 令 和 makefile<br />

• 何 謂 makefile <br />

1. make 命 令 雖 然 有 很 多 內 建 的 功 能 , 但 它 也 無 法 知 道 如 何 建 立 應 用 程<br />

式 。 故 必 須 提 供 一 個 檔 案 , 即 makefile, 告 訴 make 如 何 建 立 應 用 程<br />

式 。<br />

2. makefile 與 專 案 的 原 始 碼 檔 案 , 通 常 放 在 同 一 個 目 錄 中 。<br />

De-Yu Wang CSIE CYUT 122


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

3. 可 以 同 時 有 很 多 不 同 的 makefile 管 理 專 案 的 不 同 部 分 。<br />

4. make 命 令 和 makefile 的 結 合 , 不 僅 控 制 原 始 碼 的 編 譯 , 也 可 以 用 來<br />

準 備 使 用 手 冊 文 件 、 安 裝 應 用 程 式 到 目 的 目 錄 中 。<br />

• make 使 用 makefile 的 好 處 :<br />

1. 簡 化 編 譯 時 所 需 要 下 達 的 指 令 ;<br />

2. 若 在 編 譯 完 成 之 後 , 修 改 了 某 個 原 始 碼 檔 案 , 則 make 僅 會 針 對 被 修 改<br />

了 的 檔 案 進 行 編 譯 , 其 他 的 object file 不 會 被 更 動 ;<br />

3. 最 後 可 以 依 照 相 依 性 來 更 新 ( update ) 執 行 檔 。<br />

• make 與 configure<br />

1. 當 執 行 make 時 ,make 會 在 當 時 的 目 錄 下 搜 尋 文 字 檔 makefile ( or<br />

Makefile ), 其 記 錄 了 原 始 碼 如 何 編 譯 的 詳 細 資 訊 。<br />

2. 偵 測 程 式 configure<br />

(a) 軟 體 開 發 者 會 寫 一 支 偵 測 程 式 來 偵 測 使 用 者 的 作 業 環 境 , 以 及 該 作<br />

業 環 境 是 否 有 軟 體 開 發 商 所 需 要 的 其 他 功 能 ;<br />

(b) 偵 測 完 畢 後 , 會 主 動 的 建 立 Makefile 的 規 則 檔 案 。<br />

(c) 偵 測 程 式 的 檔 名 為 configure 或 者 是 config。<br />

• 為 什 麼 要 用 make <br />

1. 假 設 有 一 些 標 頭 檔 案 a.h、b.h 和 c.h, 以 及 C 原 始 碼 檔 案<br />

main.c、2.c 和 3.c。 Souce codes download<br />

✞<br />

圱 /* main.c */<br />

#include "a.h"<br />

圳 ...<br />

/* 2.c */<br />

圵 #include "a.h"<br />

#include "b.h"<br />

圷 ...<br />

圹<br />

/* 3.c */<br />

#include "b.h"<br />

#include "c.h"<br />

圱 圱 ...<br />

✡✝<br />

✆<br />

(a) 如 果 程 式 設 計 人 員 改 變 c.h, 檔 案 main.c 和 2.c 不 需 要 重 新 編<br />

譯 ; 3.c 需 要 被 重 新 編 譯 。<br />

(b) 如 果 b.h 被 改 變 , 程 式 設 計 人 員 忘 了 重 新 編 譯 2.c, 最 後 的 程 式 可<br />

能 不 會 正 確 運 作 。<br />

2. 假 設 執 行 檔 包 含 了 四 個 原 始 碼 檔 案 , 分 別 是 main.c haha.c<br />

sin_value.c cos_value.c , 如 何 讓 這 個 程 式 可 以 執 行 <br />

De-Yu Wang CSIE CYUT 123


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

(a) 不 使 用 makefile<br />

✞<br />

圱 # 1. 先 製 作 出 四 個 目 標 檔 :<br />

[guest@test guest]# gcc -c main.c<br />

圳 [guest@test guest]# gcc -c haha.c<br />

[guest@test guest]# gcc -c sin_value.c<br />

圵 [guest@test guest]# gcc -c cos_value.c<br />

圷 # 2. 製 作 執 行 檔 main:<br />

[guest@test guest]# gcc -o main main.o haha.o sin_value.o<br />

\<br />

圹 > cos_value.o -lm -L/usr/lib -L/lib<br />

圱 圱 # 3. 執 行 :<br />

[guest@test guest]# ./main<br />

圱 圳 HaHa! I’m the King of the world<br />

0.706825<br />

圱 圵 0.707388<br />

✡✝<br />

✆<br />

(b) 使 用 makefile , 以 一 個 步 驟 完 成 所 有 動 作 :<br />

✞<br />

圱 # 1. 先 建 立 編 譯 的 規 則<br />

[root@linux ~]# vi makefile<br />

圳 main: main.o haha.o sin_value.o cos_value.o<br />

gcc -o main main.o haha.o sin_value.o cos_value.o<br />

-lm<br />

圵 # 第 二 行 的 gcc 之 前 是 按 鍵 產 生 的 空 格<br />

圷 # 2. make 會 主 動 讀 取 makefile 內 容 , 並 編 譯 相 關 的 執 行 檔<br />

[root@linux ~]# rm -f main *.o


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

✡✝<br />

✆<br />

1. 標 的 (target) 與 相 依 檔 案 ( 就 是 目 標 檔 ) 之 間 需 以 『:』 隔 開 。<br />

2. 需 要 在 命 令 行 的 第 一 個 字 元 ;<br />

3. makefile 語 法 中 之 與 空 白 :<br />

(a) 所 有 的 法 則 必 須 在 同 一 行 , 而 且 行 首 必 須 為 ; 不 能 為 空 白 。<br />

(b) 在 makefile 中 , 行 尾 如 果 有 一 個 空 白 , 會 造 成 make 命 令 執 行 錯<br />

誤 。<br />

4. makefile 的 註 解 (comment):<br />

(a) 如 同 C 原 始 碼 檔 案 一 般 , 在 makefile 中 , 以 # 為 行 首 的 文 字 都<br />

是 註 解 。<br />

(b) makefile 中 的 註 解 只 是 協 助 作 者 和 其 它 人 , 了 解 makefile 的 內<br />

容 。<br />

• makefile 的 語 法 規 則 :<br />

1. makefile 是 由 很 多 相 依 性 項 目 (dependencies) 和 法 則 (rules) 所 組<br />

成 。<br />

2. 相 依 性 項 目 , 描 述 目 標 項 目 (target, 要 產 生 的 檔 案 ) 和 產 生 該 檔 案 之<br />

相 關 的 原 始 碼 檔 案 。<br />

3. 法 則 是 說 明 如 何 根 據 相 依 性 檔 案 , 來 建 立 目 標 項 目 。<br />

4. make 命 令 利 用 makefile, 先 決 定 依 序 建 立 哪 些 目 標 項 目 , 再 決 定 依 序<br />

喚 起 哪 些 法 則 。<br />

• 相 依 性 項 目 (dependency)<br />

1. 例 題 : 目 標 項 目 myapp 與 main.o、2.o、3.o 相 關 ,main.o 與<br />

main.c、a.h 相 關 , 以 此 類 推 。<br />

✞<br />

myapp: main.o 2.o 3.o<br />

圲 main.o: main.c a.h<br />

2.o: 2.c a.h b.h<br />

圴 3.o: 3.c b.h c.h<br />

✡✝<br />

✆<br />

(a) makefile 中 依 序 為 目 標 項 目 、 冒 號 、 空 白 或 tab、 隨 後 就 是 以 空 白<br />

或 tab 區 隔 的 相 關 檔 案 。<br />

(b) 改 變 b.h, 需 要 重 建 2.o 和 3.o, 因 為 2.o 和 3.o 被 改 變 , 又<br />

需 要 重 建 myapp。<br />

2. 以 gcc 的 -MM 選 項 以 makefile 的 格 式 , 輸 出 相 依 性 項 目 。<br />

De-Yu Wang CSIE CYUT 125


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

✞<br />

$ gcc -MM main.c 2.c 3.c<br />

圲 main.o: main.c a.h<br />

2.o: 2.c a.h b.h<br />

圴 3.o: 3.c b.h c.h<br />

✡✝<br />

✆<br />

(a) 輸 出 結 果 可 插 入 makefile 中 , 成 為 相 依 性 的 法 則 。<br />

(b) makedepend 工 具 , 類 似 -MM 選 項 , 但 會 將 相 依 性 項 目 附 加 到<br />

makefile 之 後 。<br />

3. 利 用 假 造 的 目 標 項 目 all, 建 立 多 個 目 標 檔 案 。 例 如 : 產 生 二 進 位 執 行<br />

檔 myapp 和 使 用 手 冊 文 件 myapp.1。<br />

✞<br />

all: myapp myapp.1<br />

✡✝<br />

✆<br />

(a) 通 常 設 定 all 為 makefile 的 第 一 個 目 標 項 目 , 隨 後 再 一 一 列 出<br />

all 的 相 依 性 項 目 。<br />

(b) 如 果 不 指 定 all 目 標 項 目 ,make 就 會 產 生 makefile 中 的 第 一 個<br />

目 標 項 目 。<br />

• 法 則 (rule): 說 明 如 何 產 生 目 標 項 目 。<br />

✞<br />

圱 2.o: 2.c a.h b.h<br />

gcc -c 2.c<br />

圳 #, 以 法 則 gcc -c 2.c 產 生 目 標 項 目 2.o<br />

✡✝<br />

✆<br />

• make [ -f makefile ] [ options ] ... [ targets ] ..., 常 用 的 選 項<br />

及 參 數 :<br />

1. -j N: 讓 make 在 同 一 個 時 間 執 行 N 個 命 令 , 以 加 速 編 譯 的 時 間 。<br />

2. -k: 讓 make 在 遇 到 錯 誤 時 , 仍 然 繼 續 運 行 , 不 停 止 在 第 一 個 問 題 點 。<br />

3. -n: 告 訴 make 只 印 出 將 會 進 行 的 工 作 , 而 不 真 正 去 編 譯 。<br />

4. -f : 告 訴 make 該 使 用 的 makefile 檔 案 。 如 果 不 使 用<br />

這 個 選 項 , make 會 依 序 尋 找 目 錄 中 的 GNUmakefile, makefile,<br />

Makefile。<br />

5. 直 接 於 make 時 , 指 定 目 標 項 目 名 稱<br />

✞<br />

圱 [root@dywOffice ~]# make targetfile<br />

✡✝<br />

✆<br />

• 實 作 - 簡 單 的 makefile 範 例<br />

De-Yu Wang CSIE CYUT 126


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

1. 產 生 makefile- 檔 名 Makefile1:<br />

✞<br />

圱 myapp: main.o 2.o 3.o<br />

gcc -o myapp main.o 2.o 3.o<br />

圳 main.o: main.c a.h<br />

gcc -c main.c<br />

圵 2.o: 2.c a.h b.h<br />

gcc -c 2.c<br />

圷 3.o: 3.c b.h c.h<br />

gcc -c 3.c<br />

✡✝<br />

✆<br />

2. 執 行 make 命 令 , 因 為 程 式 碼 不 存 在 , 故 得 到 以 下 訊 息 :<br />

✞<br />

$ make -f Makefile1<br />

圲 make: *** No rule to make target ’main.c’, needed by ’main.o<br />

’. Stop.<br />

$<br />

✡✝<br />

✆<br />

3. 利 用 touch 產 生 空 白 的 標 頭 檔 案 。<br />

✞<br />

圱 $ touch a.h<br />

$ touch b.h<br />

圳 $ touch c.h<br />

✡✝<br />

✆<br />

4. 編 輯 程 式 main.c, 2.c 和 3.c。<br />

✞<br />

圱 /* main.c */<br />

#include <br />

圳 /* 引 用 的 標 頭 檔 案 , 在 makefile 中 , 會 有 相 依 性 關 係 。<br />

#include "a.h"<br />

圵 extern void function_two();<br />

extern void function_three();<br />

圷 int main()<br />

{<br />

圹<br />

/* 呼 叫 function_two 和 。 function_three */<br />

圱 圱 function_two();<br />

function_three();<br />

圱 圳 exit (EXIT_SUCCESS);<br />

}<br />

圱 圵<br />

/* 2.c 定 義 function_two 函 式 */<br />

圱 圷 #include "a.h"<br />

#include "b.h"<br />

圱 圹 void function_two() {<br />

De-Yu Wang CSIE CYUT 127


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

}<br />

圲 圱<br />

/* 3.c 定 義 function_three 函 式 */<br />

圲 圳 #include "b.h"<br />

#include "c.h"<br />

圲 圵 void function_three() {<br />

}<br />

✡✝<br />

✆<br />

5. 再 次 測 試 make 成 功 :<br />

✞<br />

$ make -f Makefile1<br />

圲 gcc -c main.c<br />

gcc -c 2.c<br />

圴 gcc -c 3.c<br />

gcc -o myapp main.o 2.o 3.o<br />

圶 $<br />

✡✝<br />

✆<br />

6. b.h 修 改 後 再 make:<br />

✞<br />

$ touch b.h<br />

圲 $ make -f Makefile1<br />

gcc -c 2.c<br />

圴 gcc -c 3.c<br />

gcc -o myapp main.o 2.o 3.o<br />

圶 $<br />

✡✝<br />

✆<br />

7. 刪 除 目 的 檔 案 後 再 make:<br />

✞<br />

$ rm 2.o<br />

圲<br />

$ make -f Makefile1<br />

gcc -c 2.c<br />

圴 gcc -o myapp main.o 2.o 3.o<br />

$<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 使 用 make 時 , 會 在 當 時 的 目 錄 下 搜 尋 那 個 文 字 檔 , 以 得 知 如 何 建 立 應 用 程<br />

式 <br />

Sol. makefile 或 Makefile<br />

2. 軟 體 開 發 者 會 寫 一 支 偵 測 程 式 來 建 立 makefile 的 規 則 檔 案 , 其 檔 名 為 何 <br />

Sol. configure 或 config ( 較 少 用 )<br />

De-Yu Wang CSIE CYUT 128


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

3. 假 設 有 一 些 標 頭 檔 案 a.h、b.h 和 c.h, 以 及 C 原 始 碼 檔 案 main.c、2.c<br />

和 3.c。<br />

/* main.c */<br />

#include "a.h"<br />

...<br />

/* 2.c */<br />

#include "a.h"<br />

#include "b.h"<br />

...<br />

/* 3.c */<br />

#include "b.h"<br />

#include "c.h"<br />

...<br />

如 果 程 式 設 計 人 員 改 變 a.h, 則 那 些 檔 案 需 要 重 新 編 譯 那 些 檔 案 則 不 需 要<br />

被 重 新 編 譯 <br />

Sol. main.c 及 2.c 需 重 新 編 譯 ;3.c 不 需 重 新 編 譯 。<br />

4. 假 設 執 行 檔 包 含 了 三 個 原 始 碼 檔 案 , 分 別 是 main.c ha1.c ha2.c , 不 使 用<br />

makefile 情 況 下 , 如 何 建 立 可 執 行 檔 main<br />

Sol. 逐 步 執 行 以 下 動 作 :gcc -c main.c; gcc -c ha1.c; gcc -c<br />

ha2.c; gcc -o main main.o ha1.o ha2.o<br />

5. 假 設 執 行 檔 包 含 了 三 個 原 始 碼 檔 案 , 分 別 是 main.c ha1.c ha2.c , 使 用<br />

makefile 情 況 下 , 如 何 建 立 可 執 行 檔 main<br />

Sol.<br />

#%* 1. 先 建 立 編 譯 的 規 則 *)<br />

$ vi makefile<br />

main: main.o ha1.o ha2.o<br />

→ gcc -o main main.o ha1.o ha2.o<br />

#%* 2. make 會 主 動 讀 取 makefile 內 容 , 並 編 譯 相 關 的 執 行 檔 *)<br />

$ make<br />

6. 請 寫 出 makefile 的 語 法 。<br />

Sol.<br />

標 的 : 目 標 檔 1 目 標 檔 2<br />

gcc -o 欲 建 立 的 執 行 檔 目 標 檔 1 目 標 檔 2<br />

7. 某 一 makefile 中 , 有 如 下 語 法 , 其 中 □ 代 表 空 白 字 元 , 請 問 是 否 有 錯 <br />

若 有 請 說 明 原 因 。<br />

2.o:□2.c□a.h□b.h<br />

□□□□gcc□-c□2.c<br />

Sol. 有 錯 。gcc 前 為 , 不 可 為 空 白 。<br />

8. 某 一 makefile 中 , 有 如 下 語 法 , 其 中 □ 代 表 空 白 字 元 , → 代 表<br />

。 請 問 是 否 有 錯 若 有 請 說 明 原 因 。<br />

2.o:□2.c□a.h□b.h<br />

→ gcc□-c□2.c□<br />

Sol. 有 錯 。 行 尾 不 可 為 空 白 。<br />

De-Yu Wang CSIE CYUT 129


8.2. MAKE 命 令 和 MAKEFILECHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

9. 某 一 makefile 中 , 有 如 下 語 法 , 其 中 □ 代 表 空 白 字 元 , → 代 表<br />

。 請 問 是 否 有 錯 若 有 請 說 明 原 因 。<br />

2.o:□2.c□a.h□b.h□<br />

→ gcc□-c□2.c<br />

Sol. 有 錯 。 行 尾 不 可 為 空 白 。<br />

10. 在 makefile 中 , 註 解 要 如 何 處 理 <br />

Sol. 行 首 以 # 開 頭 。<br />

11. makefile 主 要 由 那 兩 部 分 組 成 <br />

Sol. 相 依 性 項 目 (dependencies) 和 法 則 (rules) 所 組 成 。<br />

12. 請 說 明 makefile 中 的 相 依 性 項 目 <br />

Sol. 描 述 目 標 項 目 (target, 要 產 生 的 檔 案 ) 和 產 生 該 檔 案 之 相 關 的 原 始<br />

碼 檔 案 。<br />

13. 如 何 以 gcc 指 令 , 以 makefile 格 式 輸 出 main.c, 2.c 及 3.c 的 相 依 性<br />

項 目 <br />

Sol. gcc -MM main.c 2.c 3.c<br />

14. 請 說 明 makefile 中 的 法 則 <br />

Sol. 說 明 如 何 根 據 相 依 性 檔 案 , 來 建 立 目 標 項 目 。<br />

15. 請 說 明 make 指 令 如 何 使 用 makefile<br />

Sol. 利 用 makefile, 先 決 定 依 序 建 立 哪 些 目 標 項 目 , 再 決 定 依 序 喚 起 哪<br />

些 法 則 。<br />

16. 若 要 讓 make 在 同 一 個 時 間 執 行 4 個 命 令 , 以 加 速 編 譯 的 時 間 。 如 何 下 指<br />

令 <br />

Sol. make -j 4<br />

17. 若 要 讓 make 在 遇 到 錯 誤 之 時 , 仍 然 繼 續 運 行 , 而 不 會 停 止 在 第 一 個 問 題<br />

點 。 如 何 下 指 令 <br />

Sol. make -k<br />

18. 若 要 讓 make 只 印 出 將 會 進 行 的 工 作 , 而 不 會 真 正 去 編 譯 。 如 何 下 指 令 <br />

Sol. make -n<br />

19. 若 要 指 定 makefile1 來 進 行 make。 如 何 下 指 令 <br />

Sol. make -f makefile1<br />

20. 在 沒 指 定 makefile 情 況 下 ,make 會 依 序 搜 尋 那 些 檔 名 的 makefile<br />

Sol. GNUmakefile, makefile, Makefile<br />

21. 請 撰 寫 一 makefile, 目 標 檔 及 產 生 之 可 執 行 檔 , 檔 名 為 myapp, 其 相 依 性<br />

項 目 有 main.o 及 2.o, 而 目 標 項 目 main.o 及 2.o 之 相 依 性 項 目 則 分 別<br />

為 main.h, a.h 及 2.c, a.h, b.h。<br />

Sol.<br />

myapp:□main.o□2.o<br />

De-Yu Wang CSIE CYUT 130


8.3. MAKEFILE 的 變 數 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

→ gcc□-o□myapp□main.o□2.o<br />

main.o:□main.c□a.h<br />

→ gcc□-c□main.c<br />

2.o:□2.c□a.h□b.h<br />

→ gcc□-c□2.c<br />

22. 執 行 make -f Makefile1 時 出 現 訊 息 『make: *** No rule to make<br />

target ’main.c’, needed by ’main.o’. Stop』, 代 表 意 義 為 何 <br />

Sol. 產 生 目 標 檔 main.o 需 要 的 檔 案 main.c 不 存 在 , 故 停 止 。<br />

23. 若 程 式 2.c 中 有 兩 行 #include "a.h" 及 #include "b.h", 則 makefile<br />

中 目 標 項 目 2.o 要 如 何 撰 寫 <br />

Sol.<br />

2.o:□2.c□a.h□b.h<br />

→ gcc□-c□2.c<br />

24. 若 程 式 3.c 中 有 兩 行 #include "b.h" 及 #include "c.h", 則 makefile<br />

中 目 標 項 目 3.o 要 如 何 撰 寫 <br />

Sol.<br />

3.o:□3.c□b.h□c.h<br />

→ gcc□-c□3.c<br />

8.3 makefile 的 變 數<br />

• 變 數 用 途 :<br />

1. 簡 化 makefile<br />

2. 開 發 過 程 與 最 終 版 本 使 用 之 編 譯 參 數 不 同<br />

(a) 開 發 應 用 程 式 過 程 中 , 不 會 進 行 最 佳 化 處 理 , 而 須 連 結 一 些 除 錯 資<br />

訊 ;<br />

(b) 最 終 版 本 則 應 是 一 個 最 小 的 二 進 位 檔 案 , 且 不 含 除 錯 資 訊 。<br />

3. 讓 makefile 也 適 用 不 同 的 編 譯 器 。<br />

• 變 數 定 義 :MACRONAME=value<br />

1. 變 數 與 變 數 內 容 以 『=』 隔 開 , 同 時 兩 邊 可 以 具 有 空 格 ;<br />

(shell 中 的 變 數 設 定 , 兩 邊 不 可 以 具 有 空 格 )<br />

2. 變 數 左 邊 不 可 以 有 ;<br />

3. 變 數 與 變 數 內 容 在 『=』 兩 邊 不 能 具 有 『:』;<br />

4. 習 慣 上 , 變 數 最 好 是 以 『 大 寫 字 母 』 為 主 ;<br />

5. 等 號 後 面 的 value 變 成 空 白 時 , 代 表 將 變 數 清 成 空 白 。<br />

• 變 數 存 取<br />

De-Yu Wang CSIE CYUT 131


8.3. MAKEFILE 的 變 數 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

1. $(MACRONAME)<br />

2. ${MACRONAME}<br />

3. 有 些 make 版 本 也 接 受 $MACRONAME<br />

• 以 『 變 數 』 簡 化 makefile :<br />

✞<br />

圱 [guest@test guest]# vi makefile<br />

LIBS = -lm<br />

圳 OBJS = main.o haha.o sin_value.o cos_value.o<br />

main: ${OBJS}<br />

圵<br />

gcc -o main ${OBJS} ${LIBS}<br />

clean:<br />

圷<br />

rm -f main ${OBJS}<br />

✡✝<br />

✆<br />

• 定 義 變 數 , 以 環 境 變 數 CFLAGS 為 例 :<br />

1. make 指 令 中 直 接 定 義<br />

✞<br />

圱 [guest@test guest]# make clean main "CFLAGS=-Wall"<br />

✡✝<br />

✆<br />

2. makefile 檔 案 內 直 接 指 定 環 境 變 數<br />

✞<br />

圱 [guest@test guest]# vi makefile<br />

LIBS = -lm<br />

圳 OBJS = main.o haha.o sin_value.o cos_value.o<br />

CFLAGS = -Wall<br />

圵 main: ${OBJS}<br />

gcc -o main ${OBJS} ${LIBS}<br />

圷 clean:<br />

rm -f main ${OBJS}<br />

✡✝<br />

✆<br />

• 環 境 變 數 取 用 規 則 :<br />

1. make 指 令 列 後 面 加 上 的 環 境 變 數 為 優 先 ;<br />

2. makefile 裡 面 指 定 的 環 境 變 數 第 二 ;<br />

3. shell 原 本 具 有 的 環 境 變 數 第 三 。<br />

• 實 作 - 含 有 變 數 的 makefile<br />

1. Makefile1 的 修 改 版 本 , 加 入 一 些 變 數 之 後 , 變 成 Makefile2:<br />

De-Yu Wang CSIE CYUT 132


8.3. MAKEFILE 的 變 數 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

✞<br />

# 目 標 項 目 all 只 會 產 生 myapp。 執 行 make 預 設 建 立 目 標 項 目<br />

myapp。<br />

圲 all: myapp<br />

# Which compiler<br />

圴 CC = gcc<br />

# Where are include files kept<br />

圶 INCLUDE = .<br />

# Options for development (-g Produce debugging information)<br />

圸 CFLAGS = -g -Wall -ansi<br />

# Options for release<br />

圱 地 # CFLAGS = -O -Wall -ansi<br />

myapp: main.o 2.o 3.o<br />

圱 圲 $(CC) -o myapp main.o 2.o 3.o<br />

圱 圴<br />

main.o: main.c a.h<br />

$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c<br />

2.o: 2.c a.h b.h<br />

圱 圶 $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c<br />

3.o: 3.c b.h c.h<br />

圱 圸 $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c<br />

✡✝<br />

✆<br />

2. 執 行 結 果 :<br />

✞<br />

$ rm *.o myapp<br />

圲 $ make -f Makefile2<br />

gcc -I. -g -Wall -ansi -c main.c<br />

圴 gcc -I. -g -Wall -ansi -c 2.c<br />

gcc -I. -g -Wall -ansi -c 3.c<br />

圶 gcc -o myapp main.o 2.o 3.o<br />

$<br />

✡✝<br />

✆<br />

3. make 程 式 取 代 $(CC)、$(CFLAGS) 和 $(INCLUDE) 的 部 分 。 故 若 要 改<br />

變 編 譯 器 命 令 , 只 需 改 變 這 些 變 數 。<br />

• make 常 用 的 變 數<br />

$ 代 表 需 要 重 建 ( 被 修 改 ) 的 相 依 性 項 目 。<br />

$@ 目 前 的 目 標 項 目 名 稱 。<br />

$< 代 表 目 前 的 相 依 性 項 目 。<br />

$* 代 表 目 前 的 相 依 性 項 目 , 不 過 不 含 副 檔 名 。<br />

1. 例 題 : 以 $@ 代 表 目 前 的 目 標 (target) 項 目 。<br />

[guest@test guest]# vi makefile<br />

LIBS = -lm<br />

OBJS = main.o haha.o sin_value.o cos_value.o<br />

De-Yu Wang CSIE CYUT 133


8.3. MAKEFILE 的 變 數 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

CFLAGS = -Wall<br />

main: ${OBJS}<br />

gcc -o $@ ${OBJS} ${LIBS}<br />

此 $@ 即 main 。 *)<br />

clean:<br />

rm -f main ${OBJS}<br />

%*


8.4. 多 重 目 標 項 目 (TARGET)CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

3. 在 makefile 中 , 定 義 變 數 『MACRONAME□=□value』, 有 無 錯 誤 , 若 有 ,<br />

則 說 明 原 因 , 其 中 □ 表 示 空 白 。<br />

Sol. 正 確<br />

4. 在 makefile 中 , 定 義 變 數 『→MACRONAME□=□value』, 有 無 錯 誤 , 若<br />

有 , 則 說 明 原 因 , 其 中 → 表 示 , □ 表 示 空 白 。<br />

Sol. 錯 誤 , 變 數 左 邊 不 可 以 有 <br />

5. 在 makefile 中 , 定 義 變 數 『MACRONAME:□=□value』, 有 無 錯 誤 , 若 有 ,<br />

則 說 明 原 因 , 其 中 □ 表 示 空 白 。<br />

Sol. 錯 誤 , 變 數 與 變 數 內 容 在 『=』 兩 邊 不 能 具 有 『:』<br />

6. 在 makefile 中 , 定 義 變 數 『MACRONAME□=□』, 代 表 意 義 為 何 其 中 □<br />

表 示 空 白 。<br />

Sol. 將 變 數 清 成 空 白<br />

7. 請 列 舉 兩 項 , 在 makefile 中 取 出 變 數 MACRONAME 的 方 法 。<br />

Sol. $(MACRONAME) 或 ${MACRONAME}<br />

8. 請 說 明 make 取 用 環 境 變 數 的 規 則 。<br />

Sol. 1.make 指 令 列 後 加 ;2.makefile 裡 面 指 定 ;3.shell 原 已 具 有 。<br />

9. 若 有 一 makefile 中 , 目 標 項 目 myapp 的 編 譯 法 則 為 gcc -o $@ main.o<br />

ha.o, 則 產 生 之 可 執 行 檔 為 何 <br />

Sol. myapp<br />

10. 若 有 一 makefile 中 , 目 標 項 目 myapp 的 編 譯 法 則 為 gcc -o $@ main.o<br />

ha.o, 其 中 $@ 代 表 <br />

Sol. 變 數 $@ 代 表 目 前 的 目 標 項 目 myapp<br />

11. 若 有 一 makefile 中 , 有 一 法 則 為 -mkdir /usr/local/repository, 其 中<br />

- 代 表 意 義 為 何 <br />

Sol. make 會 忽 略 命 令 的 錯 誤 。<br />

12. 若 有 一 makefile 中 , 有 一 法 則 為 -rm main.o 2.o 3.o, 其 中 - 代 表 意 義<br />

為 何 <br />

Sol. make 會 忽 略 命 令 的 錯 誤 。<br />

13. 若 有 一 makefile 中 , 有 一 法 則 為 @rm main.o 2.o 3.o, 其 中 @ 代 表 意 義<br />

為 何 <br />

Sol. make 不 會 在 標 準 輸 出 上 , 顯 示 要 執 行 的 命 令 。<br />

8.4 多 重 目 標 項 目 (target)<br />

• 可 在 makefile 中 建 立 多 個 目 標 項 目 , 並 於 make 時 指 定 目 標 項 目 。<br />

• 例 題 : 沿 上 例 , 加 入 clean 目 標 項 目 , 以 移 除 不 想 要 的 目 的 檔<br />

(object)。<br />

De-Yu Wang CSIE CYUT 135


8.4. 多 重 目 標 項 目 (TARGET)CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

1. 建 立 編 譯 的 規 則<br />

✞<br />

圱 [guest@test guest]# vi makefile<br />

main: main.o haha.o sin_value.o cos_value.o<br />

圳<br />

gcc -o main main.o haha.o sin_value.o cos_value.o -lm<br />

clean:<br />

圵<br />

rm -f main main.o haha.o sin_value.o cos_value.o<br />

# clean 冒 號 之 後 是 空 白 。 目 標 項 目 永 遠 會 被 認 為 過 期 , 所 以 它 的 法 則 永<br />

遠 會 被 執 行 。<br />

✡✝<br />

✆<br />

2. 測 試 標 的 clean:<br />

✞<br />

[guest@test guest]# make clean<br />

圲 rm -f main main.o haha.o sin_value.o cos_value.o<br />

✡✝<br />

✆<br />

3. 先 清 除 目 標 檔 再 編 譯 程 式 main :<br />

✞<br />

[guest@test guest]# make clean main<br />

圲 rm -f main main.o haha.o sin_value.o cos_value.o<br />

cc -c -o main.o main.c<br />

圴 cc -c -o haha.o haha.c<br />

cc -c -o sin_value.o sin_value.c<br />

圶 cc -c -o cos_value.o cos_value.c<br />

gcc -o main main.o haha.o sin_value.o cos_value.o -lm<br />

✡✝<br />

✆<br />

• 沿 上 例 , 再 加 入 install 目 標 項 目 , 將 完 成 的 應 用 程 式 安 裝 到 不 同 的 目 錄 。<br />

1. makefile 新 的 版 本 Makefile3:<br />

✞<br />

圱 all: myapp<br />

# Which compiler<br />

圳 CC = gcc<br />

# Where to install<br />

圵 INSTDIR = /usr/local/bin<br />

# Where are include files kept<br />

圷 INCLUDE = .<br />

# Options for development<br />

圹 CFLAGS = -g -Wall -ansi<br />

# Options for release<br />

圱 圱 # CFLAGS = -O -Wall -ansi<br />

myapp: main.o 2.o 3.o<br />

圱 圳 $(CC) -o myapp main.o 2.o 3.o<br />

main.o: main.c a.h<br />

圱 圵 $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c<br />

2.o: 2.c a.h b.h<br />

De-Yu Wang CSIE CYUT 136


8.4. 多 重 目 標 項 目 (TARGET)CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

圱 圷 $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c<br />

3.o: 3.c b.h c.h<br />

圱 圹 $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c<br />

clean:<br />

圲 圱 -rm main.o 2.o 3.o<br />

install: myapp<br />

圲 圳 # 每 個 命 令 都 會 啟 動 一 個 新 的 , 所 以 必 須 加 上 反 斜 線 shell(\), 讓 所<br />

有 script 命 令 在 同 一 行 , 且 在 同 一 個 shell 中 執 行 。<br />

@if [ -d $(INSTDIR) ]; \<br />

圲 圵 then \<br />

cp myapp $(INSTDIR);\<br />

圲 圷 chmod a+x $(INSTDIR)/myapp;\<br />

chmod og-w $(INSTDIR)/myapp;\<br />

圲 圹 echo "Installed in $(INSTDIR)";\<br />

else \<br />

圳 圱 echo "Sorry, $(INSTDIR) does not exist";\<br />

fi<br />

✡✝<br />

✆<br />

2. &&: 前 個 命 令 成 功 , 才 執 行 下 個 命 令<br />

✞<br />

@if [ -d $(INSTDIR) ]; \<br />

圲 then \<br />

cp myapp $(INSTDIR) &&\<br />

圴 chmod a+x $(INSTDIR)/myapp && \<br />

chmod og-w $(INSTDIR/myapp && \<br />

圶 echo "Installed in $(INSTDIR)" ;\<br />

else \<br />

圸 echo "Sorry, $(INSTDIR) does not exist" ; false ; \<br />

fi<br />

✡✝<br />

✆<br />

3. 執 行<br />

✞<br />

圱 $ rm *.o myapp<br />

$ make -f Makefile3<br />

圳 gcc -I. -g -Wall -ansi -c main.c<br />

gcc -I. -g -Wall -ansi -c 2.c<br />

圵 gcc -I. -g -Wall -ansi -c 3.c<br />

gcc -o myapp main.o 2.o 3.o<br />

圷 $ make -f Makefile3<br />

make: Nothing to be done for ’all’.<br />

圹 $ rm myapp<br />

$ make -f Makefile3 install<br />

圱 圱 gcc -o myapp main.o 2.o 3.o<br />

Installed in /usr/local/bin<br />

圱 圳 $ make -f Makefile3 clean<br />

rm main.o 2.o 3.o<br />

圱 圵 $<br />

De-Yu Wang CSIE CYUT 137


8.4. 多 重 目 標 項 目 (TARGET)CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

✡✝<br />

✆<br />

練 習 題<br />

1. makefile 中 , 是 否 可 以 有 多 個 目 標 項 目 <br />

Sol. 可 以 。<br />

2. 若 makefile 中 有 一 目 標 項 目 clean, 則 如 何 於 執 行 make 時 指 定 此 目 標 項<br />

目 <br />

Sol. make clean<br />

3. 若 有 一 makefile 中 , 目 標 項 目 clean 冒 號 之 後 是 空 白 , 代 表 意 義 為 何 <br />

Sol. 目 標 項 目 永 遠 會 被 認 為 過 期 , 所 以 它 的 法 則 永 遠 會 被 執 行 。<br />

4. 若 makefile 中 , 多 個 目 標 項 目 main, clean 與 install, 要 如 何 指 定 目<br />

標 項 目 install 執 行 make<br />

Sol. make install<br />

5. 若 makefile 中 , 多 個 目 標 項 目 main, clean 與 install, make 如 何 " 一<br />

次 " 執 行 claen 後 接 著 install<br />

Sol. make clean install<br />

6. 請 解 釋 如 下 makefile 片 段 , 假 設 變 數 INSTDIR=mydir。<br />

install: myapp<br />

@if [ -d $(INSTDIR) ]; \<br />

then \<br />

cp myapp $(INSTDIR);\<br />

chmod a+x $(INSTDIR)/myapp;\<br />

chmod og-w $(INSTDIR)/myapp;\<br />

echo "Installed in $(INSTDIR)";\<br />

else \<br />

echo "Sorry, $(INSTDIR) does not exist";\<br />

fi<br />

Sol. 1. 目 標 項 目 install 的 相 依 性 項 目 有 myapp; 2. @ 表 示 不 會 在 標<br />

準 輸 出 上 , 顯 示 要 執 行 的 命 令 ; 3. 如 果 mydir 是 一 個 目 錄 , 則 執 行 複 製<br />

myapp 到 目 錄 mydir、 改 變 mydir/myapp 的 屬 性 , 所 有 使 用 者 加 上 可 執 行<br />

屬 性 、 其 他 使 用 者 及 同 群 組 使 用 者 刪 除 可 寫 屬 性 ; 螢 幕 輸 出 Installed in<br />

mydir; 4. 其 他 ( 即 mydir 不 是 一 個 目 錄 , 則 螢 幕 輸 出 Sorry, mydir does<br />

not exist; 5. 因 為 每 個 命 令 都 會 啟 動 一 個 新 的 shell, 所 以 必 須 加 上 反 斜<br />

線 (\), 讓 所 有 script 命 令 在 同 一 行 , 且 在 同 一 個 shell 中 執 行 。<br />

7. 如 下 makefile ,&& \ 代 表 意 義 為 何 <br />

chmod a+x $(INSTDIR)/myapp && \<br />

chmod og-w $(INSTDIR/myapp && \<br />

Sol. && 表 示 前 個 命 令 成 功 , 才 執 行 下 個 命 令 ,\ 讓 script 命 令 在 同 一<br />

行 , 且 在 同 一 個 shell 中 執 行 。<br />

De-Yu Wang CSIE CYUT 138


8.5. MAKEFILE 其 他 法 則 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

8.5 Makefile 其 他 法 則<br />

• 檔 尾 (suffix) 和 符 號 (pattern) 法 則 :<br />

✞<br />

圱 # 將 .old suffix 的 檔 案 變 成 .new suffix 的 檔 案<br />

圳 # 符 號 法 則 1<br />

..:<br />

圵<br />

# 符 號 法 則 2<br />

圷 %.: %.:<br />

✡✝<br />

✆<br />

• 例 題 : 將 .cpp 檔 案 變 成 .o 檔 案 :<br />

1. 符 號 法 則 1:<br />

✞<br />

圱 .SUFFIXES: .cpp<br />

.cpp.o:<br />

圳 $(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<<br />

# gcc 的 -xc++ 旗 標 告 訴 編 譯 器 , 它 是 一 個 C++ 原 始 碼 檔 案 。<br />

圵 # 變 數 $< 代 表 目 前 的 相 依 性 項 目 , 會 被 展 開 成 為 原 本 的 檔 案 名 稱 ( 含 舊<br />

✡✝<br />

的 檔 尾 )。<br />

✆<br />

2. 符 號 法 則 2:<br />

✞<br />

圱 %.o: %.cpp<br />

$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<<br />

✡✝<br />

✆<br />

• 內 建 的 法 則 : 借 助 檔 尾 (suffix), make 即 知 使 用 什 麼 法 則 。<br />

1. 可 以 利 用 -p 選 項 , 要 求 make 印 出 內 建 法 則 , 截 取 部 分 如 下 :<br />

✞<br />

[dywang@dywOffice ~]$ make -p | vi -<br />

圲 OUTPUT_OPTION = -o $@<br />

CXX = g++ ###(gcc)<br />

圴 COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c<br />

COMPILE.C = $(COMPILE.cc)<br />

圶 COMPILE.cpp = $(COMPILE.cc)<br />

圸 %.o: %.c<br />

# commands to execute (built-in):<br />

圱 地 $(COMPILE.cc) $(OUTPUT_OPTION) $<<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 139


8.5. MAKEFILE 其 他 法 則 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

2. 例 題 : 將 .c 檔 尾 的 檔 案 變 成 .o 檔 尾 的 檔 案 。<br />

(a) 編 輯 foo.c,( 傳 統 的 Hello World 程 式 )。<br />

✞<br />

#include <br />

圲 #include <br />

int main()<br />

圴 {<br />

printf("Hello World\n");<br />

圶 exit(EXIT_SUCCESS);<br />

}<br />

✡✝<br />

✆<br />

(b) 藉 由 make 編 譯 程 式 , 但 沒 有 指 定 makefile。<br />

✞<br />

圱 $ make foo<br />

cc foo.c -o foo<br />

圳 $<br />

✡✝<br />

✆<br />

(c) 若 不 使 用 內 建 法 則 , 可 以 於 make 時 , 直 接 加 入 參 數<br />

✞<br />

圱 $ rm foo<br />

$ make CC=gcc CFLAGS="-Wall -g" foo<br />

圳 gcc -Wall -g foo.c -o foo<br />

$<br />

✡✝<br />

✆<br />

3. 可 以 借 用 內 建 法 則 , 簡 化 Makefile3 中 之 編 譯 法 則 , 儲 存 為<br />

Makefile4:<br />

✞<br />

main.o: main.c a.h<br />

圲 # $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c<br />

2.o: 2.c a.h b.h<br />

圴 # $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c<br />

3.o: 3.c b.h c.h<br />

圶 # $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c<br />

# 註 解 部 分 為 原 Makefile3 之 編 譯 法 則<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 請 使 用 兩 種 方 式 寫 出 , 將 .cpp 的 檔 案 變 成 .o 的 檔 案 法 則 。<br />

Sol. .cpp.o: 及 %.o: %.cpp<br />

2. makefile 中 有 一 .cpp.o 之 編 譯 法 則 $(CC) -xc++ -c $


8.6. 函 式 庫 管 理 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

3. makefile 中 有 一 .cpp.o 之 編 譯 法 則 $(CC) -xc++ -c $


8.6. 函 式 庫 管 理 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

✞<br />

圱 /usr/lib<br />

/lib<br />

圳 # kernel 的 函 式 庫 放 在 /lib/modules<br />

✡✝<br />

✆<br />

• 如 何 判 斷 某 個 可 執 行 的 binary 檔 案 含 有 什 麼 動 態 函 式 庫 <br />

1. ldd 指 令<br />

✞<br />

圱 [root@linux ~]# ldd [-vdr] [filename] 選 項 :<br />

圳 --version : 列 印 ldd 的 版 本 序 號<br />

-v : 列 出 所 有 內 容 資 訊 ;<br />

圵 --help : 指 令 用 法 資 訊<br />

✡✝<br />

✆<br />

2. 找 出 檔 案 /usr/bin/passwd 的 函 式 庫 資 料 。<br />

✞<br />

圱 [root@linux ~]# ldd /usr/bin/passwd<br />

linux-gate.so.1 => (0x00d19000) 中 間 省 略<br />

圳 .............<br />

libpam_misc.so.0 => /lib/libpam_misc.so.0 (0x00bd6000<br />

) 中 間 省<br />

略<br />

圵 .............<br />

✡✝<br />

✆<br />

3. 找 出 函 式 /lib/libc.so.6 的 相 關 其 他 函 式 庫 。<br />

✞<br />

圱 [root@linux ~]# ldd /lib/libc.so.6<br />

/lib/ld-linux.so.2 (0x00bf1000)<br />

圳 linux-gate.so.1 => (0x00632000)<br />

圵 [root@linux ~]# ldd -v /lib/libc.so.6<br />

/lib/ld-linux.so.2 (0x00bf1000)<br />

圷 linux-gate.so.1 => (0x00111000)<br />

圹<br />

圱 圱<br />

圱 圳<br />

✡✝<br />

Version information:<br />

/lib/libc.so.6:<br />

ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so<br />

.2<br />

ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so<br />

.2<br />

ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ldlinux.so.2<br />

✆<br />

De-Yu Wang CSIE CYUT 142


8.6. 函 式 庫 管 理 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

• 如 何 將 動 態 函 式 庫 載 入 快 取 記 憶 體 ( cache ), 以 增 進 動 態 函 式 庫 的 讀 取 速<br />

度 <br />

1. 在 /etc/ld.so.conf 寫 入 想 要 讀 入 快 取 記 憶 體 的 動 態 函 式 庫 所 在 的 目<br />

錄 ;<br />

2. 利 用 執 行 檔 ldconfig 將 /etc/ld.so.conf 的 資 料 讀 入 快 取 中 ;<br />

3. 同 時 也 將 資 料 記 錄 一 份 在 檔 案 /etc/ld.so.cache 中 。<br />

✞<br />

圱 [root@test root]# ldconfig [-f conf] [-C cache] [-p] 參 數 說<br />

明 :<br />

圳 -f conf :conf 預 設 為 /etc/ld.so.conf<br />

-C :cachecache 預 設 為 /etc/ld.so.cache<br />

圵 - : 列 出 目 前 在 p cache 內 的 資 料<br />

✡✝<br />

✆<br />

4. 例 題 : 將 xorg 相 關 函 式 庫 加 到 快 取 記 憶 體 中 :<br />

✞<br />

圱 [root@dywHome2 ~]# cat /etc/ld.so.conf<br />

include ld.so.conf.d/*.conf<br />

圳 /usr/X11R6/lib<br />

/usr/lib/qt3/lib<br />

圵 [root@dywHome2 ~]# ldconfig -p | grep "libafb"<br />

[root@dywHome2 ~]# vi /etc/ld.so.conf<br />

圷 [root@dywHome2 ~]# cat /etc/ld.so.conf<br />

include ld.so.conf.d/*.conf<br />

圹 /usr/X11R6/lib<br />

/usr/lib/qt3/lib<br />

圱 圱 /usr/lib/xorg/modules # 加 入 此 行<br />

[root@dywHome2 ~]# ldconfig<br />

圱 圳 [root@dywHome2 ~]# ldconfig -p | grep "libafb"<br />

libafb.so (libc6) => /usr/lib/xorg/modules/libafb.so<br />

✡✝<br />

✆<br />

• 建 立 函 式 庫 : 將 多 個 目 標 檔 案 組 合 成 一 個 函 式 庫 檔 案<br />

1. 函 式 庫 建 立 指 令 ar。 例 如 :<br />

✞<br />

$ cc -c f1.c # 產 生 f1.o<br />

圲 $ cc -c f2.c # 產 生 f2.o<br />

$ ar rv mlib.a f1.o f2.o # 將 目 標 檔 f1.o 及 f2.o 插 入 到 函 式<br />

庫 mlib.a<br />

圴<br />

# 選 項 r : 在 函 式 庫 中 插 入 目 標 檔 。 當 插 入 的 目 標 檔 名 已 在 庫 中 存 在 ,<br />

則 替 換 。<br />

圶 # 選 項 v : 顯 示 執 行 操 作 選 項 的 附 加 信 息 。<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 143


8.6. 函 式 庫 管 理 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

2. nm: 查 看 目 標 檔 庫 檔 案 mlib.a 的 內 容 。<br />

✞<br />

$ nm mlib.a<br />

✡✝<br />

✆<br />

3. make 內 建 函 式 庫 管 理 法 則 , 例 如 : 將 .c 檔 案 變 成 .a 函 式 庫<br />

✞<br />

圱 .c.a:<br />

$(CC) -c $(CFLAGS) $<<br />

圳 $(AR) $(ARFLAGS) $@ $*.o<br />

圵<br />

# 變 數 在 AR 圩 (ARFLAGS), 一 般 分 別 為 命 令 ar 和 選 項 rv。<br />

✡✝<br />

✆<br />

4. 若 有 一 函 式 庫 fud, 包 含 bas.o 檔 案 , 則 上 例 法 則 中 的 變 數 為<br />

(a) $< 代 表 目 前 的 相 依 性 項 目 , 就 是 bas.c。<br />

(b) $@ 代 表 目 前 的 目 標 項 目 , 就 是 fud.a 函 式 庫 。<br />

(c) $* 代 表 目 前 的 相 依 性 項 目 , 不 過 不 含 副 檔 名 , 就 是 bas。<br />

• 實 作 - 管 理 一 個 函 式 庫<br />

1. 將 2.o 和 3.o 插 入 mylib.a 函 式 庫 中 。 新 的 Makefile5 如 下 :<br />

✞<br />

圱 all: myapp<br />

# Which compiler<br />

圳 CC = gcc<br />

# Where to install<br />

圵 INSTDIR = /usr/local/bin<br />

# Where are include files kept<br />

圷 INCLUDE = .<br />

# Options for development<br />

圹 CFLAGS = -g -Wall -ansi<br />

# Options for release<br />

圱 圱 # CFLAGS = -O -Wall -ansi<br />

# Local Libraries<br />

圱 圳 MYLIB = mylib.a<br />

myapp: main.o $(MYLIB)<br />

圱 圵 $(CC) -o myapp main.o $(MYLIB)<br />

$(MYLIB): $(MYLIB)(2.o) $(MYLIB)(3.o)<br />

圱 圷 main.o: main.c a.h<br />

2.o: 2.c a.h b.h<br />

圱 圹 3.o: 3.c b.h c.h<br />

clean:<br />

圲 圱 -rm main.o 2.o 3.o $(MYLIB)<br />

install: myapp<br />

圲 圳 @if [ -d $(INSTDIR) ]; \<br />

then \<br />

圲 圵 cp myapp $(INSTDIR);\<br />

De-Yu Wang CSIE CYUT 144


8.6. 函 式 庫 管 理 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

chmod a+x $(INSTDIR)/myapp;\<br />

圲 圷 chmod og-w $(INSTDIR)/myapp;\<br />

echo "Installed in $(INSTDIR)";\<br />

圲 圹 else \<br />

echo "Sorry, $(INSTDIR) does not exist";\<br />

圳 圱 fi<br />

✡✝<br />

✆<br />

2. 執 行<br />

✞<br />

圱 $ rm -f myapp *.o mylib.a<br />

$ make -f Makefile5<br />

圳 gcc -g -Wall -ansi -c -o main.o main.c<br />

gcc -g -Wall -ansi -c -o 2.o 2.c<br />

圵 ar rv mylib.a 2.o<br />

a - 2.o<br />

圷 gcc -g -Wall -ansi -c -o 3.o 3.c<br />

ar rv mylib.a 3.o<br />

圹 a - 3.o<br />

gcc -o myapp main.o mylib.a<br />

✡✝<br />

✆<br />

3. 試 驗 3.o 的 相 依 性 項 目<br />

✞<br />

$ touch c.h<br />

圲 $ make -f Makefile5<br />

gcc -g -Wall -ansi -c -o 3.o 3.c<br />

圴 ar rv mylib.a 3.o<br />

r - 3.o<br />

圶 gcc -o myapp main.o mylib.a<br />

$<br />

✡✝<br />

✆<br />

• 以 子 目 錄 來 管 理 函 式 庫<br />

1. 方 法 一 : 由 主 要 的 makefile 呼 叫 子 目 錄 的 makefile。<br />

✞<br />

圱 mylib.a:<br />

(cd mylibdirectory;$(MAKE))<br />

✡✝<br />

✆<br />

(a) 要 先 製 作 mylib.a。<br />

(b) 當 make 依 據 這 個 法 則 建 立 函 式 庫 時 , 它 會 進 入 子 目 錄<br />

mylibdirectory;<br />

(c) 隨 後 再 喚 起 make 命 令 來 管 理 函 式 庫 。 這 會 喚 起 一 個 新 shell。<br />

(d) 括 弧 是 為 了 確 保 , 所 有 的 處 理 動 作 都 是 在 一 個 shell 中 。<br />

De-Yu Wang CSIE CYUT 145


8.6. 函 式 庫 管 理 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

2. 方 法 二 : 在 makefile 中 使 用 變 數 , 目 錄 加 上 D, 檔 案 加 上 F。<br />

✞<br />

.c.o:<br />

圲 $(CC) $(CFLAGS) -c $(@D)/$(


8.6. 函 式 庫 管 理 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

8. 如 何 找 出 函 式 /lib/libc.so.6 的 相 關 其 他 函 式 庫 <br />

Sol. ldd /lib/libc.so.6<br />

9. 如 何 找 出 函 式 /lib/libc.so.6 的 相 關 其 他 函 式 庫 , 並 列 出 所 有 內 容 資 訊 <br />

Sol. ldd -v /lib/libc.so.6<br />

10. 要 將 某 目 錄 下 之 動 態 函 式 庫 , 載 入 快 取 記 憶 體 , 必 須 於 那 個 檔 案 中 加 入 此 目<br />

錄 <br />

Sol. /etc/ld.so.conf<br />

11. 如 何 將 /etc/ld.so.conf 的 資 料 讀 入 快 取 記 憶 體 中 <br />

Sol. 執 行 ldconfig<br />

12. 如 何 將 /etc/my.so.conf 的 資 料 讀 入 快 取 記 憶 體 中 <br />

Sol. 執 行 ldconfig -f /etc/my.so.conf<br />

13. 如 何 將 /etc/ld.so.conf 的 資 料 讀 入 快 取 記 憶 體 /etc/my.so.cache 中 <br />

Sol. 執 行 ldconfig -C /etc/my.so.cache<br />

14. 如 何 列 出 目 前 在 cache 內 的 資 料 <br />

Sol. 執 行 ldconfig -p<br />

15. 如 何 查 看 動 態 函 式 庫 libafb.so, 是 否 在 快 取 記 憶 體 中 <br />

Sol. 執 行 ldconfig -p | grep "libafb"<br />

16. 若 目 錄 /usr/lib/xorg/modules 包 含 動 態 函 式 庫 libafb.so, 如 何 將 其 載<br />

入 快 取 記 憶 體 , 以 增 進 動 態 函 式 庫 的 讀 取 速 度 請 詳 列 步 驟 。<br />

Sol. 1. 以 vi 編 輯 檔 案 /etc/ld.so.conf 加 入 一 行<br />

/usr/lib/xorg/modules, 命 令 為 vi /etc/ld.so.conf; 2. 執 行<br />

ldconfig; 3. 查 看 動 態 函 式 庫 libafb.so, 是 否 在 快 取 記 憶 體 中 ,ldconfig<br />

-p | grep "libafb"<br />

17. 如 何 將 目 標 檔 f1.o 及 f2.o 插 入 到 函 式 庫 mlib.a<br />

Sol. ar r mlib.a f1.o f2.o<br />

18. 如 何 將 目 標 檔 f1.o 及 f2.o 插 入 到 函 式 庫 mlib.a, 並 顯 示 訊 息 <br />

Sol. ar rv mlib.a f1.o f2.o<br />

19. 如 何 查 看 目 標 檔 庫 檔 案 mlib.a 的 內 容 <br />

Sol. nm mlib.a<br />

20. 若 有 一 函 式 庫 fud, 包 含 bas.o 檔 案 , 則 下 列 makefile 法 則 中 的 變 數<br />

$


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

Sol. 1.$< 代 表 目 前 的 相 依 性 項 目 , 就 是 bas.c。 2.$@ 代 表 目 前 的 目 標<br />

項 目 , 就 是 fud.a 函 式 庫 。 3.$* 代 表 目 前 的 相 依 性 項 目 , 不 過 不 含 副 檔<br />

名 , 就 是 bas。<br />

21. 請 列 舉 兩 種 以 子 目 錄 來 管 理 函 式 庫 之 makefile 寫 法 。<br />

Sol. 1. 先 進 入 子 目 錄 , 並 在 子 目 錄 中 產 生 函 式 庫 ; 2. 在 makefile 中 使<br />

用 變 數 , 目 錄 加 上 D, 檔 案 加 上 F。<br />

22. 請 說 明 makefile 法 則 (cd mydir;$(MAKE))。<br />

Sol. 1. 先 進 入 子 目 錄 mydir, 並 在 子 目 錄 中 執 行 變 數 $(MAKE) 的 內 容 ;<br />

2. 括 弧 是 為 了 確 保 , 所 有 的 處 理 動 作 都 是 在 一 個 shell 中 。<br />

23. 若 目 標 項 目 所 在 目 錄 為 mydir, 程 式 2.c, 目 標 項 目 2.o 檔 案 ,<br />

則 makefile 法 則 $(CC) $(CFLAGS) -c $(@D)/$(


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

✞<br />

圱 .TH MYAPP 1<br />

.SH NAME<br />

圳 Myapp \- A simple demonstration application that does very little<br />

.<br />

.SH SYNOPSIS<br />

圵 .B myapp<br />

[\-option ...]<br />

圷 .SH DESCRIPTION<br />

.PP<br />

圹 \fImyapp\fP is a complete application that does nothing useful.<br />

.PP<br />

圱 圱 It was written for demonstration purposes.<br />

.SH OPTIONS<br />

圱 圳 .PP<br />

It doesn’t have any, but let’s pretend, to make this template<br />

圱 圵 complete:<br />

.TP<br />

圱 圷 .BI \-option<br />

If there was an option, it would not be -option.<br />

圱 圹 .SH RESOURCES<br />

.PP<br />

圲 圱 myapp uses almost no resources.<br />

.SH DIAGNOSTICS<br />

圲 圳 The program shouldn’t output anything, so if you find it doing so<br />

there’s probably something wrong. The return value is zero.<br />

圲 圵 .SH SEE ALSO<br />

The only other program we know with this this little<br />

functionality is<br />

圲 圷 the ubiquitous hello world application.<br />

.SH COPYRIGHT<br />

圲 圹 myapp is Copyright (c) 2003 Wrox Press.<br />

This program is free software; you can redistribute it and/or<br />

modify<br />

圳 圱 it under the terms of the GNU General Public License as published<br />

by<br />

the Free Software Foundation; either version 2 of the License, or<br />

圳 圳 (at your option) any later version.<br />

This program is distributed in the hope that it will be useful,<br />

圳 圵 but WITHOUT ANY WARRANTY; without even the implied warranty of<br />

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />

圳 圷 GNU General Public License for more details.<br />

You should have received a copy of the GNU General Public License<br />

圳 圹 along with this program; if not, write to the Free Software<br />

Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA<br />

02111-1307<br />

圴 圱 USA.<br />

.SH BUGS<br />

圴 圳 There probably are some, but we don’t know what they are yet.<br />

.SH AUTHORS<br />

圴 圵 Neil Matthew and Rick Stones<br />

De-Yu Wang CSIE CYUT 149


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

✡✝<br />

✆<br />

1. 巨 集 都 以 (.) 開 頭 , 而 且 都 很 簡 短 。<br />

2. 上 例 第 一 行 的 1 表 示 使 用 手 冊 歸 屬 於 第 一 類 ( 使 用 者 可 以 操 作 的 指 令 或<br />

可 執 行 檔 )。<br />

3. 巨 集 格 式 可 以 man 7 man 查 詢<br />

✞<br />

圱 [root@dywOffice ~]# man -f man<br />

man (1) - format and display the on-line<br />

manual pages<br />

圳 man.config [man] (5) - configuration data for man<br />

man (7) - macros to format man pages<br />

圵 [root@dywOffice ~]# man 7 man | cat -<br />

圷 MAN(7) <strong>Linux</strong> Programmer’s Manual<br />

MAN(7)<br />

圹 NAME<br />

man - macros to format man pages<br />

圱 圱<br />

SYNOPSIS<br />

圱 圳 groff -Tascii -man file ...<br />

groff -Tps -man file ...<br />

圱 圵 man [section] title<br />

圱 圷<br />

圱 圹<br />

圲 圱<br />

DESCRIPTION<br />

PREAMBLE<br />

The first command in a man page should be<br />

.TH title section date source manual,<br />

圲 圳 SECTIONS<br />

Sections are started with .SH followed by the<br />

name.<br />

圲 圵<br />

.SH NAME<br />

chess \- the game of chess<br />

圲 圷 FONTS<br />

The commands to select the type face are:<br />

圲 圹 .B Bold<br />

.BI Bold alternating with italics<br />

圳 圱 .BR Bold alternating with Roman<br />

.I Italics<br />

圳 圳 .IB Italics alternating with bold<br />

.IR Italics alternating with Roman<br />

圳 圵 .RB Roman alternating with bold<br />

.RI Roman alternating with italics<br />

圳 圷 .SB Small alternating with bold<br />

.SM Small (useful for acronyms)<br />

heading<br />

De-Yu Wang CSIE CYUT 150


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

圳 圹<br />

OTHER MACROS AND STRINGS<br />

圴 圱 Normal Paragraphs<br />

.LP Same as .PP (begin a new paragraph).<br />

圴 圳 .P Same as .PP (begin a new paragraph).<br />

.PP Begin a new paragraph and reset prevailing<br />

indent.<br />

圴 圵 Relative Margin Indent<br />

.RS i Start relative margin indent:<br />

圴 圷<br />

moves the left margin i to the right.<br />

.RE End relative margin indent and restores<br />

圴 圹 the previous value of the prevailing indent.<br />

Indented Paragraph Macros<br />

圵 圱 .HP i Begin paragraph with a hanging indent.<br />

.IP x i Indented paragraph with optional hanging tag<br />

x.<br />

圵 圳 .TP i Begin paragraph with hanging tag.<br />

Hypertext Link Macros<br />

圵 圵 Miscellaneous Macros<br />

.DT Reset tabs to default tab values (every 0.5<br />

inches)..<br />

圵 圷 .PD d Set inter-paragraph vertical distance to d (<br />

if omitted,<br />

d=0.4v).<br />

圵 圹 .SS t Subheading t (like .SH, but used for a<br />

subsection).<br />

Predefined Strings<br />

圶 圱<br />

圶 圳<br />

圶 圵<br />

SAFE SUBSET<br />

NOTES<br />

Font changes (ft and the \f escape sequence) should<br />

only have the<br />

values 1, 2, 3, 4, R, I, B, P, or CW.<br />

圶 圷<br />

圶 圹<br />

圷 圱<br />

圷 圳<br />

圷 圵<br />

圷 圷<br />

FILES<br />

BUGS<br />

AUTHORS<br />

/usr/share/groff/[*/]tmac/tmac.an<br />

/usr/man/whatis<br />

SEE ALSO<br />

apropos(1), groff(1), man(1), man2html(1), mdoc(7),<br />

mdoc.samples(7),<br />

groff_man(7), groff_www(7), whatis(1)<br />

<strong>Linux</strong> 2004-07-27<br />

MAN(7)<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 151


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

• UNIX 使 用 手 冊 是 藉 由 nroff 工 具 , 格 式 處 理 後 所 形 成 , 在 <strong>Linux</strong> 系 統 上<br />

也 有 個 類 似 的 GNU 專 案 groff。<br />

• 利 用 指 令 groff 處 理 使 用 手 冊 的 原 始 碼 。<br />

1. 指 令 groff<br />

✞<br />

$ groff [-Tm] file<br />

圲 -: 產 生 Tascii ASCII 文 字 。<br />

-: 產 生 Tps 。PostScript<br />

圴 -: 告 訴 man groff 輸 入 一 個 使 用 手 冊 。<br />

✡✝<br />

✆<br />

2. 將 使 用 手 冊 myapp.1 以 ASCII 文 字 產 生 :<br />

✞<br />

[dywang@dywHome2 chapter09]$ groff -Tascii -man myapp.1<br />

圲 MYAPP(1)<br />

MYAPP(1)<br />

圴<br />

圶<br />

圸<br />

NAME<br />

Myapp - A simple demonstration application that does<br />

very little.<br />

圱 地<br />

圱 圲<br />

圱 圴<br />

圱 圶<br />

圱 圸<br />

圲 地<br />

圲 圲<br />

圲 圴<br />

圲 圶<br />

圲 圸<br />

SYNOPSIS<br />

myapp [-option ...]<br />

DESCRIPTION<br />

myapp is a complete application that does nothing<br />

useful.<br />

OPTIONS<br />

RESOURCES<br />

It was written for demonstration purposes.<br />

It doesn’t have any, but lets pretend, to make this<br />

template complete:<br />

-option<br />

If there was an option, it would not be -option<br />

.<br />

De-Yu Wang CSIE CYUT 152


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

圳 地<br />

myapp uses almost no resources.<br />

圳 圲<br />

DIAGNOSTICS<br />

圳 圴 The program shouldn’t output anything, so if you<br />

find it doing so<br />

there’s probably something wrong. The return value is<br />

zero.<br />

圳 圶<br />

圳 圸<br />

圴 地<br />

圴 圲<br />

圴 圴<br />

SEE ALSO<br />

The only other program we know with this this little<br />

functionality is<br />

the ubiquitous hello world application.<br />

COPYRIGHT<br />

myapp is Copyright (c) 2003 Wrox Press.<br />

圴 圶 This program is free software; you can redistribute it<br />

and/or modify it<br />

under the terms of the GNU General Public License as<br />

published by the<br />

圴 圸 Free Software Foundation; either version 2 of the<br />

License, or (at your<br />

option) any later version.<br />

圵 地<br />

This program is distributed in the hope that it will<br />

be useful, but<br />

圵 圲 WITHOUT ANY WARRANTY; without even the implied<br />

warranty of MER-<br />

CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See<br />

the GNU General<br />

圵 圴 Public License for more details.<br />

圵 圶<br />

圵 圸<br />

圶 地<br />

圶 圲<br />

BUGS<br />

You should have received a copy of the GNU General<br />

Public License along<br />

with this program; if not, write to the Free Software<br />

Foundation, Inc.,<br />

675 Mass Ave, Cambridge, MA 02139, USA.<br />

There probably are some, but we don’t know what they<br />

are yet.<br />

圶 圴<br />

圶 圶<br />

AUTHORS<br />

Neil Matthew and Rick Stones<br />

圶 圸<br />

De-Yu Wang CSIE CYUT 153


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

圷 地<br />

ACKNOWLEDGEMENT<br />

Thanks to Wrox press for publishing this book.<br />

圷 圲<br />

圷 圴<br />

MYAPP<br />

(1)<br />

✡✝<br />

✆<br />

• 使 用 man 命 令 查 詢 使 用 手 冊<br />

1. 先 以 指 令 bzip2 將 使 用 手 冊 myapp.1 壓 縮 ;<br />

✞<br />

[dywang@dywHome2 chapter09]$ bzip2 -z myapp.1<br />

圲 [dywang@dywHome2 chapter09]$ ls myapp.*<br />

myapp.1.bz2 myapp.spec<br />

✡✝<br />

✆<br />

2. 將 壓 縮 之 使 用 手 冊 myapp.1.bz2 放 到 /usr/share/man/man1 目 錄 下 。<br />

✞<br />

圱 [dywang@dywHome2 chapter09] cp myapp.1.bz2 /usr/share/man/<br />

man1/<br />

✡✝<br />

✆<br />

練 習 題<br />

1. UNIX 使 用 手 冊 處 理 工 具 為 何 <br />

Sol. nroff<br />

2. <strong>Linux</strong> 使 用 手 冊 處 理 工 具 為 何 <br />

Sol. groff<br />

3. 請 說 明 .TH MYAPP 1 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中 之 意 義 及 結<br />

果 。<br />

Sol. 指 令 名 稱 顯 示 在 man page 的 開 頭 第 一 行 ;1 代 表 使 用 手 冊 歸 屬 於 第<br />

一 類 ; 顯 示 結 果 MYAPP(1)<br />

4. 請 說 明 .SH NAME 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中 之 意 義 及 結 果 。<br />

Sol. 段 落 的 抬 頭 為 NAME; 顯 示 結 果 NAME<br />

5. 請 說 明 .B myapp [\-option ...] 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中<br />

之 意 義 及 結 果 。<br />

Sol. 字 型 myapp [-option ...] 為 粗 體 字 ;\- 為 跳 脫 特 殊 字 元 -<br />

De-Yu Wang CSIE CYUT 154


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

6. 請 說 明 .PP \fImyapp\fP 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中 之 意 義 及<br />

結 果 。<br />

Sol. 開 始 新 的 一 行 且 內 縮 ; 顯 示 myapp;\f 為 字 型 改 變 指 令 ; 字 型 改 變<br />

為 有 下 線 I, 後 再 改 變 回 無 下 線 之 正 常 字 體 P<br />

7. 請 說 明 .TP .BI \-option 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中 之 意 義<br />

及 結 果 。<br />

Sol. 開 始 新 的 一 行 且 外 凸 為 標 籤 ; 顯 示 -option 字 型 為 粗 斜 體<br />

8. 如 何 以 指 令 groff, 將 使 用 手 冊 myapp.1 以 ASCII 文 字 產 生 <br />

Sol. groff -Tascii -man myapp.1<br />

9. 要 讓 系 統 可 以 使 用 man 命 令 查 詢 使 用 手 冊 myapp.1, 必 須 做 那 兩 個 動 作 <br />

Sol. 1. 壓 縮 bzip2 -z myapp.1 2. 複 製 cp myapp.1.bz2<br />

/usr/share/man/man1/<br />

De-Yu Wang CSIE CYUT 155


8.7. 撰 寫 使 用 者 手 冊 CHAPTER 8. 開 發 工 具 – MAKE 與 MAKEFILE<br />

De-Yu Wang CSIE CYUT 156


CHAPTER 9.<br />

開 發 工 具 – MAKEFILE 其 他 功 能<br />

Chapter 9<br />

開 發 工 具 – makefile 其 他 功 能<br />

9.1 多 重 目 標 項 目 (target)<br />

• 可 在 makefile 中 建 立 多 個 目 標 項 目 , 並 於 make 時 指 定 目 標 項 目 。<br />

• 例 題 : 沿 上 例 , 加 入 clean 目 標 項 目 , 以 移 除 不 想 要 的 目 的 檔<br />

(object)。<br />

1. 建 立 編 譯 的 規 則<br />

✞<br />

圱 [guest@test guest]# vi makefile<br />

main: main.o haha.o sin_value.o cos_value.o<br />

圳<br />

gcc -o main main.o haha.o sin_value.o cos_value.o -lm<br />

clean:<br />

圵<br />

rm -f main main.o haha.o sin_value.o cos_value.o<br />

# clean 冒 號 之 後 是 空 白 。 目 標 項 目 永 遠 會 被 認 為 過 期 , 所 以 它 的 法 則 永<br />

遠 會 被 執 行 。<br />

✡✝<br />

✆<br />

2. 測 試 標 的 clean:<br />

✞<br />

[guest@test guest]# make clean<br />

圲 rm -f main main.o haha.o sin_value.o cos_value.o<br />

✡✝<br />

✆<br />

3. 先 清 除 目 標 檔 再 編 譯 程 式 main :<br />

✞<br />

[guest@test guest]# make clean main<br />

圲 rm -f main main.o haha.o sin_value.o cos_value.o<br />

cc -c -o main.o main.c<br />

圴 cc -c -o haha.o haha.c<br />

cc -c -o sin_value.o sin_value.c<br />

圶 cc -c -o cos_value.o cos_value.c<br />

gcc -o main main.o haha.o sin_value.o cos_value.o -lm<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 157


9.1. 多 重 目 標 項 目 (TARGET)CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

• 沿 上 例 , 再 加 入 install 目 標 項 目 , 將 完 成 的 應 用 程 式 安 裝 到 不 同 的 目 錄 。<br />

1. makefile 新 的 版 本 Makefile3:<br />

✞<br />

圱 all: myapp<br />

# Which compiler<br />

圳 CC = gcc<br />

# Where to install<br />

圵 INSTDIR = /usr/local/bin<br />

# Where are include files kept<br />

圷 INCLUDE = .<br />

# Options for development<br />

圹 CFLAGS = -g -Wall -ansi<br />

# Options for release<br />

圱 圱 # CFLAGS = -O -Wall -ansi<br />

myapp: main.o 2.o 3.o<br />

圱 圳 $(CC) -o myapp main.o 2.o 3.o<br />

main.o: main.c a.h<br />

圱 圵 $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c<br />

2.o: 2.c a.h b.h<br />

圱 圷 $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c<br />

3.o: 3.c b.h c.h<br />

圱 圹 $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c<br />

clean:<br />

圲 圱 -rm main.o 2.o 3.o<br />

install: myapp<br />

圲 圳 # 每 個 命 令 都 會 啟 動 一 個 新 的 , 所 以 必 須 加 上 反 斜 線 shell(\), 讓 所<br />

有 script 命 令 在 同 一 行 , 且 在 同 一 個 shell 中 執 行 。<br />

@if [ -d $(INSTDIR) ]; \<br />

圲 圵 then \<br />

cp myapp $(INSTDIR);\<br />

圲 圷 chmod a+x $(INSTDIR)/myapp;\<br />

chmod og-w $(INSTDIR)/myapp;\<br />

圲 圹 echo "Installed in $(INSTDIR)";\<br />

else \<br />

圳 圱 echo "Sorry, $(INSTDIR) does not exist";\<br />

fi<br />

✡✝<br />

✆<br />

2. &&: 前 個 命 令 成 功 , 才 執 行 下 個 命 令<br />

✞<br />

@if [ -d $(INSTDIR) ]; \<br />

圲 then \<br />

cp myapp $(INSTDIR) &&\<br />

圴 chmod a+x $(INSTDIR)/myapp && \<br />

chmod og-w $(INSTDIR/myapp && \<br />

圶 echo "Installed in $(INSTDIR)" ;\<br />

else \<br />

圸 echo "Sorry, $(INSTDIR) does not exist" ; false ; \<br />

fi<br />

De-Yu Wang CSIE CYUT 158


9.1. 多 重 目 標 項 目 (TARGET)CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

✡✝<br />

✆<br />

3. 執 行<br />

✞<br />

圱 $ rm *.o myapp<br />

$ make -f Makefile3<br />

圳 gcc -I. -g -Wall -ansi -c main.c<br />

gcc -I. -g -Wall -ansi -c 2.c<br />

圵 gcc -I. -g -Wall -ansi -c 3.c<br />

gcc -o myapp main.o 2.o 3.o<br />

圷 $ make -f Makefile3<br />

make: Nothing to be done for ’all’.<br />

圹 $ rm myapp<br />

$ make -f Makefile3 install<br />

圱 圱 gcc -o myapp main.o 2.o 3.o<br />

Installed in /usr/local/bin<br />

圱 圳 $ make -f Makefile3 clean<br />

rm main.o 2.o 3.o<br />

圱 圵 $<br />

✡✝<br />

✆<br />

練 習 題<br />

1. makefile 中 , 是 否 可 以 有 多 個 目 標 項 目 <br />

Sol. 可 以 。<br />

2. 若 makefile 中 有 一 目 標 項 目 clean, 則 如 何 於 執 行 make 時 指 定 此 目 標 項<br />

目 <br />

Sol. make clean<br />

3. 若 有 一 makefile 中 , 目 標 項 目 clean 冒 號 之 後 是 空 白 , 代 表 意 義 為 何 <br />

Sol. 目 標 項 目 永 遠 會 被 認 為 過 期 , 所 以 它 的 法 則 永 遠 會 被 執 行 。<br />

4. 若 makefile 中 , 多 個 目 標 項 目 main, clean 與 install, 要 如 何 指 定 目<br />

標 項 目 install 執 行 make<br />

Sol. make install<br />

5. 若 makefile 中 , 多 個 目 標 項 目 main, clean 與 install, make 如 何 " 一<br />

次 " 執 行 claen 後 接 著 install<br />

Sol. make clean install<br />

6. 請 解 釋 如 下 makefile 片 段 , 假 設 變 數 INSTDIR=mydir。<br />

install: myapp<br />

@if [ -d $(INSTDIR) ]; \<br />

then \<br />

cp myapp $(INSTDIR);\<br />

De-Yu Wang CSIE CYUT 159


9.2. MAKEFILE 其 他 法 則 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

chmod a+x $(INSTDIR)/myapp;\<br />

chmod og-w $(INSTDIR)/myapp;\<br />

echo "Installed in $(INSTDIR)";\<br />

else \<br />

echo "Sorry, $(INSTDIR) does not exist";\<br />

fi<br />

Sol. 1. 目 標 項 目 install 的 相 依 性 項 目 有 myapp; 2. @ 表 示 不 會 在 標<br />

準 輸 出 上 , 顯 示 要 執 行 的 命 令 ; 3. 如 果 mydir 是 一 個 目 錄 , 則 執 行 複 製<br />

myapp 到 目 錄 mydir、 改 變 mydir/myapp 的 屬 性 , 所 有 使 用 者 加 上 可 執 行<br />

屬 性 、 其 他 使 用 者 及 同 群 組 使 用 者 刪 除 可 寫 屬 性 ; 螢 幕 輸 出 Installed in<br />

mydir; 4. 其 他 ( 即 mydir 不 是 一 個 目 錄 , 則 螢 幕 輸 出 Sorry, mydir does<br />

not exist; 5. 因 為 每 個 命 令 都 會 啟 動 一 個 新 的 shell, 所 以 必 須 加 上 反 斜<br />

線 (\), 讓 所 有 script 命 令 在 同 一 行 , 且 在 同 一 個 shell 中 執 行 。<br />

7. 如 下 makefile ,&& \ 代 表 意 義 為 何 <br />

chmod a+x $(INSTDIR)/myapp && \<br />

chmod og-w $(INSTDIR/myapp && \<br />

Sol. && 表 示 前 個 命 令 成 功 , 才 執 行 下 個 命 令 ,\ 讓 script 命 令 在 同 一<br />

行 , 且 在 同 一 個 shell 中 執 行 。<br />

9.2 Makefile 其 他 法 則<br />

• 檔 尾 (suffix) 和 符 號 (pattern) 法 則 :<br />

✞<br />

圱 # 將 .old_suffix 的 檔 案 變 成 .new_suffix 的 檔 案<br />

圳 # 符 號 法 則 1<br />

..:<br />

圵<br />

# 符 號 法 則 2<br />

圷 %.: %.:<br />

✡✝<br />

✆<br />

• 例 題 : 將 .cpp 檔 案 變 成 .o 檔 案 :<br />

1. 符 號 法 則 1:<br />

✞<br />

圱 .SUFFIXES: .cpp<br />

.cpp.o:<br />

圳 $(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<<br />

# gcc 的 -xc++ 旗 標 告 訴 編 譯 器 , 它 是 一 個 C++ 原 始 碼 檔 案 。<br />

圵 # 變 數 $< 代 表 目 前 的 相 依 性 項 目 , 會 被 展 開 成 為 原 本 的 檔 案 名 稱 ( 含 舊<br />

✡✝<br />

的 檔 尾 )。<br />

✆<br />

De-Yu Wang CSIE CYUT 160


9.2. MAKEFILE 其 他 法 則 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

2. 符 號 法 則 2:<br />

✞<br />

圱 %.o: %.cpp<br />

$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<<br />

✡✝<br />

✆<br />

• 內 建 的 法 則 : 借 助 檔 尾 (suffix), make 即 知 使 用 什 麼 法 則 。<br />

1. 可 以 利 用 -p 選 項 , 要 求 make 印 出 內 建 法 則 , 截 取 部 分 如 下 :<br />

✞<br />

[dywang@dywOffice ~]$ make -p | vi -<br />

圲 OUTPUT_OPTION = -o $@<br />

CXX = g++ ###(gcc)<br />

圴 COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c<br />

COMPILE.C = $(COMPILE.cc)<br />

圶 COMPILE.cpp = $(COMPILE.cc)<br />

圸 %.o: %.c<br />

# commands to execute (built-in):<br />

圱 地 $(COMPILE.cc) $(OUTPUT_OPTION) $<<br />

✡✝<br />

✆<br />

2. 例 題 : 將 .c 檔 尾 的 檔 案 變 成 .o 檔 尾 的 檔 案 。<br />

(a) 編 輯 foo.c,( 傳 統 的 Hello World 程 式 )。<br />

✞<br />

#include <br />

圲 #include <br />

int main()<br />

圴 {<br />

printf("Hello World\n");<br />

圶 exit(EXIT_SUCCESS);<br />

}<br />

✡✝<br />

✆<br />

(b) 藉 由 make 編 譯 程 式 , 但 沒 有 指 定 makefile。<br />

✞<br />

圱 $ make foo<br />

cc foo.c -o foo<br />

圳 $<br />

✡✝<br />

✆<br />

(c) 若 不 使 用 內 建 法 則 , 可 以 於 make 時 , 直 接 加 入 參 數<br />

✞<br />

圱 $ rm foo<br />

$ make CC=gcc CFLAGS="-Wall -g" foo<br />

圳 gcc -Wall -g foo.c -o foo<br />

$<br />

De-Yu Wang CSIE CYUT 161


9.2. MAKEFILE 其 他 法 則 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

✡✝<br />

✆<br />

3. 可 以 借 用 內 建 法 則 , 簡 化 Makefile3 中 之 編 譯 法 則 , 儲 存 為<br />

Makefile4:<br />

✞<br />

main.o: main.c a.h<br />

圲 # $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c<br />

2.o: 2.c a.h b.h<br />

圴 # $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c<br />

3.o: 3.c b.h c.h<br />

圶 # $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c<br />

# 註 解 部 分 為 原 Makefile3 之 編 譯 法 則<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 請 使 用 兩 種 方 式 寫 出 , 將 .cpp 的 檔 案 變 成 .o 的 檔 案 法 則 。<br />

Sol. .cpp.o: 及 %.o: %.cpp<br />

2. makefile 中 有 一 .cpp.o 之 編 譯 法 則 $(CC) -xc++ -c $


9.3. 函 式 庫 管 理 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

9.3 函 式 庫 管 理<br />

• 函 式 庫 : 目 標 檔 庫<br />

1. 靜 態 函 式 庫 :<br />

(a) 附 檔 名 : 通 常 為 libxxx.a 的 類 型 ;<br />

(b) 編 譯 行 為 : 整 個 函 式 庫 的 資 料 被 整 合 到 執 行 檔 中 , 所 以 利 用 編 譯 成<br />

的 檔 案 會 比 較 大 。<br />

(c) 獨 立 執 行 的 狀 態 : 編 譯 成 功 的 可 執 行 檔 可 以 獨 立 執 行 , 而 不 需 要 再<br />

向 外 部 要 求 讀 取 函 式 庫 的 內 容 。<br />

(d) 升 級 難 易 度 : 函 式 庫 升 級 後 , 連 執 行 檔 也 需 要 重 新 編 譯 過 一 次 , 將<br />

新 的 函 式 庫 整 合 到 執 行 檔 當 中 。<br />

2. 動 態 函 式 庫 :<br />

(a) 附 檔 名 : 通 常 為 libxxx.so 的 類 型 ;<br />

(b) 編 譯 行 為 : 編 譯 時 執 行 檔 中 僅 具 有 指 向 動 態 函 式 庫 所 在 的 指 標 而<br />

已 , 並 不 包 含 函 式 庫 的 內 容 , 所 以 檔 案 會 比 較 小 。<br />

(c) 獨 立 執 行 的 狀 態 : 不 能 被 獨 立 執 行 , 程 式 讀 取 函 式 庫 時 , 函 式 庫<br />

『 必 須 要 存 在 』, 且 函 式 庫 的 『 所 在 目 錄 也 不 能 改 變 』。<br />

(d) 升 級 難 易 度 : 函 式 庫 升 級 後 , 執 行 檔 不 需 要 進 行 重 新 編 譯 , 故 目 前<br />

的 <strong>Linux</strong> distribution 比 較 傾 向 使 用 動 態 函 式 庫 。<br />

• <strong>Linux</strong> 放 置 函 式 庫 之 目 錄 :<br />

✞<br />

圱 /usr/lib<br />

/lib<br />

圳 # kernel 的 函 式 庫 放 在 /lib/modules<br />

✡✝<br />

✆<br />

• 如 何 判 斷 某 個 可 執 行 的 binary 檔 案 含 有 什 麼 動 態 函 式 庫 <br />

1. ldd 指 令<br />

✞<br />

圱 [root@linux ~]# ldd [-vdr] [filename] 選 項 :<br />

圳 --version : 列 印 ldd 的 版 本 序 號<br />

-v : 列 出 所 有 內 容 資 訊 ;<br />

圵 --help : 指 令 用 法 資 訊<br />

✡✝<br />

✆<br />

2. 找 出 檔 案 /usr/bin/passwd 的 函 式 庫 資 料 。<br />

✞<br />

圱 [root@linux ~]# ldd /usr/bin/passwd<br />

linux-gate.so.1 => (0x00d19000) 中 間 省 略<br />

圳 .............<br />

De-Yu Wang CSIE CYUT 163


9.3. 函 式 庫 管 理 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

libpam_misc.so.0 => /lib/libpam_misc.so.0 (0x00bd6000<br />

) 中 間 省<br />

略<br />

圵 .............<br />

✡✝<br />

✆<br />

3. 找 出 函 式 /lib/libc.so.6 的 相 關 其 他 函 式 庫 。<br />

✞<br />

圱 [root@linux ~]# ldd /lib/libc.so.6<br />

/lib/ld-linux.so.2 (0x00bf1000)<br />

圳 linux-gate.so.1 => (0x00632000)<br />

圵 [root@linux ~]# ldd -v /lib/libc.so.6<br />

/lib/ld-linux.so.2 (0x00bf1000)<br />

圷 linux-gate.so.1 => (0x00111000)<br />

圹<br />

圱 圱<br />

圱 圳<br />

✡✝<br />

Version information:<br />

/lib/libc.so.6:<br />

ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so<br />

.2<br />

ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so<br />

.2<br />

ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ldlinux.so.2<br />

✆<br />

• 如 何 將 動 態 函 式 庫 載 入 快 取 記 憶 體 ( cache ), 以 增 進 動 態 函 式 庫 的 讀 取 速<br />

度 <br />

1. 在 /etc/ld.so.conf 寫 入 想 要 讀 入 快 取 記 憶 體 的 動 態 函 式 庫 所 在 的 目<br />

錄 ;<br />

2. 利 用 執 行 檔 ldconfig 將 /etc/ld.so.conf 的 資 料 讀 入 快 取 中 ;<br />

3. 同 時 也 將 資 料 記 錄 一 份 在 檔 案 /etc/ld.so.cache 中 。<br />

✞<br />

圱 [root@test root]# ldconfig [-f conf] [-C cache] [-p] 參 數 說<br />

明 :<br />

圳 -f conf :conf 預 設 為 /etc/ld.so.conf<br />

-C :cachecache 預 設 為 /etc/ld.so.cache<br />

圵 - : 列 出 目 前 在 p cache 內 的 資 料<br />

✡✝<br />

✆<br />

4. 例 題 : 將 xorg 相 關 函 式 庫 加 到 快 取 記 憶 體 中 :<br />

✞<br />

圱 [root@dywHome2 ~]# cat /etc/ld.so.conf<br />

include ld.so.conf.d/*.conf<br />

圳 /usr/X11R6/lib<br />

De-Yu Wang CSIE CYUT 164


9.3. 函 式 庫 管 理 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

/usr/lib/qt3/lib<br />

圵 [root@dywHome2 ~]# ldconfig -p | grep "libafb"<br />

[root@dywHome2 ~]# vi /etc/ld.so.conf<br />

圷 [root@dywHome2 ~]# cat /etc/ld.so.conf<br />

include ld.so.conf.d/*.conf<br />

圹 /usr/X11R6/lib<br />

/usr/lib/qt3/lib<br />

圱 圱 /usr/lib/xorg/modules # 加 入 此 行<br />

[root@dywHome2 ~]# ldconfig<br />

圱 圳 [root@dywHome2 ~]# ldconfig -p | grep "libafb"<br />

libafb.so (libc6) => /usr/lib/xorg/modules/libafb.so<br />

✡✝<br />

✆<br />

• 建 立 函 式 庫 : 將 多 個 目 標 檔 案 組 合 成 一 個 函 式 庫 檔 案<br />

1. 函 式 庫 建 立 指 令 ar。 例 如 :<br />

✞<br />

$ cc -c f1.c # 產 生 f1.o<br />

圲 $ cc -c f2.c # 產 生 f2.o<br />

$ ar rv mlib.a f1.o f2.o # 將 目 標 檔 f1.o 及 f2.o 插 入 到 函 式<br />

庫 mlib.a<br />

圴<br />

# 選 項 r : 在 函 式 庫 中 插 入 目 標 檔 。 當 插 入 的 目 標 檔 名 已 在 庫 中 存 在 ,<br />

則 替 換 。<br />

圶 # 選 項 v : 顯 示 執 行 操 作 選 項 的 附 加 信 息 。<br />

✡✝<br />

✆<br />

2. nm: 查 看 目 標 檔 庫 檔 案 mlib.a 的 內 容 。<br />

✞<br />

$ nm mlib.a<br />

✡✝<br />

✆<br />

3. make 內 建 函 式 庫 管 理 法 則 , 例 如 : 將 .c 檔 案 變 成 .a 函 式 庫<br />

✞<br />

圱 .c.a:<br />

$(CC) -c $(CFLAGS) $<<br />

圳 $(AR) $(ARFLAGS) $@ $*.o<br />

圵<br />

# 變 數 $(AR) 和 $(ARFLAGS), 一 般 分 別 為 命 令 ar 和 選 項 。 rv<br />

✡✝<br />

✆<br />

4. 若 有 一 函 式 庫 fud, 包 含 bas.o 檔 案 , 則 上 例 法 則 中 的 變 數 為<br />

(a) $< 代 表 目 前 的 相 依 性 項 目 , 就 是 bas.c。<br />

(b) $@ 代 表 目 前 的 目 標 項 目 , 就 是 fud.a 函 式 庫 。<br />

(c) $* 代 表 目 前 的 相 依 性 項 目 , 不 過 不 含 副 檔 名 , 就 是 bas。<br />

• 實 作 - 管 理 一 個 函 式 庫<br />

De-Yu Wang CSIE CYUT 165


9.3. 函 式 庫 管 理 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

1. 將 2.o 和 3.o 插 入 mylib.a 函 式 庫 中 。 新 的 Makefile5 如 下 :<br />

✞<br />

圱 all: myapp<br />

# Which compiler<br />

圳 CC = gcc<br />

# Where to install<br />

圵 INSTDIR = /usr/local/bin<br />

# Where are include files kept<br />

圷 INCLUDE = .<br />

# Options for development<br />

圹 CFLAGS = -g -Wall -ansi<br />

# Options for release<br />

圱 圱 # CFLAGS = -O -Wall -ansi<br />

# Local Libraries<br />

圱 圳 MYLIB = mylib.a<br />

myapp: main.o $(MYLIB)<br />

圱 圵 $(CC) -o myapp main.o $(MYLIB)<br />

$(MYLIB): $(MYLIB)(2.o) $(MYLIB)(3.o)<br />

圱 圷 main.o: main.c a.h<br />

2.o: 2.c a.h b.h<br />

圱 圹 3.o: 3.c b.h c.h<br />

clean:<br />

圲 圱 -rm main.o 2.o 3.o $(MYLIB)<br />

install: myapp<br />

圲 圳 @if [ -d $(INSTDIR) ]; \<br />

then \<br />

圲 圵 cp myapp $(INSTDIR);\<br />

chmod a+x $(INSTDIR)/myapp;\<br />

圲 圷 chmod og-w $(INSTDIR)/myapp;\<br />

echo "Installed in $(INSTDIR)";\<br />

圲 圹 else \<br />

echo "Sorry, $(INSTDIR) does not exist";\<br />

圳 圱 fi<br />

✡✝<br />

✆<br />

2. 執 行<br />

✞<br />

圱 $ rm -f myapp *.o mylib.a<br />

$ make -f Makefile5<br />

圳 gcc -g -Wall -ansi -c -o main.o main.c<br />

gcc -g -Wall -ansi -c -o 2.o 2.c<br />

圵 ar rv mylib.a 2.o<br />

a - 2.o<br />

圷 gcc -g -Wall -ansi -c -o 3.o 3.c<br />

ar rv mylib.a 3.o<br />

圹 a - 3.o<br />

gcc -o myapp main.o mylib.a<br />

✡✝<br />

✆<br />

3. 試 驗 3.o 的 相 依 性 項 目<br />

De-Yu Wang CSIE CYUT 166


9.3. 函 式 庫 管 理 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

✞<br />

$ touch c.h<br />

圲 $ make -f Makefile5<br />

gcc -g -Wall -ansi -c -o 3.o 3.c<br />

圴 ar rv mylib.a 3.o<br />

r - 3.o<br />

圶 gcc -o myapp main.o mylib.a<br />

$<br />

✡✝<br />

✆<br />

• 以 子 目 錄 來 管 理 函 式 庫<br />

1. 方 法 一 : 由 主 要 的 makefile 呼 叫 子 目 錄 的 makefile。<br />

✞<br />

圱 mylib.a:<br />

(cd mylibdirectory;$(MAKE))<br />

✡✝<br />

✆<br />

(a) 要 先 製 作 mylib.a。<br />

(b) 當 make 依 據 這 個 法 則 建 立 函 式 庫 時 , 它 會 進 入 子 目 錄<br />

mylibdirectory;<br />

(c) 隨 後 再 喚 起 make 命 令 來 管 理 函 式 庫 。 這 會 喚 起 一 個 新 shell。<br />

(d) 括 弧 是 為 了 確 保 , 所 有 的 處 理 動 作 都 是 在 一 個 shell 中 。<br />

2. 方 法 二 : 在 makefile 中 使 用 變 數 , 目 錄 加 上 D, 檔 案 加 上 F。<br />

✞<br />

.c.o:<br />

圲 $(CC) $(CFLAGS) -c $(@D)/$(


9.3. 函 式 庫 管 理 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

1. 何 謂 函 式 庫 <br />

Sol. 集 合 目 標 檔 的 目 標 檔 庫<br />

2. 函 式 庫 分 為 那 兩 種 <br />

Sol. 靜 態 及 動 態 函 式 庫<br />

3. 何 謂 靜 態 函 式 庫 <br />

Sol. 1. 附 檔 名 通 常 為 libxxx.a 的 類 型 ;2. 整 個 函 式 庫 的 資 料 被 整 合 到 執<br />

行 檔 中 , 故 可 執 行 檔 可 以 獨 立 執 行 , 但 升 級 時 , 連 執 行 檔 也 需 要 重 新 編 譯 過<br />

一 次 。<br />

4. 何 謂 動 態 函 式 庫 <br />

Sol. 1. 附 檔 名 通 常 為 libxxx.so 的 類 型 ;2. 編 譯 時 執 行 檔 中 僅 具 有 指 向<br />

動 態 函 式 庫 所 在 的 指 標 , 故 可 執 行 檔 不 能 被 獨 立 執 行 , 而 函 式 庫 升 級 後 , 執<br />

行 檔 不 需 要 進 行 重 新 編 譯 ;3. 目 前 的 <strong>Linux</strong> distribution 比 較 傾 向 使 用 動<br />

態 函 式 庫 。<br />

5. 通 常 <strong>Linux</strong> 放 置 函 式 庫 之 目 錄 為 何 <br />

Sol. /usr/lib 及 /lib<br />

6. 通 常 <strong>Linux</strong> kernel 的 函 式 庫 放 置 目 錄 為 何 <br />

Sol. /lib/modules<br />

7. 如 何 找 出 檔 案 /usr/bin/passwd 的 函 式 庫 資 料 <br />

Sol. ldd /usr/bin/passwd<br />

8. 如 何 找 出 函 式 /lib/libc.so.6 的 相 關 其 他 函 式 庫 <br />

Sol. ldd /lib/libc.so.6<br />

9. 如 何 找 出 函 式 /lib/libc.so.6 的 相 關 其 他 函 式 庫 , 並 列 出 所 有 內 容 資 訊 <br />

Sol. ldd -v /lib/libc.so.6<br />

10. 要 將 某 目 錄 下 之 動 態 函 式 庫 , 載 入 快 取 記 憶 體 , 必 須 於 那 個 檔 案 中 加 入 此 目<br />

錄 <br />

Sol. /etc/ld.so.conf<br />

11. 如 何 將 /etc/ld.so.conf 的 資 料 讀 入 快 取 記 憶 體 中 <br />

Sol. 執 行 ldconfig<br />

12. 如 何 將 /etc/my.so.conf 的 資 料 讀 入 快 取 記 憶 體 中 <br />

Sol. 執 行 ldconfig -f /etc/my.so.conf<br />

13. 如 何 將 /etc/ld.so.conf 的 資 料 讀 入 快 取 記 憶 體 /etc/my.so.cache 中 <br />

Sol. 執 行 ldconfig -C /etc/my.so.cache<br />

14. 如 何 列 出 目 前 在 cache 內 的 資 料 <br />

Sol. 執 行 ldconfig -p<br />

15. 如 何 查 看 動 態 函 式 庫 libafb.so, 是 否 在 快 取 記 憶 體 中 <br />

Sol. 執 行 ldconfig -p | grep "libafb"<br />

De-Yu Wang CSIE CYUT 168


9.3. 函 式 庫 管 理 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

16. 若 目 錄 /usr/lib/xorg/modules 包 含 動 態 函 式 庫 libafb.so, 如 何 將 其 載<br />

入 快 取 記 憶 體 , 以 增 進 動 態 函 式 庫 的 讀 取 速 度 請 詳 列 步 驟 。<br />

Sol. 1. 以 vi 編 輯 檔 案 /etc/ld.so.conf 加 入 一 行<br />

/usr/lib/xorg/modules, 命 令 為 vi /etc/ld.so.conf; 2. 執 行<br />

ldconfig; 3. 查 看 動 態 函 式 庫 libafb.so, 是 否 在 快 取 記 憶 體 中 ,ldconfig<br />

-p | grep "libafb"<br />

17. 如 何 將 目 標 檔 f1.o 及 f2.o 插 入 到 函 式 庫 mlib.a<br />

Sol. ar r mlib.a f1.o f2.o<br />

18. 如 何 將 目 標 檔 f1.o 及 f2.o 插 入 到 函 式 庫 mlib.a, 並 顯 示 訊 息 <br />

Sol. ar rv mlib.a f1.o f2.o<br />

19. 如 何 查 看 目 標 檔 庫 檔 案 mlib.a 的 內 容 <br />

Sol. nm mlib.a<br />

20. 若 有 一 函 式 庫 fud, 包 含 bas.o 檔 案 , 則 下 列 makefile 法 則 中 的 變 數<br />

$


9.4. 撰 寫 使 用 者 手 冊 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

25. 若 有 一 makefile 中 , 目 標 項 目 mylib.a: mydir/2.o mydir/3.o 的 法 則<br />

為 ar rv mylib.a $, 其 中 $ 代 表 意 義 為 何 <br />

Sol. 代 表 需 要 重 建 ( 被 修 改 ) 的 相 依 性 項 目 , 就 是 mydir/2.o 及 ( 或 )<br />

mydir/3.o<br />

9.4 撰 寫 使 用 者 手 冊<br />

• 大 部 分 使 用 手 冊 的 設 計 都 有 如 下 樣 式 :<br />

1. Header<br />

2. Name<br />

3. Synopsis<br />

4. Description<br />

5. Options<br />

6. Files<br />

7. See also<br />

8. Bugs<br />

• 簡 單 的 範 本 : 應 用 程 式 使 用 手 冊 之 原 始 碼 myapp.1。<br />

✞<br />

圱 .TH MYAPP 1<br />

.SH NAME<br />

圳 Myapp \- A simple demonstration application that does very little<br />

.<br />

.SH SYNOPSIS<br />

圵 .B myapp<br />

[\-option ...]<br />

圷 .SH DESCRIPTION<br />

.PP<br />

圹 \fImyapp\fP is a complete application that does nothing useful.<br />

.PP<br />

圱 圱 It was written for demonstration purposes.<br />

.SH OPTIONS<br />

圱 圳 .PP<br />

It doesn’t have any, but let’s pretend, to make this template<br />

圱 圵 complete:<br />

.TP<br />

圱 圷 .BI \-option<br />

If there was an option, it would not be -option.<br />

圱 圹 .SH RESOURCES<br />

.PP<br />

圲 圱 myapp uses almost no resources.<br />

.SH DIAGNOSTICS<br />

圲 圳 The program shouldn’t output anything, so if you find it doing so<br />

there’s probably something wrong. The return value is zero.<br />

圲 圵 .SH SEE ALSO<br />

De-Yu Wang CSIE CYUT 170


9.4. 撰 寫 使 用 者 手 冊 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

The only other program we know with this this little<br />

functionality is<br />

圲 圷 the ubiquitous hello world application.<br />

.SH COPYRIGHT<br />

圲 圹 myapp is Copyright (c) 2003 Wrox Press.<br />

This program is free software; you can redistribute it and/or<br />

modify<br />

圳 圱 it under the terms of the GNU General Public License as published<br />

by<br />

the Free Software Foundation; either version 2 of the License, or<br />

圳 圳 (at your option) any later version.<br />

This program is distributed in the hope that it will be useful,<br />

圳 圵 but WITHOUT ANY WARRANTY; without even the implied warranty of<br />

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />

圳 圷 GNU General Public License for more details.<br />

You should have received a copy of the GNU General Public License<br />

圳 圹 along with this program; if not, write to the Free Software<br />

Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA<br />

02111-1307<br />

圴 圱 USA.<br />

.SH BUGS<br />

圴 圳 There probably are some, but we don’t know what they are yet.<br />

.SH AUTHORS<br />

圴 圵 Neil Matthew and Rick Stones<br />

✡✝<br />

✆<br />

1. 巨 集 都 以 (.) 開 頭 , 而 且 都 很 簡 短 。<br />

2. 上 例 第 一 行 的 1 表 示 使 用 手 冊 歸 屬 於 第 一 類 ( 使 用 者 可 以 操 作 的 指 令 或<br />

可 執 行 檔 )。<br />

3. 巨 集 格 式 可 以 man 7 man 查 詢<br />

✞<br />

圱 [root@dywOffice ~]# man -f man<br />

man (1) - format and display the on-line<br />

manual pages<br />

圳 man.config [man] (5) - configuration data for man<br />

man (7) - macros to format man pages<br />

圵 [root@dywOffice ~]# man 7 man | cat -<br />

圷 MAN(7) <strong>Linux</strong> Programmer’s Manual<br />

MAN(7)<br />

圹 NAME<br />

man - macros to format man pages<br />

圱 圱<br />

SYNOPSIS<br />

圱 圳 groff -Tascii -man file ...<br />

groff -Tps -man file ...<br />

圱 圵 man [section] title<br />

De-Yu Wang CSIE CYUT 171


9.4. 撰 寫 使 用 者 手 冊 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

圱 圷<br />

圱 圹<br />

圲 圱<br />

DESCRIPTION<br />

PREAMBLE<br />

The first command in a man page should be<br />

.TH title section date source manual,<br />

圲 圳 SECTIONS<br />

Sections are started with .SH followed by the heading<br />

name.<br />

圲 圵<br />

.SH NAME<br />

chess \- the game of chess<br />

圲 圷 FONTS<br />

The commands to select the type face are:<br />

圲 圹 .B Bold<br />

.BI Bold alternating with italics<br />

圳 圱 .BR Bold alternating with Roman<br />

.I Italics<br />

圳 圳 .IB Italics alternating with bold<br />

.IR Italics alternating with Roman<br />

圳 圵 .RB Roman alternating with bold<br />

.RI Roman alternating with italics<br />

圳 圷 .SB Small alternating with bold<br />

.SM Small (useful for acronyms)<br />

圳 圹<br />

OTHER MACROS AND STRINGS<br />

圴 圱 Normal Paragraphs<br />

.LP Same as .PP (begin a new paragraph).<br />

圴 圳 .P Same as .PP (begin a new paragraph).<br />

.PP Begin a new paragraph and reset prevailing<br />

indent.<br />

圴 圵 Relative Margin Indent<br />

.RS i Start relative margin indent:<br />

圴 圷<br />

moves the left margin i to the right.<br />

.RE End relative margin indent and restores<br />

圴 圹 the previous value of the prevailing indent.<br />

Indented Paragraph Macros<br />

圵 圱 .HP i Begin paragraph with a hanging indent.<br />

.IP x i Indented paragraph with optional hanging tag<br />

x.<br />

圵 圳 .TP i Begin paragraph with hanging tag.<br />

Hypertext Link Macros<br />

圵 圵 Miscellaneous Macros<br />

.DT Reset tabs to default tab values (every 0.5<br />

inches)..<br />

圵 圷 .PD d Set inter-paragraph vertical distance to d (<br />

if omitted,<br />

d=0.4v).<br />

圵 圹 .SS t Subheading t (like .SH, but used for a<br />

subsection).<br />

Predefined Strings<br />

圶 圱<br />

De-Yu Wang CSIE CYUT 172


9.4. 撰 寫 使 用 者 手 冊 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

圶 圳<br />

圶 圵<br />

SAFE SUBSET<br />

Font changes (ft and the \f escape sequence) should<br />

only have the<br />

values 1, 2, 3, 4, R, I, B, P, or CW.<br />

NOTES<br />

圶 圷<br />

圶 圹<br />

圷 圱<br />

圷 圳<br />

圷 圵<br />

圷 圷<br />

FILES<br />

BUGS<br />

AUTHORS<br />

/usr/share/groff/[*/]tmac/tmac.an<br />

/usr/man/whatis<br />

SEE ALSO<br />

apropos(1), groff(1), man(1), man2html(1), mdoc(7),<br />

mdoc.samples(7),<br />

groff_man(7), groff_www(7), whatis(1)<br />

<strong>Linux</strong> 2004-07-27<br />

MAN(7)<br />

✡✝<br />

✆<br />

• UNIX 使 用 手 冊 是 藉 由 nroff 工 具 , 格 式 處 理 後 所 形 成 , 在 <strong>Linux</strong> 系 統 上<br />

也 有 個 類 似 的 GNU 專 案 groff。<br />

• 利 用 指 令 groff 處 理 使 用 手 冊 的 原 始 碼 。<br />

1. 指 令 groff<br />

✞<br />

$ groff [-Tm] file<br />

圲 -: 產 生 Tascii ASCII 文 字 。<br />

-: 產 生 Tps 。PostScript<br />

圴 -: 告 訴 man groff 輸 入 一 個 使 用 手 冊 。<br />

✡✝<br />

✆<br />

2. 將 使 用 手 冊 myapp.1 以 ASCII 文 字 產 生 :<br />

✞<br />

[dywang@dywHome2 chapter09]$ groff -Tascii -man myapp.1<br />

圲 MYAPP(1)<br />

MYAPP(1)<br />

圴<br />

圶<br />

圸<br />

NAME<br />

Myapp - A simple demonstration application that does<br />

very little.<br />

De-Yu Wang CSIE CYUT 173


9.4. 撰 寫 使 用 者 手 冊 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

圱 地<br />

圱 圲<br />

圱 圴<br />

圱 圶<br />

圱 圸<br />

圲 地<br />

圲 圲<br />

圲 圴<br />

圲 圶<br />

圲 圸<br />

圳 地<br />

SYNOPSIS<br />

myapp [-option ...]<br />

DESCRIPTION<br />

myapp is a complete application that does nothing<br />

useful.<br />

OPTIONS<br />

It was written for demonstration purposes.<br />

It doesn’t have any, but lets pretend, to make this<br />

template complete:<br />

-option<br />

If there was an option, it would not be -option<br />

.<br />

RESOURCES<br />

myapp uses almost no resources.<br />

圳 圲<br />

DIAGNOSTICS<br />

圳 圴 The program shouldn’t output anything, so if you<br />

find it doing so<br />

there’s probably something wrong. The return value is<br />

zero.<br />

圳 圶<br />

圳 圸<br />

圴 地<br />

圴 圲<br />

圴 圴<br />

SEE ALSO<br />

The only other program we know with this this little<br />

functionality is<br />

the ubiquitous hello world application.<br />

COPYRIGHT<br />

myapp is Copyright (c) 2003 Wrox Press.<br />

圴 圶 This program is free software; you can redistribute it<br />

and/or modify it<br />

under the terms of the GNU General Public License as<br />

published by the<br />

圴 圸 Free Software Foundation; either version 2 of the<br />

License, or (at your<br />

option) any later version.<br />

圵 地<br />

This program is distributed in the hope that it will<br />

De-Yu Wang CSIE CYUT 174


9.4. 撰 寫 使 用 者 手 冊 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

be useful, but<br />

圵 圲 WITHOUT ANY WARRANTY; without even the implied<br />

warranty of MER-<br />

CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See<br />

the GNU General<br />

圵 圴 Public License for more details.<br />

圵 圶<br />

圵 圸<br />

圶 地<br />

圶 圲<br />

BUGS<br />

You should have received a copy of the GNU General<br />

Public License along<br />

with this program; if not, write to the Free Software<br />

Foundation, Inc.,<br />

675 Mass Ave, Cambridge, MA 02139, USA.<br />

There probably are some, but we don’t know what they<br />

are yet.<br />

圶 圴<br />

圶 圶<br />

圶 圸<br />

圷 地<br />

AUTHORS<br />

Neil Matthew and Rick Stones<br />

ACKNOWLEDGEMENT<br />

Thanks to Wrox press for publishing this book.<br />

圷 圲<br />

圷 圴<br />

MYAPP<br />

(1)<br />

✡✝<br />

✆<br />

• 使 用 man 命 令 查 詢 使 用 手 冊<br />

1. 先 以 指 令 bzip2 將 使 用 手 冊 myapp.1 壓 縮 ;<br />

✞<br />

[dywang@dywHome2 chapter09]$ bzip2 -z myapp.1<br />

圲 [dywang@dywHome2 chapter09]$ ls myapp.*<br />

myapp.1.bz2 myapp.spec<br />

✡✝<br />

✆<br />

2. 將 壓 縮 之 使 用 手 冊 myapp.1.bz2 放 到 /usr/share/man/man1 目 錄 下 。<br />

✞<br />

圱 [dywang@dywHome2 chapter09] cp myapp.1.bz2 /usr/share/man/<br />

man1/<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 175


9.4. 撰 寫 使 用 者 手 冊 CHAPTER 9. 開 發 工 具 – MAKEFILE 其 他 功 能<br />

練 習 題<br />

1. UNIX 使 用 手 冊 處 理 工 具 為 何 <br />

Sol. nroff<br />

2. <strong>Linux</strong> 使 用 手 冊 處 理 工 具 為 何 <br />

Sol. groff<br />

3. 請 說 明 .TH MYAPP 1 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中 之 意 義 及 結<br />

果 。<br />

Sol. 指 令 名 稱 顯 示 在 man page 的 開 頭 第 一 行 ;1 代 表 使 用 手 冊 歸 屬 於 第<br />

一 類 ; 顯 示 結 果 MYAPP(1)<br />

4. 請 說 明 .SH NAME 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中 之 意 義 及 結 果 。<br />

Sol. 段 落 的 抬 頭 為 NAME; 顯 示 結 果 NAME<br />

5. 請 說 明 .B myapp [\-option ...] 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中<br />

之 意 義 及 結 果 。<br />

Sol. 字 型 myapp [-option ...] 為 粗 體 字 ;\- 為 跳 脫 特 殊 字 元 -<br />

6. 請 說 明 .PP \fImyapp\fP 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中 之 意 義 及<br />

結 果 。<br />

Sol. 開 始 新 的 一 行 且 內 縮 ; 顯 示 myapp;\f 為 字 型 改 變 指 令 ; 字 型 改 變<br />

為 有 下 線 I, 後 再 改 變 回 無 下 線 之 正 常 字 體 P<br />

7. 請 說 明 .TP .BI \-option 在 <strong>Linux</strong> 應 用 程 式 使 用 手 冊 之 原 始 碼 中 之 意 義<br />

及 結 果 。<br />

Sol. 開 始 新 的 一 行 且 外 凸 為 標 籤 ; 顯 示 -option 字 型 為 粗 斜 體<br />

8. 如 何 以 指 令 groff, 將 使 用 手 冊 myapp.1 以 ASCII 文 字 產 生 <br />

Sol. groff -Tascii -man myapp.1<br />

9. 要 讓 系 統 可 以 使 用 man 命 令 查 詢 使 用 手 冊 myapp.1, 必 須 做 那 兩 個 動 作 <br />

Sol. 1. 壓 縮 bzip2 -z myapp.1 2. 複 製 cp myapp.1.bz2<br />

/usr/share/man/man1/<br />

De-Yu Wang CSIE CYUT 176


CHAPTER 10.<br />

*RCS 版 本 控 制 系 統<br />

Chapter 10<br />

*RCS 版 本 控 制 系 統<br />

10.1 版 本 控 制<br />

• 版 本 控 制 Version Control( VC )<br />

1. VC 是 指 發 展 程 式 文 件 檔 案 時 , 檔 案 版 本 的 儲 存 和 管 理 的 功 能 。<br />

2. 程 式 發 展 過 程 , 需 要 重 覆 的 修 改 、 暫 存 、 測 試 以 期 得 到 正 確 的 結 果 。<br />

3. 每 次 修 改 的 結 果 分 以 不 同 的 檔 案 儲 存 起 來 , 以 避 免 重 要 訊 息 的 流 失 和 除<br />

錯 時 的 困 難 。<br />

4. RCS ( Revision Control System ) 為 提 供 VC 環 境 的 工 具 。<br />

• RCS 的 功 能<br />

1. 提 供 一 些 命 令 來 管 理 原 始 碼 檔 案 。<br />

2. 透 過 一 個 檔 案 來 管 理 一 系 列 的 修 改 動 作 , 檔 案 紀 錄 足 以 恢 復 先 前 的 版<br />

本 。<br />

3. 只 儲 存 不 同 版 本 之 間 的 修 正 部 分 , 所 以 非 常 節 省 空 間 。<br />

4. 能 比 較 檔 案 各 版 本 之 間 的 不 同 。<br />

5. 將 一 些 完 成 除 錯 的 版 本 內 容 與 其 它 檔 案 版 本 整 合 ( merge )。<br />

• 產 生 檢 查 點 ( Check-Point ) 與 除 錯<br />

1. 設 立 檢 查 點 : 在 檔 案 完 成 階 段 目 標 後 , 將 其 內 容 當 成 一 個 版 本 , 給 予 一<br />

個 版 本 序 號 ( revision number ) 存 起 來 。<br />

1.1 ✲ 1.2 ✲ 1.6 ✲ 1.7<br />

<br />

❳2 ❳❳ ◗❦<br />

❳ ❳❳<br />

◗<br />

❳ ❳❳<br />

◗<br />

❳ ◗ ❳❳<br />

❳<br />

◗ ❳ ◗✘ ✘ ✘ ✘✘ ✘ ✘✘ ✘ ✘✘ ✘ ✘ ✘✿<br />

✑ ✑✑✑✑✑✸<br />

Check-Point<br />

De-Yu Wang CSIE CYUT 177


10.1. 版 本 控 制 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

2. 除 錯 ( debug ) 時 可 取 出 先 前 的 版 本 , 找 出 錯 誤 ( bug ) 發 生 前 的 階<br />

段 ,<br />

3. 比 較 錯 誤 ( bug ) 發 生 前 後 版 本 間 的 差 異 , 進 而 找 出 錯 誤 發 生 的 原 因 。<br />

• 產 生 標 記 符 號<br />

1. 專 案 發 展 需 要 結 合 數 個 程 式 檔 案 , 每 個 版 本 的 檔 案 個 數 不 一 定 相 同 。<br />

2. 不 同 的 專 案 亦 可 能 用 到 相 同 的 檔 案 。<br />

3. RCS 除 了 以 版 本 序 號 代 表 該 版 本 外 , 也 可 產 生 標 記 符 號 ( mark symbol<br />

) 來 代 表 某 些 特 別 的 版 本 。<br />

4. 版 本 序 號 通 常 是 由 RCS 自 動 編 排 , 而 標 記 符 號 則 需 要 使 用 者 自 己 針 對<br />

特 別 的 版 本 產 生 。<br />

5. 若 需 要 指 出 某 些 版 本 為 相 關 ( 例 如 : 同 專 案 ), 則 可 給 序 特 定 符 號 以 供<br />

辨 識 。<br />

• 版 本 比 較 與 合 併<br />

1. RCS 能 比 較 檔 案 各 版 本 之 不 同 , 幫 助 使 用 者 瞭 解 版 本 間 的 差 異 。<br />

2. 檔 案 版 本 的 比 較 之 訊 息 , 往 往 是 除 錯 的 重 要 訊 息 。<br />

3. RCS 也 可 將 兩 個 版 本 的 差 異 與 正 在 工 作 的 檔 案 版 本 整 合 ( merge )。<br />

• 存 取 名 單<br />

• 鎖 檔<br />

練 習 題<br />

1. 支 援 多 人 工 作 環 境 中 檔 案 存 取 權 的 管 理 以 及 避 免 同 時 編 輯 相 同 檔 案 的 發<br />

生 。<br />

2. 提 供 存 取 名 單 ( access list ) 的 設 立 , 記 錄 有 存 取 權 使 用 者 。<br />

3. 存 取 名 單 設 定<br />

(a) 記 錄 在 存 取 名 單 的 使 用 者 才 有 讀 寫 檔 案 的 權 限 。<br />

(b) 存 取 名 單 內 的 使 用 者 同 時 具 有 讀 、 寫 、 執 行 三 種 權 限 。<br />

1. 鎖 檔 ( lock ) 的 功 能 主 要 避 免 同 時 多 人 寫 入 同 一 檔 案 。<br />

2. 一 個 檔 案 同 時 只 能 有 一 個 使 用 者 做 編 輯 的 動 作 ;<br />

3. 在 RCS 中 若 要 對 檔 案 做 修 改 的 動 作 , 必 先 鎖 住 ( lock ) 該 檔 案 ;<br />

4. 被 鎖 住 的 檔 案 , 不 可 以 再 被 其 它 使 用 者 鎖 住 。<br />

5. 鎖 檔 方 式 :<br />

(a) strick lock: 只 有 被 鎖 住 的 檔 案 版 本 , 才 能 有 寫 入 的 動 作 , 此 為 預<br />

設 鎖 檔 方 式 。<br />

(b) nonstrick lock: 可 寫 入 檔 案 的 任 一 版 本 。 因 容 易 發 生 錯 誤 , 所 以<br />

通 常 不 與 考 慮 使 用 。<br />

De-Yu Wang CSIE CYUT 178


10.1. 版 本 控 制 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

1. 何 謂 版 本 控 制 Version Control( VC )<br />

Sol. 指 發 展 程 式 文 件 檔 案 時 , 檔 案 版 本 的 儲 存 和 管 理 的 功 能 。<br />

2. 發 展 程 式 文 件 檔 案 時 , 為 什 麼 要 做 版 本 控 制 <br />

Sol. 程 式 發 展 過 程 , 需 要 重 覆 的 修 改 、 暫 存 、 測 試 以 期 得 到 正 確 的 結 果 ,<br />

而 每 次 修 改 的 結 果 分 以 不 同 的 檔 案 儲 存 起 來 , 以 避 免 重 要 訊 息 的 流 失 和 除 錯<br />

時 的 困 難 。<br />

3. 請 簡 述 三 項 RCS 功 能 。<br />

Sol. 1. 提 供 命 令 管 理 原 始 碼 檔 案 。2. 能 比 較 檔 案 各 版 本 之 間 的 不 同 。3. 能<br />

將 完 成 除 錯 的 版 本 與 其 它 版 本 整 合 。<br />

4. 在 檔 案 完 成 階 段 目 標 後 , RCS 會 在 此 設 立 檢 查 點 , 將 其 內 容 存 起 來 , 並 給 予<br />

一 個 號 碼 , 稱 之 為 何 <br />

Sol. 版 本 序 號 (revision number)<br />

5. RCS 中 除 了 自 動 編 排 的 版 本 序 號 外 , 使 用 者 還 可 以 依 個 別 需 求 自 訂 符 號 , 稱<br />

之 為 何 <br />

Sol. 標 記 符 號 ( mark symbol )<br />

6. 請 說 明 RCS 中 , 存 取 名 單 ( access list ) 的 功 能 。<br />

Sol. 1. 支 援 多 人 工 作 環 境 以 避 免 同 時 編 輯 相 同 檔 案 的 發 生 。2. 存 取 名 單 記<br />

錄 有 存 取 權 使 用 者 。<br />

7. 請 說 明 RCS 中 , 鎖 檔 ( lock ) 的 功 能 。<br />

Sol. 1. 避 免 同 時 多 人 寫 入 同 一 檔 案 。2. 若 要 對 檔 案 做 修 改 , 必 先 鎖 住 該 檔<br />

案 。3. 被 鎖 住 的 檔 案 , 不 能 再 被 其 它 使 用 者 鎖 住 。<br />

8. 請 說 明 RCS 中 , 鎖 檔 ( lock ) 的 方 式 。<br />

Sol. 1.strick lock: 只 有 被 鎖 住 的 檔 案 版 本 , 才 能 有 寫 入 的 動 作 , 此 為<br />

預 設 鎖 檔 方 式 。 2.nonstrick lock: 可 寫 入 檔 案 的 任 一 版 本 。 因 容 易 發 生<br />

錯 誤 , 所 以 通 常 不 與 考 慮 使 用 。<br />

9. RCS 指 令 ci 之 功 能 為 何 <br />

Sol. 將 檔 案 版 本 寫 入 管 理 檔 案 。<br />

10. RCS 指 令 co 之 功 能 為 何 <br />

Sol. 把 檔 案 的 某 個 版 本 從 管 理 檔 案 讀 出 。<br />

11. RCS 中 版 本 主 支 的 序 號 如 何 設 定 <br />

Sol. 1. 以 m.n 為 單 位 , m 為 主 要 號 碼 ,n 為 次 要 號 碼 ;2. 預 設 的 版 本 序<br />

號 從 1.1 開 始 。<br />

12. RCS 中 版 本 分 支 的 序 號 如 何 設 定 <br />

Sol. 1. 在 原 版 本 的 版 本 序 號 後 加 上 .m.n。 例 如 : 版 本 1.2 產 生 的 分 支 為<br />

1.2.1.1, 版 本 1.2.1.1 產 生 的 分 支 為 1.2.1.1.1.1。<br />

13. 請 說 明 RCS 中 , 附 記 ( log ) 的 功 能 。<br />

Sol. 版 本 在 寫 入 時 , 產 生 該 版 本 的 附 記 , 可 以 記 錄 該 版 本 的 一 些 特 性 。<br />

De-Yu Wang CSIE CYUT 179


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

10.2 RCS 基 本 功 能<br />

• 管 理 檔 案 ( archive file )<br />

1. 必 先 針 對 個 別 檔 案 產 生 屬 於 該 檔 的 管 理 檔 案 , 以 儲 存 該 檔 案 的 各 個 版<br />

本 。<br />

2. 各 檔 案 archive file 的 檔 名 是 在 該 檔 案 名 後 加 上 ,v 來 標 示 。<br />

3. 例 如 : 檔 名 test.c 的 管 理 檔 案 即 為 test.c,v。<br />

• 讀 出 ( check-out ) 與 寫 入 ( check-in )<br />

1. 一 個 檔 案 的 管 理 檔 案 存 放 該 檔 的 各 個 版 本 , 可 以 透 過 讀 出 ( check-out<br />

) 與 寫 入 ( check-in ) 動 作 , 取 出 已 存 入 的 版 本 修 改 或 存 入 新 的 版 本 。<br />

archive file<br />

(test.c,v)<br />

check-out<br />

✲<br />

✛<br />

check-in<br />

working file<br />

(test.c)<br />

(a) check in ( ci ): 將 檔 案 版 本 寫 入 管 理 檔 案 的 動 作 。<br />

(b) check out ( co ): 把 檔 案 的 某 個 版 本 從 管 理 檔 案 讀 出 的 動 作 。<br />

2. 預 設 為 唯 讀 狀 態 取 出 版 本 , 不 可 修 改 。 若 要 修 改 檔 案 , 必 須 將 其 鎖 住 。<br />

• 版 本 序 號 (revision number)<br />

1. 在 RCS 的 檔 案 中 每 一 個 版 本 , 都 會 有 一 個 版 本 序 號 以 區 分 各 個 版 本 ;<br />

2. 對 於 特 定 版 本 的 存 取 都 利 用 版 本 序 號 來 指 定 ;<br />

3. 版 本 序 號 的 設 定 是 以 m.n 為 單 位 , m 為 主 要 號 碼 (major number),n<br />

為 次 要 號 碼 (minor number);<br />

4. 預 設 的 版 本 序 號 從 1.1 開 始 。<br />

1.1 ✲ 1.2 ✲ 1.3 ✲ 1.4 <br />

• 分 支 ( branch )<br />

1. 檔 案 的 發 展 可 能 因 為 修 改 或 是 目 的 的 不 同 , 會 從 一 個 版 本 產 生 不 同 的 分<br />

支 。<br />

2. 分 支 的 序 號 為 在 原 版 本 的 版 本 序 號 後 加 上 .m.n, 其 中 m 用 以 區 分 不 同<br />

的 分 支 , n 區 分 在 同 一 分 支 下 的 不 同 版 本 。<br />

De-Yu Wang CSIE CYUT 180


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

3. 例 如 : 版 本 1.2 產 生 的 分 支 為 1.2.1.1, 版 本 1.2.1.1 產 生 的 分 支 為<br />

1.2.1.1.1.1。<br />

1.1 ✲ 1.2 ✲ 1.3 ✲ 1.4 <br />

✲<br />

1.2.1.1 ✲ 1.2.1.2<br />

<br />

✲1.2.1.1.1.1<br />

<br />

• 附 記 ( log )<br />

1. 每 個 版 本 在 寫 入 ( check in ) archive file 時 , 都 會 要 求 使 用 者 產 生<br />

該 版 本 的 附 記 以 記 錄 該 版 本 的 一 些 特 性 。<br />

2. 例 如 : 為 何 產 生 該 版 本 、 該 板 本 解 決 了 那 些 問 題 、 甚 至 該 版 本 用 了 那 些<br />

想 法 與 技 巧 等 等 。<br />

• 產 生 RCS archive file<br />

1. rcs 命 令<br />

✞<br />

圱 [root@dywHome2 ~]# rcs [-Aabeilmnotu] parameter<br />

-A file 將 其 它 檔 案 的 可 存 取 名 單 寫 入 該 檔 的 可 存 取 名 單<br />

圳 -a name 將 使 用 者 寫 入 可 存 取 名 單<br />

-b branch number 設 定 主 支 ( default branch )<br />

圵 -e name 將 使 用 者 自 可 存 取 名 單 內 剔 除<br />

-i file 產 生 及 初 始 化 一 個 新 的 RCS 檔 案<br />

圷 -l[number] lock 該 版 本 但 不 取 出<br />

-m 更 改 檔 案 版 本 的 附 注 ( log ) 的 內 容<br />

圹 -n symbol 產 生 或 去 除 標 記 符 號 ( mark symbol )<br />

-o[number] 從 檔 案 的 archive file 中 移 除 某 版 本<br />

圱 圱 -t 改 檔 案 版 本 的 描 述 ( description ) 的 內 容<br />

-u[number] 去 除 該 版 本 lock 的 狀 態<br />

圱 圳 # u[number] 表 示 選 項 u 後 面 馬 上 接 版 本 序 號<br />

✡✝<br />

✆<br />

2. 以 vi 編 輯 important.c:<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ vi important.c<br />

/*<br />

圳 This is an important file for managing the project.<br />

It implements the canoncial "Hello World" program.<br />

圵 */<br />

De-Yu Wang CSIE CYUT 181


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圷 #include <br />

#include <br />

圹<br />

int main()<br />

圱 圱 {<br />

printf("Hello World\n");<br />

圱 圳<br />

}<br />

✡✝<br />

exit(EXIT_SUCCESS);<br />

✆<br />

3. 初 始 RCS 檔 案 管 理 : 使 用 rcs -i 命 令 初 始 一 個 RCS 管 理 檔 案 。<br />

✞<br />

[dywang@dywOffice testrcs]$ rcs -i important.c<br />

圲 RCS file: important.c,v<br />

enter description, terminated with single ’.’ or end of file:<br />

圴 NOTE: This is NOT the log message!<br />

>> This is an important demonstration file<br />

圶 >> .<br />

done<br />

圸 # 可 以 輸 入 很 多 註 解 。 要 跳 離 提 示 符 號 , 必 須 輸 入 (.), 或 者 在 檔 案 字 元<br />

的 結 尾 輸 入 Ctrl+。D<br />

✡✝<br />

✆<br />

4. rcs 命 令 後 會 產 生 一 個 新 的 唯 讀 檔 案 , 其 檔 尾 為 (,v):<br />

✞<br />

[dywang@dywOffice testrcs]$ ll<br />

圲 total 12<br />

-rw-r--r-- 1 dywang users 226 Mar 5 13:45 important.c<br />

圴 -r--r--r-- 1 dywang users<br />

✡✝<br />

105 Mar 5 13:55 important.c,v<br />

✆<br />

5. 如 果 要 將 RCS 檔 案 放 在 不 同 的 目 錄 , 可 先 產 生 一 個 RCS 子 目 錄 。 所 有<br />

的 rcs 命 令 都 會 自 動 將 rcs 檔 案 儲 存 在 RCS 子 目 錄 。<br />

rcstest/<br />

important.c<br />

RCS/<br />

important.c,v<br />

✞<br />

[dywang@dywOffice testrcs]$ mkdir RCS<br />

圲 [dywang@dywOffice testrcs]$ ll<br />

total 8<br />

圴 -rw-r--r-- 1 dywang users 226 Mar 5 13:45 important.c<br />

drwxr-xr-x 2 dywang users 4096 Mar 5 13:49 RCS/<br />

圶<br />

De-Yu Wang CSIE CYUT 182


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

[dywang@dywOffice testrcs]$ rcs -i important.c<br />

圸 RCS file: RCS/important.c,v<br />

enter description, terminated with single ’.’ or end of file:<br />

圱 地 NOTE: This is NOT the log message!<br />

>> This is an important demonstration file<br />

圱 圲 >> .<br />

done<br />

圱 圴<br />

[dywang@dywOffice testrcs]$ ll . RCS<br />

圱 圶 .:<br />

total 8<br />

圱 圸 -rw-r--r-- 1 dywang users 226 Mar 5 13:45 important.c<br />

drwxr-xr-x 2 dywang users 4096 Mar 5 13:49 RCS/<br />

圲 地<br />

RCS:<br />

圲 圲 total 4<br />

-r--r--r-- 1 dywang users 105 Mar<br />

✡✝<br />

5 13:49 important.c,v<br />

✆<br />

6. 查 看 important.c,v 內 容<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ cat RCS/important.c,v<br />

head ;<br />

圳 access;<br />

symbols;<br />

圵 locks; strict;<br />

comment @ * @;<br />

圷<br />

圹<br />

desc<br />

圱 圱 @This is an important demonstration file<br />

@<br />

✡✝<br />

✆<br />

• 將 程 式 內 容 寫 入 archive file<br />

1. ci (check in) 命 令<br />

✞<br />

[root@dywHome2 ~]# ci [-dfwmnrtlu] parameter<br />

圲 -d date 給 定 版 本 生 成 時 間<br />

-f 強 制 產 生 新 版 本 不 管 是 否 寫 入 相 同 版 本 內 容 ()<br />

圴 -w name 給 定 生 成 該 版 本 的 作 者 名<br />

-m log-message 直 接 以 log-message 寫 入 附 記 ( log )<br />

圶 -n symbol 在 寫 入 archive file 同 時 , 給 定 標 記 符<br />

號 ( mark symbol )<br />

-r[number] 寫 入 時 指 定 版 本 的 rivision number<br />

圸 -t description 直 接 以 檔 案 的 形 式 寫 入 描 述 ( description )<br />

-l 寫 入 後 再 取 出 該 版 本 為 工 作 檔 案 ( lock )<br />

De-Yu Wang CSIE CYUT 183


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圱 地 -u 寫 入 後 再 取 出 該 版 本 為 工 作 檔 案 ( unlock )<br />

✡✝<br />

✆<br />

2. 利 用 ci 命 令 寫 入 (check in) 檔 案 , 儲 存 現 在 的 版 本 。<br />

✞<br />

[dywang@dywOffice testrcs]$ ci important.c<br />

圲 RCS/important.c,v


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圲 圴 text<br />

@/*<br />

圲 圶 This is an important file for managing the project.<br />

It implements the canoncial "Hello World" program.<br />

圲 圸 */<br />

圳 地 #include <br />

#include <br />

圳 圲<br />

int main()<br />

圳 圴 {<br />

printf("Hello World\n");<br />

圳 圶 exit(EXIT_SUCCESS);<br />

}<br />

圳 圸<br />

@<br />

✡✝<br />

✆<br />

• 產 生 新 版 本 : 將 工 作 檔 案 從 archive file 讀 出 、 修 改 , 再 寫 入 archive<br />

file<br />

1. co (check out) 命 令<br />

✞<br />

圱 [root@dywHome2 ~]# co [-dfjlprwu] parameter<br />

-d date 取 出 在 指 定 時 間 前 最 後 生 成 的 版 本<br />

圳 -f 強 制 取 出 版 本 內 容 取 代 目 前 工 作 檔 案<br />

-j 取 出 並 整 合 指 定 的 版 本 內 容<br />

圵 -l lock 取 出 版 本<br />

-p 取 出 版 本 內 容 至 標 準 輸 出 ( standard output )<br />

圷 -r number 指 定 取 出 版 本<br />

-w name 取 出 指 定 作 者 名 之 版 本<br />

圹 -u 取 出 unlock 的 版 本 內 容<br />

✡✝<br />

✆<br />

2. 將 檔 案 important.c 讀 出 (check out)。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ co important.c<br />

RCS/important.c,v --> important.c<br />

圳 revision 1.1<br />

done<br />

圵 [dywang@dywOffice testrcs]$ ll<br />

total 8<br />

圷 -r--r--r-- 1 dywang users 226 Mar 5 14:15 important.c<br />

drwxr-xr-x 2 dywang users 4096 Mar<br />

✡✝<br />

5 14:06 RCS/<br />

✆<br />

3. 將 檔 案 important.c 讀 出 (check out), 以 co -l 鎖 定 取 出 版 本 。<br />

De-Yu Wang CSIE CYUT 185


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

✞<br />

[dywang@dywOffice testrcs]$ co -l important.c<br />

圲 RCS/important.c,v --> important.c<br />

revision 1.1 (locked)<br />

圴<br />

done<br />

[dywang@dywOffice testrcs]$ ll<br />

圶 total 8<br />

-rw-r--r-- 1 dywang users 226 Mar 5 14:18 important.c<br />

圸 drwxr-xr-x 2 dywang users 4096 Mar 5 14:18 RCS/<br />

✡✝<br />

✆<br />

4. 編 輯 important.c, 加 入 一 行 , 並 儲 存 新 的 版 本 :<br />

✞<br />

[dywang@dywOffice testrcs]$ vi important.c<br />

圲 [dywang@dywOffice testrcs]$ cat important.c<br />

/*<br />

圴 This is an important file for managing the project.<br />

It implements the canoncial "Hello World" program.<br />

圶 */<br />

圸 #include <br />

#include <br />

圱 地<br />

int main()<br />

圱 圲 {<br />

圱 圴<br />

圱 圶 }<br />

✡✝<br />

printf("Hello World\n");<br />

printf("This is an extra line added later\n");<br />

exit(EXIT_SUCCESS);<br />

✆<br />

5. 利 用 ci 命 令 儲 存 改 變 處 :<br />

✞<br />

[dywang@dywOffice testrcs]$ ci important.c<br />

圲 RCS/important.c,v > Added an extra line to be printed out<br />

圶 >> .<br />

done<br />

✡✝<br />

✆<br />

6. 查 看 目 錄 看 到 important.c 再 次 被 刪 除 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ ll . RCS<br />

.:<br />

圳 total 8<br />

-rw-r--r-- 1 dywang users 226 Mar 5 14:18 important.c~<br />

圵 drwxr-xr-x 2 dywang users 4096 Mar 5 14:24 RCS/<br />

De-Yu Wang CSIE CYUT 186


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圷 RCS:<br />

total 4<br />

圹 -r--r--r-- 1 dywang users 639 Mar 5 14:24 important.c,v<br />

✡✝<br />

✆<br />

7. 查 看 important.c,v 內 容<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ cat RCS/important.c,v<br />

head 1.2;<br />

圳 access;<br />

symbols;<br />

圵 locks; strict;<br />

comment @ * @;<br />

圷<br />

圹 1.2<br />

date 2008.03.05.06.23.52; author dywang; state Exp;<br />

圱 圱 branches;<br />

next 1.1;<br />

圱 圳<br />

1.1<br />

圱 圵 date 2008.03.05.06.06.15; author dywang; state Exp;<br />

branches;<br />

圱 圷 next ;<br />

圱 圹<br />

圲 圱<br />

圲 圳<br />

desc<br />

@This is an important demonstration file<br />

@<br />

圲 圵 1.2<br />

log<br />

圲 圷 @Added an extra line to be printed out<br />

@<br />

圲 圹 text<br />

@/*<br />

圳 圱 This is an important file for managing the project.<br />

It implements the canoncial "Hello World" program.<br />

圳 圳 */<br />

圳 圵 #include <br />

#include <br />

圳 圷<br />

int main()<br />

圳 圹 {<br />

printf("Hello World\n");<br />

圴 圱 printf("This is an extra line added later\n");<br />

exit(EXIT_SUCCESS);<br />

圴 圳 }<br />

De-Yu Wang CSIE CYUT 187


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圴 圵<br />

@<br />

圴 圷<br />

1.1<br />

圴 圹 log<br />

@Initial revision<br />

圵 圱 @<br />

text<br />

圵 圳 @d12 1<br />

@<br />

✡✝<br />

✆<br />

• 加 上 自 己 對 該 版 本 的 附 註 ( log )<br />

1. check in 時 RCS 會 自 動 要 求 輸 入 :<br />

(a) 初 始 RCS archive file<br />

✞<br />

[dywang@dywOffice testrcs]$ rcs -i important.c<br />

圲 RCS file: important.c,v<br />

enter description, terminated with single ’.’ or end of<br />

file:<br />

圴 NOTE: This is NOT the log message!<br />

>> This is an important demonstration file<br />

圶 >> .<br />

done<br />

圸 # 可 以 輸 入 很 多 註 解 。 要 跳 離 提 示 符 號 , 必 須 輸 入 (.), 或 者 在 檔 案<br />

字 元 的 結 尾 輸 入 Ctrl+。D<br />

✡✝<br />

✆<br />

(b) 寫 入 archive file<br />

✞<br />

[dywang@dywOffice testrcs]$ ci important.c<br />

圲 RCS/important.c,v > Added an extra line to be printed out<br />

圶 >> .<br />

done<br />

✡✝<br />

✆<br />

2. 使 用 指 令 ci -m"comment" file.c, 將 版 本 附 註 comment 直 接 寫 入<br />

archive file 中 , 而 不 會 再 產 生 提 示 訊 息 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ co -l important.c<br />

RCS/important.c,v --> important.c<br />

圳 revision 1.3<br />

De-Yu Wang CSIE CYUT 188


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

done<br />

圵 [dywang@dywOffice testrcs]$ vi important.c<br />

[dywang@dywOffice testrcs]$ ci -m"test for comment" important<br />

.c<br />

圷 RCS/important.c,v


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

locks: strict<br />

圸 access list:<br />

symbolic names:<br />

圱 地 keyword substitution: kv<br />

total revisions: 2; selected revisions: 2<br />

圱 圲 description:<br />

This is an important demonstration file<br />

圱 圴 ----------------------------<br />

revision 1.2<br />

圱 圶 date: 2008/03/05 06:23:52; author: dywang; state: Exp;<br />

lines: +1 -0<br />

Added an extra line to be printed out<br />

圱 圸 ----------------------------<br />

revision 1.1<br />

圲 地 date: 2008/03/05 06:06:15; author: dywang; state: Exp;<br />

Initial revision<br />

圲 圲 =======================================================================<br />

# 在 1.2 版 中 的 第 一 行 行 尾 lines:+1 -0 表 示 增 加 了 一 行 , 但 沒 有 刪<br />

除 任 何 行 。<br />

✡✝<br />

✆<br />

3. 透 過 rlog 命 令 查 看 檔 案 附 記 ( log ) 的 標 頭 ( header )。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rlog -h important.c<br />

圳 RCS file: RCS/important.c,v<br />

Working file: important.c<br />

圵 head: 1.2<br />

branch:<br />

圷 locks: strict<br />

圹<br />

access list:<br />

symbolic names:<br />

keyword substitution: kv<br />

圱 圱 total revisions: 2<br />

=======================================================================<br />

✡✝<br />

✆<br />

4. 透 過 rlog 命 令 查 看 檔 案 的 archive file 路 徑 與 名 稱 。<br />

✞<br />

[dywang@dywOffice testrcs]$ rlog -R important.c<br />

圲 RCS/important.c,v<br />

✡✝<br />

✆<br />

5. 透 過 rlog 命 令 查 看 檔 案 附 記 ( log ) 的 標 頭 ( header )+ 描 述 (<br />

description )。<br />

✞<br />

De-Yu Wang CSIE CYUT 190


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

[dywang@dywOffice testrcs]$ rlog -t important.c<br />

圲<br />

RCS file: RCS/important.c,v<br />

圴 Working file: important.c<br />

head: 1.2<br />

圶 branch:<br />

locks: strict<br />

圸 access list:<br />

symbolic names:<br />

圱 地 keyword substitution: kv<br />

total revisions: 2<br />

圱 圲 description:<br />

This is an important demonstration file<br />

圱 圴 =======================================================================<br />

✡✝<br />

✆<br />

• 解 決 檔 案 未 鎖 住 之 錯 誤<br />

1. 讀 出 important.c, 但 未 鎖 住 。<br />

✞<br />

[dywang@dywOffice testrcs]$ co important.c<br />

圲 RCS/important.c,v --> important.c<br />

revision 1.2<br />

圴<br />

done<br />

[dywang@dywOffice testrcs]$ ll<br />

圶 total 12<br />

-r--r--r-- 1 dywang users 276 Mar 6 09:56 important.c<br />

圸 -rw-r--r-- 1 dywang users 277 Mar 5 21:09 important.c~<br />

drwxr-xr-x 2 dywang users 4096 Mar<br />

✡✝<br />

6 09:56 RCS/<br />

✆<br />

2. 修 改 important.c, 並 強 制 存 檔 後 , 無 法 寫 入 archive file。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ vi important.c<br />

[dywang@dywOffice testrcs]$ ci important.c<br />

圳 RCS/important.c,v


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

new revision: 1.3; previous revision: 1.2<br />

圸 enter log message, terminated with single ’.’ or end of file:<br />

>> test for lock<br />

圱 地 >> .<br />

done<br />

✡✝<br />

✆<br />

• 版 本 之 刪 除<br />

1. 讀 出 important.c, 並 鎖 住 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ co -l important.c<br />

RCS/important.c,v --> important.c<br />

圳 revision 1.2 (locked)<br />

done<br />

✡✝<br />

✆<br />

2. 修 改 important.c, 存 檔 後 , 指 定 為 原 先 版 本 ( 1.2 ), 則 無 法 寫 入<br />

archive file。<br />

✞<br />

[dywang@dywOffice testrcs]$ vi important.c<br />

圲 [dywang@dywOffice testrcs]$ ci -r1.2 important.c<br />

RCS/important.c,v test for lock<br />

圶 >> .<br />

done<br />

✡✝<br />

✆<br />

4. 重 新 讀 出 important.c( 版 本 為 1.3), 並 鎖 住 , 修 改 後 存 檔 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ co -l important.c<br />

RCS/important.c,v --> important.c<br />

圳 revision 1.3 (locked)<br />

done<br />

圵 [dywang@dywOffice testrcs]$ vi important.c<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 192


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

5. 先 移 除 原 先 版 本 ( 1.3 )。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rcs -o1.3 important.c<br />

RCS file: RCS/important.c,v<br />

圳 rcs: RCS/important.c,v: can’t remove locked revision 1.3<br />

[dywang@dywOffice testrcs]$ rcs -u1.3 important.c<br />

圵 RCS file: RCS/important.c,v<br />

1.3 unlocked<br />

圷 done<br />

[dywang@dywOffice testrcs]$ rcs -o1.3 important.c<br />

圹 RCS file: RCS/important.c,v<br />

deleting revision 1.3<br />

圱 圱 done<br />

✡✝<br />

✆<br />

6. 最 後 寫 入 archive file, 版 本 仍 為 1.3。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ ci important.c<br />

RCS/important.c,v test for deletes<br />

圱 圳 >> .<br />

done<br />

✡✝<br />

✆<br />

• 產 生 分 支 ( branch )<br />

如 果 在 版 本 1.2 產 生 版 本 1.3 之 後 , 又 修 改 版 本 1.2 的 內 容 而 欲 生 成 新<br />

的 版 本 , 則 需 在 版 本 1.2 處 產 生 分 支 ( branch ) 1.2.1.1。<br />

lock<br />

1.1 ✲ 1.2 ✲ 1.3 ✲ 1.4<br />

✲<br />

1.2.1.1<br />

1. 取 出 可 寫 入 的 版 本 1.2<br />

De-Yu Wang CSIE CYUT 193


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

✞<br />

[dywang@dywOffice testrcs]$ co -r1.2 -l important.c<br />

圲 RCS/important.c,v --> important.c<br />

revision 1.2 (locked)<br />

圴 done<br />

✡✝<br />

✆<br />

2. 如 果 沒 有 變 動 , 直 接 寫 入 , 不 會 產 生 版 本 1.2.1.1<br />

✞<br />

[dywang@dywOffice testrcs]$ ci important.c<br />

圲 RCS/important.c,v important.c<br />

revision 1.2 (locked)<br />

圴 done<br />

[dywang@dywOffice testrcs]$ vi important.c<br />

圶 [dywang@dywOffice testrcs]$ cat important.c<br />

圸<br />

/*<br />

圱 地 */<br />

This is an important file for managing the project.<br />

It implements the canoncial "Hello World" program.<br />

圱 圲 #include <br />

#include <br />

圱 圴<br />

int main()<br />

圱 圶 {<br />

printf("Hello World\n");<br />

圱 圸 printf("This is an extra line added later\n");<br />

printf("test for branch\n");<br />

圲 地<br />

}<br />

✡✝<br />

exit(EXIT_SUCCESS);<br />

✆<br />

4. 寫 入 產 生 版 本 1.2.1.1<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ ci important.c<br />

RCS/important.c,v


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

enter log message, terminated with single ’.’ or end of file:<br />

圵 >> test for branch<br />

>> .<br />

圷 done<br />

✡✝<br />

✆<br />

5. 查 看 版 本 訊 息<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rlog important.c<br />

圳 RCS file: RCS/important.c,v<br />

Working file: important.c<br />

圵 head: 1.3<br />

branch:<br />

圷 locks: strict<br />

access list:<br />

圹 symbolic names:<br />

keyword substitution: kv<br />

圱 圱 total revisions: 4; selected revisions: 4<br />

圱 圳<br />

description:<br />

This is an important demonstration file<br />

----------------------------<br />

圱 圵 revision 1.3<br />

date: 2008/03/06 03:17:00; author: dywang; state: Exp;<br />

lines: +1 -0<br />

圱 圷<br />

test for deletes<br />

----------------------------<br />

圱 圹 revision 1.2<br />

date: 2008/03/05 06:23:52; author: dywang; state: Exp;<br />

lines: +1 -0<br />

圲 圱 branches: 1.2.1;<br />

Added an extra line to be printed out<br />

圲 圳 ----------------------------<br />

revision 1.1<br />

圲 圵 date: 2008/03/05 06:06:15; author: dywang; state: Exp;<br />

Initial revision<br />

圲 圷 ----------------------------<br />

revision 1.2.1.1<br />

圲 圹 date: 2008/03/06 05:07:38; author: dywang; state: Exp;<br />

lines: +1 -0<br />

test for branch<br />

圳 圱 =======================================================================<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 如 何 以 rcs 指 令 初 始 程 式 important.c 的 RCS 管 理 檔 案 。<br />

Sol. rcs -i important.c<br />

De-Yu Wang CSIE CYUT 195


10.2. RCS 基 本 功 能 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

2. 若 程 式 檔 名 為 important.c , 則 其 RCS 管 理 檔 案 ( archive file ) 檔 名 為<br />

何 <br />

Sol. important.c,v<br />

3. 以 rcs 指 令 初 始 RCS 管 理 檔 案 或 以 ci 指 令 寫 入 RCS 管 理 檔 案 , 會 被 要<br />

求 輸 入 附 記 , 請 問 如 何 結 束 輸 入 <br />

Sol. 輸 入 一 點 (.), 或 按 鍵 Ctrl+D。<br />

4. 如 果 希 望 RCS 的 管 理 檔 案 自 動 存 放 在 一 個 子 目 錄 , 則 必 須 建 立 怎 樣 的 子 目<br />

錄 <br />

Sol. 檔 名 為 RCS ( 不 可 為 小 寫 ) 的 子 目 錄 。<br />

5. 如 何 將 程 式 important.c 從 RCS 管 理 檔 案 中 讀 出 。<br />

Sol. co important.c<br />

6. 如 何 將 程 式 important.c 從 RCS 管 理 檔 案 中 讀 出 , 且 鎖 定 取 出 版 本 。<br />

Sol. co -l important.c<br />

7. 如 果 從 RCS 管 理 檔 案 中 讀 出 的 程 式 important.c 屬 性 為 -r--r--r--, 則<br />

取 出 版 本 是 否 鎖 定 <br />

Sol. 沒 鎖 定<br />

8. 如 果 從 RCS 管 理 檔 案 中 讀 出 的 程 式 important.c 屬 性 為 -rw-r--r--, 則<br />

取 出 版 本 是 否 鎖 定 <br />

Sol. 已 鎖 定<br />

9. 將 修 改 後 的 程 式 important.c 存 入 RCS 管 理 檔 案 後 , 檔 案 important.c<br />

是 否 存 在 <br />

Sol. 不 存 在<br />

10. 有 那 兩 種 狀 況 ,RCS 會 自 動 要 求 輸 入 版 本 的 附 註 ( log )<br />

Sol. 1. 初 始 RCS 管 理 檔 案 ;2. 寫 入 管 理 檔 案 。<br />

11. 如 何 使 用 指 令 ci, 將 程 式 important.c 的 版 本 附 註 "test for log" 直 接<br />

寫 入 管 理 檔 案 中 , 而 不 會 再 產 生 提 示 訊 息 <br />

Sol. ci -m"test for log" important.c<br />

12. 如 何 使 用 指 令 rlog, 查 詢 程 式 important.c 修 改 的 摘 要 <br />

Sol. rlog important.c<br />

13. 使 用 指 令 rlog, 查 詢 程 式 important.c 修 改 的 摘 要 , 在 版 本 1.2 中 , 有<br />

一 行 行 尾 出 現 "lines: +1 -0", 代 表 意 義 為 何 <br />

Sol. 表 示 增 加 了 一 行 , 但 沒 有 刪 除 任 何 行 。<br />

14. 如 何 使 用 指 令 rlog, 查 詢 程 式 important.c 附 記 的 標 頭 ( header )<br />

Sol. rlog -h important.c<br />

15. 如 何 使 用 指 令 rlog, 查 詢 程 式 important.c 之 管 理 檔 案 之 路 徑 與 名 稱 <br />

Sol. rlog -R important.c<br />

De-Yu Wang CSIE CYUT 196


10.3. 識 別 關 鍵 字 串 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

16. 如 何 使 用 指 令 rlog, 查 詢 程 式 important.c 附 記 的 標 頭 ( header ) + 描<br />

述 ( description )<br />

Sol. rlog -t important.c<br />

17. 使 用 rlog 指 令 , 查 看 檔 案 important.c 附 註 時 , 出 現 locks: strict,<br />

代 表 意 義 為 何 <br />

Sol. 鎖 住 方 式 為 strict<br />

18. 使 用 rlog 指 令 , 查 看 檔 案 important.c 附 註 時 , 出 現 keyword<br />

substitution: kv, 代 表 意 義 為 何 <br />

Sol. 識 別 關 鍵 字 串 解 釋 方 式 為 kv<br />

19. 如 果 以 指 令 co important.c 讀 出 程 式 important.c, 修 改 後 以 指 令 寫 入<br />

RCS 管 理 檔 案 , 會 出 現 什 麼 狀 況 <br />

Sol. 沒 有 鎖 住 , 故 無 法 存 入 。<br />

20. 當 從 RCS 管 理 檔 案 中 讀 出 版 本 1.2 之 程 式 important.c, 但 未 鎖 住 , 修 改<br />

後 要 如 何 寫 入 RCS 管 理 檔 案 <br />

Sol. 先 執 行 指 令 rcs -l1.2 important.c 鎖 住 , 再 寫 入 。<br />

21. 如 何 從 RCS 管 理 檔 案 中 , 刪 除 版 本 1.3 之 程 式 important.c<br />

Sol. rcs -o1.3 important.c<br />

22. 如 何 從 RCS 管 理 檔 案 中 , 解 除 版 本 1.3 之 程 式 important.c 鎖 住 <br />

Sol. rcs -u1.3 important.c<br />

23. 如 果 在 版 本 1.2 產 生 版 本 1.3 之 後 , 要 版 本 1.2 處 產 生 分 支 , 則 分 支 之<br />

序 號 為 何 <br />

Sol. 1.2.1.1<br />

24. 如 果 從 RCS 管 理 檔 案 中 , 讀 出 版 本 1.3 之 程 式 important.c, 未 經 修 改 的<br />

情 況 下 寫 入 管 理 檔 案 , 是 否 會 產 生 新 的 版 本 <br />

Sol. 不 會<br />

25. 如 果 從 RCS 管 理 檔 案 中 , 最 新 版 本 為 1.6 , 現 在 讀 出 版 本 1.4 之 程 式<br />

important.c, 修 改 後 再 寫 入 管 理 檔 案 , 產 生 的 新 版 本 序 號 為 何 <br />

Sol. 1.4.1.1<br />

10.3 識 別 關 鍵 字 串<br />

• RCS 提 供 識 別 關 鍵 字 串 ( IdKeyword ), 幫 助 使 用 者 產 生 各 版 本 的 相 關 資 訊 ,<br />

這 些 識 別 關 鍵 字 串 都 是 用 符 號 $ 夾 住 以 供 RCS 辨 識 。<br />

• 各 IdKeyword 代 表 意 義 :<br />

keyword 相 關 資 訊<br />

----------------------------------------------------------<br />

De-Yu Wang CSIE CYUT 197


10.3. 識 別 關 鍵 字 串 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

$Author$ 寫 入 該 版 本 的 作 者<br />

$Date$ 日 期 和 時 間 ( UTC )<br />

$Header$ RCS 檔 名 ( 含 路 徑 )+ 版 本 (Revision)+ 日 期 (Date)<br />

+ 作 者 (Author)+ 狀 態 (State)+ 正 lock 該 檔 案 者 (Locker)<br />

$Id$ 除 RCS 檔 名 不 含 路 徑 外 , 餘 與 $Header$ 相 同<br />

$Locker$ 目 前 lock 住 該 檔 案 者 , 如 未 lock , 則 空 白<br />

$Log$ 關 於 該 版 本 的 log 的 訊 息<br />

$Name$ 標 記 名 稱<br />

例 如 : 執 行 co -r first, 則 $Name$ 展 開<br />

為 ‘Name: first’.<br />

$RCSfile$ RCS 檔 名 ( 不 含 路 徑 )<br />

$Revision$ 版 本 序 號<br />

$Source$ RCS 檔 名 ( 含 路 徑 )<br />

$State$ 狀 態 :Exp (for experimental), Stab (for stable),<br />

and Rel (for released)<br />

• IdKeyword 的 使 用 : 通 常 加 在 程 式 檔 案 的 檔 頭<br />

1. 讀 出 並 鎖 定 important.c。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ co -l important.c<br />

RCS/important.c,v --> important.c<br />

圳 revision 1.4 (locked)<br />

done<br />

✡✝<br />

✆<br />

2. 在 important.c 的 檔 頭 加 上 $Id$<br />

✞<br />

[dywang@dywOffice testrcs]$ vi important.c<br />

圲 [dywang@dywOffice testrcs]$ cat important.c<br />

/*<br />

圴 * $Id$<br />

This is an important file for managing the project.<br />

圶 It implements the canoncial "Hello World" program.<br />

*/ 以 下 省 略<br />

✡✝<br />

✆<br />

3. 將 important.c 寫 入 archive file。<br />

✞<br />

[dywang@dywOffice testrcs]$ ci -m"test for IdKeyword"<br />

important.c<br />

圲 RCS/important.c,v


10.3. 識 別 關 鍵 字 串 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

4. 再 將 important.c 從 archive file 讀 出 , 則 $Id$ 代 表 的 相 關 資<br />

訊 , 會 被 加 在 $ 符 號 裡 面 。<br />

✞<br />

[dywang@dywOffice testrcs]$ co -l important.c<br />

圲 RCS/important.c,v --> important.c<br />

revision 1.5 (locked)<br />

圴<br />

done<br />

[dywang@dywOffice testrcs]$ cat important.c<br />

圶 /*<br />

* $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $<br />

圸<br />

圱 地<br />

This is an important file for managing the project.<br />

It implements the canoncial "Hello World" program.<br />

*/ 以 下 省 略<br />

圱 圲 # RCS 檔 名 不 含 路 徑 ():important.c,v<br />

# 版 本 (Revision):1.5<br />

圱 圴 # 日 期 與 時 間 (Date):2008/03/07 03:30:31<br />

# 作 者 (Author):dywang<br />

圱 圶 # 狀 態 (State):Exp<br />

# 目 前 lock 住 該 檔 案 者 (locker):dywang<br />

✡✝<br />

✆<br />

• RCS 如 何 來 解 釋 各 個 識 別 關 鍵 字 串 ( IdKeyword )<br />

Option 解 釋 方 式<br />

說 明<br />

-----------------------------------------------------<br />

-kkv keyword+ 相 關 資 訊 default 的 解 釋 方 式<br />

-kkvl keyword+ 相 關 資 訊 +locker 如 -kkv 再 加 上 locker<br />

-kk keyword 只 顯 示 keyword 不 加 解 釋<br />

-kv 相 關 資 訊 只 顯 示 相 關 資 訊 不 加 keyword<br />

1. 以 -kk 選 項 登 出 檔 案 ( unlock )<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ co -kk important.c<br />

RCS/important.c,v --> important.c<br />

圳 revision 1.5<br />

done<br />

圵 [dywang@dywOffice testrcs]$ cat important.c<br />

/*<br />

圷 * $Id$<br />

This is an important file for managing the project.<br />

圹 It implements the canoncial "Hello World" program.<br />

*/ 以 下 省 略<br />

✡✝<br />

✆<br />

2. 以 -kv 選 項 登 出 檔 案 ( unlock )<br />

De-Yu Wang CSIE CYUT 199


10.3. 識 別 關 鍵 字 串 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ co -kv important.c<br />

RCS/important.c,v --> important.c<br />

圳 revision 1.5<br />

done<br />

圵 [dywang@dywOffice testrcs]$ cat important.c<br />

/*<br />

圷 * important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

This is an important file for managing the project.<br />

圹 It implements the canoncial "Hello World" program.<br />

*/ 以 下 省 略<br />

✡✝<br />

✆<br />

• ident 命 令 : 找 出 檔 案 中 之 IdKeyword。<br />

1. IdKeyword 只 存 在 於 註 解 中 , 則 編 譯 完 之 目 標 檔 important.o 及 可 執<br />

行 檔 important 中 不 會 有 IdKeyword<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ gcc -c important.c; gcc -o<br />

important important.o<br />

[dywang@dywOffice testrcs]$ ident important.c important.o<br />

important<br />

圳 important.c:<br />

$Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $<br />

圵<br />

important.o:<br />

圷 ident warning: no id keywords in important.o<br />

圹<br />

important:<br />

ident warning: no id keywords in important<br />

✡✝<br />

✆<br />

2. 編 輯 程 式 important.c, 加 入 字 串 變 數 rcsid[] = "$Id$"<br />

✞<br />

[dywang@dywOffice testrcs]$ vi important.c<br />

圲 [dywang@dywOffice testrcs]$ cat important.c<br />

/*<br />

圴 * $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $<br />

This is an important file for managing the project.<br />

圶 It implements the canoncial "Hello World" program.<br />

*/<br />

圸<br />

#include <br />

圱 地 #include <br />

static char const rcsid[] = "$Id$";<br />

圱 圲<br />

int main()<br />

De-Yu Wang CSIE CYUT 200


10.3. 識 別 關 鍵 字 串 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圱 圴 {<br />

圱 圶<br />

圱 圸<br />

圲 地<br />

}<br />

✡✝<br />

printf("Hello World\n");<br />

printf("This is an extra line added later\n");<br />

printf("test for lock\n");<br />

printf("test for comment\n");<br />

printf("%s\n", rcsid);<br />

exit(EXIT_SUCCESS);<br />

✆<br />

3. 寫 入 important.c,v 後 再 讀 出 , 得 到 $Id$ 之 相 關 資 訊<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ ci important.c<br />

RCS/important.c,v > test ident on object files<br />

>> .<br />

圷 done<br />

[dywang@dywOffice testrcs]$ co -l important.c<br />

圹 RCS/important.c,v --> important.c<br />

revision 1.6 (locked)<br />

圱 圱 done<br />

[dywang@dywOffice testrcs]$ cat important.c<br />

圱 圳 /*<br />

* $Id: important.c,v 1.6 2008/03/12 01:51:38 dywang Exp<br />

dywang $<br />

圱 圵 This is an important file for managing the project.<br />

It implements the canoncial "Hello World" program.<br />

圱 圷 */<br />

圱 圹 #include <br />

#include <br />

圲 圱 static char const rcsid[] =<br />

"$Id: important.c,v 1.6 2008/03/12 01:51:38 dywang Exp<br />

dywang $";<br />

圲 圳<br />

int main()<br />

圲 圵 {<br />

printf("Hello World\n");<br />

圲 圷 printf("This is an extra line added later\n");<br />

printf("test for lock\n");<br />

圲 圹 printf("test for comment\n");<br />

printf("%s\n", rcsid);<br />

圳 圱<br />

}<br />

✡✝<br />

exit(EXIT_SUCCESS);<br />

✆<br />

4. 編 譯 important.c, 產 生 目 標 檔 important.o 及 可 執 行 檔<br />

important。<br />

De-Yu Wang CSIE CYUT 201


10.3. 識 別 關 鍵 字 串 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

✞<br />

[dywang@dywOffice testrcs]$ gcc -c important.c; gcc -o<br />

important important.o<br />

✡✝<br />

✆<br />

5. IdKeyword 字 串 已 被 結 合 到 目 標 檔 important.o 及 可 執 行 檔<br />

important 之 中 。 以 指 令 ident 查 看 :<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ ident important.c important.o<br />

important<br />

important.c:<br />

圳 $Id: important.c,v 1.6 2008/03/12 01:51:38 dywang Exp<br />

dywang $<br />

$Id: important.c,v 1.6 2008/03/12 01:51:38 dywang Exp<br />

dywang $<br />

圵<br />

important.o:<br />

圷 $Id: important.c,v 1.6 2008/03/12 01:51:38 dywang Exp<br />

dywang $<br />

圹<br />

important:<br />

$Id: important.c,v 1.6 2008/03/12 01:51:38 dywang Exp<br />

dywang $<br />

✡✝<br />

✆<br />

• make 配 合 RCS 產 生 可 執 行 檔<br />

1. 刪 除 important.c<br />

✞<br />

[dywang@dywOffice testrcs]$ rm -f important.c<br />

✡✝<br />

✆<br />

2. 若 important.c 不 存 在 , 則 make 會 利 用 RCS, 從 important.c,v<br />

讀 出 最 新 版 本 , 產 生 important.c, 並 進 行 編 譯 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ make important<br />

co RCS/important.c,v important.c<br />

圳 RCS/important.c,v --> important.c<br />

revision 1.5<br />

圵 done<br />

cc -c -o important.o important.c<br />

圷 cc important.o -o important<br />

rm important.o important.c<br />

✡✝<br />

✆<br />

3. make 在 編 譯 產 生 可 執 行 檔 important 後 , 再 刪 除 important.o 及<br />

important.c 檔 案 。<br />

De-Yu Wang CSIE CYUT 202


10.3. 識 別 關 鍵 字 串 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

✞<br />

[dywang@dywOffice testrcs]$ ll<br />

圲 total 20<br />

-rw-r--r-- 1 dywang users 21 Mar 7 10:16 commentfile<br />

圴 -rwxr-xr-x 1 dywang users 6850 Mar 11 15:23 important*<br />

-rw-r--r-- 1 dywang users 341 Mar 7 11:29 important.c~<br />

圶 drwxr-xr-x 2 dywang users 4096 Mar 11 15:23 RCS/<br />

✡✝<br />

✆<br />

練 習 題<br />

1. RCS 識 別 關 鍵 字 串 , 使 用 什 麼 符 號 夾 住 以 供 RCS 辨 識 <br />

Sol. $<br />

2. RCS 識 別 關 鍵 字 串 $Author$, 產 生 什 麼 資 訊 <br />

Sol. 寫 入 該 版 本 的 作 者<br />

3. RCS 識 別 關 鍵 字 串 $Date$, 產 生 什 麼 資 訊 <br />

Sol. 日 期 和 時 間 ( UTC )<br />

4. RCS 識 別 關 鍵 字 串 $Header$, 產 生 什 麼 資 訊 <br />

Sol. RCS 檔 名 ( 含 路 徑 )+ 版 本 (Revision)+ 日 期 (Date)+ 作 者 (Author)+ 狀<br />

態 (State)+ 正 鎖 住 該 檔 案 者 (Locker)<br />

5. RCS 識 別 關 鍵 字 串 $Id$, 產 生 什 麼 資 訊 <br />

Sol. RCS 檔 名 ( 不 含 路 徑 )+ 版 本 (Revision)+ 日 期 (Date)+ 作 者 (Author)+ 狀<br />

態 (State)+ 正 鎖 住 該 檔 案 者 (Locker)<br />

6. RCS 識 別 關 鍵 字 串 $Locker$, 產 生 什 麼 資 訊 <br />

Sol. 目 前 鎖 住 該 檔 案 者 , 如 未 鎖 住 , 則 空 白<br />

7. RCS 識 別 關 鍵 字 串 $Log$, 產 生 什 麼 資 訊 <br />

Sol. 關 於 該 版 本 的 附 註 訊 息<br />

8. RCS 識 別 關 鍵 字 串 $Name$, 產 生 什 麼 資 訊 <br />

Sol. 標 記 名 稱<br />

9. RCS 識 別 關 鍵 字 串 $RCSfile$, 產 生 什 麼 資 訊 <br />

Sol. RCS 檔 名 ( 不 含 路 徑 )<br />

10. RCS 識 別 關 鍵 字 串 $Revision$, 產 生 什 麼 資 訊 <br />

Sol. 版 本 序 號<br />

11. RCS 識 別 關 鍵 字 串 $Source$, 產 生 什 麼 資 訊 <br />

Sol. RCS 檔 名 ( 含 路 徑 )<br />

12. RCS 識 別 關 鍵 字 串 $State$, 產 生 什 麼 資 訊 <br />

Sol. 狀 態 ( 實 驗 、 穩 定 或 釋 出 )<br />

De-Yu Wang CSIE CYUT 203


10.3. 識 別 關 鍵 字 串 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

13. RCS 識 別 關 鍵 字 串 通 常 加 在 什 麼 地 方 <br />

Sol. 程 式 檔 案 的 檔 頭<br />

14. 在 程 式 中 加 入 RCS 識 別 關 鍵 字 串 $Id$, 寫 入 管 理 檔 案 後 再<br />

讀 出 , 出 現 $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $, 其 中 important.c,v 表 示 什 麼 訊 息 <br />

Sol. RCS 檔 名 ( 不 含 路 徑 ) 為 important.c,v<br />

15. 在 程 式 中 加 入 RCS 識 別 關 鍵 字 串 $Id$, 寫 入 管 理 檔 案 後 再<br />

讀 出 , 出 現 $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $, 其 中 1.5 表 示 什 麼 訊 息 <br />

Sol. 版 本 序 號 1.5<br />

16. 在 程 式 中 加 入 RCS 識 別 關 鍵 字 串 $Id$, 寫 入 管 理 檔 案 後 再<br />

讀 出 , 出 現 $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $, 其 中 2008/03/07 03:30:31 表 示 什 麼 訊 息 <br />

Sol. 日 期 2008/03/07, 時 間 03:30:31<br />

17. 在 程 式 中 加 入 RCS 識 別 關 鍵 字 串 $Id$, 寫 入 管 理 檔 案 後 再<br />

讀 出 , 出 現 $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $, 其 中 第 一 次 出 現 之 dywang 表 示 什 麼 訊 息 <br />

Sol. 作 者 (Author) 為 dywang<br />

18. 在 程 式 中 加 入 RCS 識 別 關 鍵 字 串 $Id$, 寫 入 管 理 檔 案 後 再<br />

讀 出 , 出 現 $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $, 其 中 Exp 表 示 什 麼 訊 息 <br />

Sol. 版 本 狀 態 為 實 驗 階 段<br />

19. 在 程 式 中 加 入 RCS 識 別 關 鍵 字 串 $Id$, 寫 入 管 理 檔 案 後 再<br />

讀 出 , 出 現 $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp<br />

dywang $, 其 中 第 二 次 出 現 之 dywang 表 示 什 麼 訊 息 <br />

Sol. 目 前 鎖 住 該 檔 案 者 為 dywang<br />

20. 從 RCS 管 理 檔 案 中 讀 出 程 式 important.c 時 , 如 何 以 keyword+ 相 關 資<br />

訊 , 顯 示 識 別 關 鍵 字 串 <br />

Sol. co -kkv important.c<br />

21. 從 RCS 管 理 檔 案 中 讀 出 程 式 important.c 時 , 預 設 之 識 別 關 鍵 字 串 解 釋 方<br />

式 為 何 <br />

Sol. co -kkv important.c, 以 keyword+ 相 關 資 訊 , 顯 示 識 別 關 鍵 字 串 。<br />

22. 從 RCS 管 理 檔 案 中 讀 出 程 式 important.c 時 , 如 何 以 keyword+ 相 關 資<br />

訊 +locker, 顯 示 識 別 關 鍵 字 串 <br />

Sol. co -kkvl important.c<br />

23. 從 RCS 管 理 檔 案 中 讀 出 程 式 important.c 時 , 如 何 只 以 keyword, 顯 示 識<br />

別 關 鍵 字 串 <br />

Sol. co -kk important.c<br />

De-Yu Wang CSIE CYUT 204


10.4. 標 記 符 號 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

24. 從 RCS 管 理 檔 案 中 讀 出 程 式 important.c 時 , 如 何 只 以 相 關 資 訊 , 顯 示 識<br />

別 關 鍵 字 串 <br />

Sol. co -kv important.c<br />

25. 若 識 別 關 鍵 字 串 只 存 在 於 程 式 important.c 之 註 解 中 , 則 編 譯 完 之 目 標<br />

檔 important.o 及 可 執 行 檔 important 中 會 不 會 有 識 別 關 鍵 字 串 之 相 關 資<br />

訊 <br />

Sol. 不 會<br />

26. 若 在 程 式 important.c 中 加 入 變 數 char rcsfile[] = "$RCSfile$";, 寫<br />

入 管 理 檔 案 後 , 再 以 預 設 解 釋 方 式 讀 出 、 編 譯 , 則 目 標 檔 important.o 及<br />

可 執 行 檔 important 中 之 之 變 數 rcsfile[] 內 容 為 何 <br />

Sol. $RCS important.c,v $<br />

27. 若 RCS 管 理 檔 案 important.c,v 存 在 , 但 程 式 important.c 並 未 讀 出 ,<br />

是 否 可 以 直 接 使 用 make 指 令 編 譯 可 執 行 檔 important 為 什 麼 <br />

Sol. 可 以 。make 會 從 important.c,v 讀 出 最 新 版 本 , 產 生<br />

important.c, 並 進 行 編 譯 , 在 編 譯 產 生 可 執 行 檔 important 後 , 再 刪<br />

除 important.o 及 important.c 檔 案 。<br />

10.4 標 記 符 號<br />

• 何 謂 標 記 符 號 ( mark symbol )<br />

1. 標 記 符 號 是 指 一 個 版 本 除 revision number 外 賦 予 的 符 號 名 稱 。<br />

2. 當 版 本 很 多 時 , 若 各 個 版 本 只 以 revision number 區 分 , 則 不 易 找 到<br />

其 中 特 定 的 版 本 。<br />

3. 因 為 只 從 revision number 很 難 知 道 該 版 本 的 內 容 , 故 RCS 提 供 自 訂<br />

版 本 標 記 符 號 之 功 能 , 以 利 了 解 各 版 本 之 關 係 。<br />

• 如 何 產 生 標 記 符 號 :<br />

1. 產 生 指 令 ci -n 加 入 或 之 後 用 rcs -n 加 入 , 一 般 建 議 的 形 式 是 用 數<br />

字 跟 下 底 線 "_" 來 建 構 標 記 符 號 , 例 如 sym1_0 sym1_0_1 等 。<br />

✞<br />

[dywang@dywOffice testrcs]$ rcs -nmarkSymbol1_6:1.6 important<br />

.c<br />

圲 RCS file: RCS/important.c,v<br />

done<br />

✡✝<br />

✆<br />

2. 除 RCS 的 特 殊 字 元 不 能 使 用 ( 包 括 $ ( 錢 字 號 ) ,( 逗 號 ) .( 句<br />

點 ) ;( 分 號 ) :( 冒 號 ) 以 及 @ 等 符 號 ) 外 , 不 限 制 符 號 的 形 式 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ ci -n$markSymbol_1 important.c<br />

ci: missing symbolic name after -n<br />

De-Yu Wang CSIE CYUT 205


10.4. 標 記 符 號 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圳 [dywang@dywOffice testrcs]$ ci -nmark,Symbol_1 important.c<br />

ci: invalid symbol ‘mark,Symbol_1’<br />

圵 ci aborted<br />

[dywang@dywOffice testrcs]$ ci -nmark.Symbol_1 important.c<br />

圷 ci: invalid symbol ‘mark.Symbol_1’<br />

ci aborted<br />

圹 [dywang@dywOffice testrcs]$ ci -nmark@Symbol_1 important.c<br />

ci: invalid symbol ‘mark@Symbol_1’<br />

圱 圱 ci aborted<br />

[dywang@dywOffice testrcs]$ ci -nmark$Symbol_1 important.c<br />

圱 圳 RCS/important.c,v


10.4. 標 記 符 號 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

Working file: important.c<br />

圵 head: 1.6<br />

branch:<br />

圷 locks: strict<br />

圹<br />

access list:<br />

symbolic names:<br />

r1_0_head: 1.2<br />

圱 圱 r1_0: 1.2<br />

mark: 1.6<br />

圱 圳 markSymbol1_6: 1.6<br />

keyword substitution: kv<br />

圱 圵 total revisions: 7<br />

===============================================================<br />

✡✝<br />

✆<br />

• 如 何 取 消 標 記 符 號 <br />

1. 以 rcs 指 令 取 消 標 記 符 號 : -n 直 接 接 要 取 消 的 標 記 , 而 不 接<br />

:[revision number]<br />

✞<br />

[dywang@dywOffice testrcs]$ rcs -nmark important.c<br />

圲 RCS file: RCS/important.c,v<br />

done<br />

✡✝<br />

✆<br />

2. 以 rlog 指 令 查 詢 產 生 的 標 記 符 號 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rlog -h important.c<br />

圳 RCS file: RCS/important.c,v<br />

Working file: important.c<br />

圵 head: 1.6<br />

branch:<br />

圷 locks: strict<br />

access list:<br />

圹 symbolic names:<br />

r1_0_head: 1.2<br />

圱 圱 r1_0: 1.2<br />

markSymbol1_6: 1.6<br />

圱 圳 keyword substitution: kv<br />

total revisions: 7<br />

圱 圵 ===============================================================<br />

✡✝<br />

✆<br />

3. 以 rcs 指 令 一 次 取 消 多 個 標 記 符 號<br />

De-Yu Wang CSIE CYUT 207


10.4. 標 記 符 號 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rcs -nr1_0 -nr1_0_head important.<br />

c<br />

RCS file: RCS/important.c,v<br />

圳 done<br />

✡✝<br />

✆<br />

4. 再 以 rlog 指 令 查 詢 , 只 剩 一 個 標 記 符 號 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rlog -h important.c<br />

圳 RCS file: RCS/important.c,v<br />

Working file: important.c<br />

圵 head: 1.6<br />

branch:<br />

圷 locks: strict<br />

access list:<br />

圹 symbolic names:<br />

markSymbol1_6: 1.6<br />

圱 圱 keyword substitution: kv<br />

total revisions: 7<br />

圱 圳 ===============================================================<br />

✡✝<br />

✆<br />

• 標 記 符 號 的 好 處 :<br />

1. 標 記 符 號 比 revision number 更 能 傳 達 該 版 本 的 特 性 , 例 如 : 若 版<br />

本 1.3 與 1.5 相 關 , 可 分 別 給 予 同 樣 式 的 標 記 符 號 r1_3 與 r1_5 標<br />

示 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rcs -nr1_3:1.3 -nr1_5:1.5<br />

important.c<br />

RCS file: RCS/important.c,v<br />

圳 done<br />

✡✝<br />

✆<br />

2. 以 rlog 指 令 查 詢 產 生 的 標 記 符 號 。<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rlog -h important.c<br />

圳 RCS file: RCS/important.c,v<br />

Working file: important.c<br />

圵 head: 1.6<br />

branch:<br />

圷 locks: strict<br />

access list:<br />

圹 symbolic names:<br />

De-Yu Wang CSIE CYUT 208


10.4. 標 記 符 號 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

r1_5: 1.5<br />

圱 圱 r1_3: 1.3<br />

markSymbol1_6: 1.6<br />

圱 圳 keyword substitution: kv<br />

total revisions: 7<br />

圱 圵 ===============================================================<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 何 謂 RSC 標 記 符 號 ( mark symbol )<br />

Sol. 標 記 符 號 是 指 一 個 版 本 除 版 本 序 號 外 賦 予 的 符 號 名 稱 。<br />

2. RCS 為 什 麼 要 使 用 標 記 符 號 ( mark symbol )<br />

Sol. 因 從 版 本 序 號 很 難 知 道 該 版 本 的 內 容 , 故 RCS 提 供 自 訂 版 本 標 記 符 號<br />

之 功 能 , 以 利 了 解 各 版 本 之 關 係 。<br />

3. 如 何 使 用 rcs 指 令 , 於 程 式 檔 案 important.c 版 本 1.5 中 , 加 入 標 記 符<br />

號 markS1_5<br />

Sol. rcs -nmarkS1_5:1.5 important.c<br />

4. 如 何 使 用 rcs 指 令 , 於 程 式 檔 案 important.c 版 本 1.6 中 , 加 入 標 記 符<br />

號 markS1_6<br />

Sol. rcs -nmarkS1_6:1.6 important.c<br />

5. 如 何 使 用 ci 指 令 , 於 程 式 檔 案 important.c 版 本 1.6 中 , 加 入 標 記 符 號<br />

markS1_6<br />

Sol. ci -nmarkS1_6:1.6 important.c<br />

6. 那 些 特 殊 字 元 , 不 可 使 用 於 RCS 標 記 符 號 <br />

Sol. $ , . ; : @ 六 個 符 號 。<br />

7. 指 令 ci -n$mS_1 important.c, 是 否 正 確 若 有 錯 , 請 說 明 為 什 麼 <br />

Sol. 錯 誤 , 標 記 符 號 不 可 使 用 $ 符 號 。<br />

8. 指 令 ci -nm,S_1 important.c, 是 否 正 確 若 有 錯 , 請 說 明 為 什 麼 <br />

Sol. 錯 誤 , 標 記 符 號 不 可 使 用 , 符 號 。<br />

9. 指 令 ci -nm.S_1 important.c, 是 否 正 確 若 有 錯 , 請 說 明 為 什 麼 <br />

Sol. 錯 誤 , 標 記 符 號 不 可 使 用 . 符 號 。<br />

10. 指 令 ci -nm;S_1 important.c, 是 否 正 確 若 有 錯 , 請 說 明 為 什 麼 <br />

Sol. 錯 誤 , 標 記 符 號 不 可 使 用 ; 符 號 。<br />

11. 指 令 ci -nm@S_1 important.c, 是 否 正 確 若 有 錯 , 請 說 明 為 什 麼 <br />

Sol. 錯 誤 , 標 記 符 號 不 可 使 用 @ 符 號 。<br />

De-Yu Wang CSIE CYUT 209


10.5. 版 本 比 較 與 整 合 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

12. 如 何 使 用 rcs 指 令 , 於 程 式 檔 案 important.c 版 本 1.6 中 , 同 時 加 入 兩<br />

個 標 記 符 號 markS1_6 及 markS1_6_0<br />

Sol. rcs -nmarkS1_6:1.6 -nmarkS1_6_0:1.6 important.c<br />

13. 如 何 使 用 rcs 指 令 , 同 時 於 程 式 檔 案 important.c , 版 本 1.3 中 加 入 標<br />

記 符 號 r1_3 及 版 本 1.5 中 加 入 標 記 符 號 r1_5 <br />

Sol. rcs -nr1_3:1.3 -nr1_5:1.5 important.c<br />

14. 執 行 rlog -h important.c, 出 現 symbolic names: r1_0_head: 1.2,<br />

代 表 意 義 為 何 <br />

Sol. 表 示 版 本 1.2 有 標 記 符 號 r1_0_head 。<br />

15. 如 何 使 用 rcs 指 令 , 取 消 程 式 檔 案 important.c 中 之 標 記 符 號<br />

markS1_6<br />

Sol. rcs -nmarkS1_6 important.c<br />

16. 如 何 使 用 rcs 指 令 , 取 消 程 式 檔 案 important.c 中 之 標 記 符 號<br />

markS1_6_0<br />

Sol. rcs -nmarkS1_6_0 important.c<br />

17. 如 何 使 用 rcs 指 令 , 一 次 取 消 程 式 檔 案 important.c 中 之 標 記 符 號 r1_0<br />

及 r1_0_had<br />

Sol. rcs -nr1_0 -nr1_0_head important.c<br />

10.5 版 本 比 較 與 整 合<br />

• 為 何 要 比 較 與 整 合 版 本 例 如 :<br />

1. 在 版 本 1.3 發 現 錯 誤 ( bug );<br />

2. 回 頭 找 尋 錯 誤 發 生 的 階 段 , 發 現 錯 誤 是 在 版 本 1.2;<br />

3. 在 除 錯 完 成 後 產 生 了 校 正 版 本 1.2.1.1。<br />

4. 如 果 版 本 1.3 已 經 完 成 某 個 階 段 性 的 目 標 且 棄 之 可 惜 , 則 可 用 整 合 (<br />

merge ) 的 功 能 將 版 本 1.2.1.1 和 版 本 1.2 的 不 同 處 與 版 本 1.3 整<br />

合 起 來 。<br />

1.1 ✲ 1.2 ✲ 1.3 ✲ ✲ 1.4<br />

merge<br />

✲ 1.2.1.1 ✑ ✑✑✸<br />

De-Yu Wang CSIE CYUT 210


10.5. 版 本 比 較 與 整 合 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

• 比 較 版 本 的 不 同<br />

1.1 ✲ 1.2 ✲ 1.3 · · · ✲ 1.6<br />

✲<br />

1.2.1.1<br />

✲<br />

working<br />

file<br />

1. rcsdiff 命 令 : 比 較 版 本 內 容 的 差 異 ( 包 括 IDKeyword), 以 瞭 解 兩 個 版<br />

本 間 哪 些 被 改 變 。<br />

✞<br />

圱 [root@dywHome2 ~]# rcsdiff [-kkkkvlr]<br />

-kk 比 較 版 本 內 容 的 差 異 不 包 括 ( IDKeyword)<br />

圳 -kkvl 指 定 IDKeyword 的 比 較 方 式 , 預 設 比 較 方 式 。<br />

-r 指 定 欲 比 較 版 本<br />

✡✝<br />

✆<br />

2. 都 不 指 定 版 本 時 ,rcsdiff 會 比 較 目 前 工 作 檔 案 與 主 幹 ( default<br />

branch ) 上 最 後 存 入 的 一 個 版 本 。<br />

✞<br />

[dywang@dywOffice testrcs]$ rcsdiff important.c<br />

圲 ===================================================================<br />

RCS file: RCS/important.c,v<br />

圴 retrieving revision 1.6<br />

diff -r1.6 important.c<br />

✡✝<br />

✆<br />

3. 目 前 工 作 檔 案 與 任 一 版 本 的 比 較<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rcsdiff -r1.3 important.c<br />

===================================================================<br />

圳 RCS file: RCS/important.c,v<br />

retrieving revision 1.3<br />

圵 diff -r1.3 important.c<br />

1a2<br />

圷 > * $Id: important.c,v 1.6 2008/03/12 01:51:38 dywang Exp<br />

dywang $<br />

圹<br />

# 1.3 版 的 第 1 行 後 , 插 入 了 新 的 第 2 行 。<br />

7a9<br />

> static char const rcsid[] = "$Id: important.c,v 1.6<br />

2008/03/12 01:51:38<br />

圱 圱 dywang Exp dywang $";<br />

# 1.3 版 的 第 7 行 後 , 插 入 了 新 的 第 9 行 。<br />

圱 圳 13a16,17<br />

De-Yu Wang CSIE CYUT 211


10.5. 版 本 比 較 與 整 合 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

> printf("test for comment\n");<br />

圱 圵 > printf("%s\n", rcsid);<br />

# 1.3 版 的 第 7 行 後 , 插 入 了 新 的 第 16,17 行 。<br />

✡✝<br />

✆<br />

4. 比 較 任 意 兩 個 版 本 :<br />

✞<br />

[dywang@dywOffice testrcs]$ rcsdiff -r1.3 -r1.4 important.c<br />

圲 ===================================================================<br />

RCS file: RCS/important.c,v<br />

圴 retrieving revision 1.3<br />

retrieving revision 1.4<br />

圶<br />

diff -r1.3 -r1.4<br />

13a14<br />

圸 > printf("test for comment\n");<br />

# 1.3 版 的 第 13 行 後 , 插 入 了 新 的 第 14 行 。<br />

✡✝<br />

✆<br />

5. 不 比 較 IdKeyword<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rcsdiff -r1.5 -r1.6 -kk important<br />

.c<br />

===================================================================<br />

圳 RCS file: RCS/important.c,v<br />

retrieving revision 1.5<br />

圵 retrieving revision 1.6<br />

diff -r1.5 -r1.6<br />

圷 8a9<br />

> static char const rcsid[] = "$Id$";<br />

圹 15a17<br />

> printf("%s\n", rcsid);<br />

✡✝<br />

✆<br />

6. 預 設 比 較 IdKeyword<br />

✞<br />

[dywang@dywOffice testrcs]$ rcsdiff -r1.5 -r1.6 -kkvl<br />

important.c<br />

圲 ===================================================================<br />

RCS file: RCS/important.c,v<br />

圴 retrieving revision 1.5<br />

retrieving revision 1.6<br />

圶<br />

diff -r1.5 -r1.6<br />

2c2<br />

圸 < * $Id: important.c,v 1.5 2008/03/07 03:30:31 dywang Exp $<br />

---<br />

De-Yu Wang CSIE CYUT 212


10.5. 版 本 比 較 與 整 合 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圱 地 > * $Id: important.c,v 1.6 2008/03/12 01:51:38 dywang Exp $<br />

8a9<br />

圱 圲 > static char const rcsid[] = "$Id: important.c,v 1.6<br />

2008/03/12 01:51:38<br />

dywang Exp $";<br />

圱 圴 15a17<br />

> printf("%s\n", rcsid);<br />

✡✝<br />

✆<br />

• 版 本 合 併<br />

1. rcsmerge 命 令 : 將 兩 版 本 內 容 的 差 異 整 合 到 工 作 檔 案 。<br />

✞<br />

圱 [root@dywHome2 ~]# rcsmerge [-kkkkvlr]<br />

-kk 整 合 檔 案 版 本 不 包 括 ( IDKeyword)<br />

圳 -kkvl 指 定 IDKeyword 的 整 合 方 式<br />

-r 整 合 檔 案 版 本 包 括 ( IDKeyword)<br />

✡✝<br />

✆<br />

2. 使 用 指 令 rcsmerge: 需 先 取 出 要 寫 入 的 版 本<br />

✞<br />

[dywang@dywOffice testrcs]$ co -l -r1.6 important.c<br />

圲 RCS/important.c,v --> important.c<br />

revision 1.6 (locked)<br />

圴 done<br />

[dywang@dywOffice testrcs]$ rcsmerge -r1.2 -r1.2.1.1<br />

important.c<br />

圶 RCS file: RCS/important.c,v<br />

retrieving revision 1.2<br />

圸 retrieving revision 1.2.1.1<br />

Merging differences between 1.2 and 1.2.1.1 into important.c<br />

圱 地 rcsmerge: warning: conflicts during merge<br />

✡✝<br />

✆<br />

3. 使 用 指 令 co -j : 在 從 archive file 中 取 出 工 作 檔 案 時 即 整 合 之<br />

✞<br />

[dywang@dywOffice testrcs]$ co -l -r1.6 -j1.2:1.2.1.1<br />

important.c<br />

圲 RCS/important.c,v --> important.c<br />

revision 1.6 (locked)<br />

圴 revision 1.2<br />

revision 1.2.1.1<br />

圶 merging...<br />

圸<br />

merge: warning: conflicts during merge<br />

done<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 213


10.5. 版 本 比 較 與 整 合 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

4. 使 用 指 令 co -j : 一 次 整 合 多 個 檔 案 的 相 異 處<br />

✞<br />

[dywang@dywOffice testrcs]$ co -l -r1.6 -j1.2:1.2.1.1,1.3:1.4<br />

important.c<br />

圲 RCS/important.c,v --> important.c<br />

revision 1.6 (locked)<br />

圴 revision 1.2<br />

revision 1.2.1.1<br />

圶 merging...<br />

merge: warning: conflicts during merge<br />

圸 revision 1.3<br />

revision 1.4<br />

圱 地 merging...<br />

圱 圲<br />

merge: warning: conflicts during merge<br />

done<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 請 舉 例 說 明 , 為 什 麼 RCS 要 比 較 與 整 合 版 本 <br />

Sol. 1. 若 在 版 本 1.3 發 現 bug;2. 發 現 錯 誤 來 自 版 本 1.2;3. 除 錯 完 成<br />

產 生 校 正 版 本 1.2.1.1。4. 比 較 版 本 1.2.1.1 和 版 本 1.2 的 不 同 , 並 與 版<br />

本 1.3 整 合 。<br />

2. 如 何 使 用 rcsdiff 指 令 , 比 較 目 前 工 作 檔 案 important.c 與 主 幹 上 最 後 存<br />

入 的 一 個 版 本 <br />

Sol. rcsdiff important.c 或 rcsdiff -kkvl important.c<br />

3. 如 何 使 用 rcsdiff 指 令 , 比 較 目 前 工 作 檔 案 important.c 與 主 幹 上 最 後 存<br />

入 的 一 個 版 本 , 且 不 包 括 識 別 關 鍵 字 串 <br />

Sol. rcsdiff -kk important.c<br />

4. 如 何 使 用 rcsdiff 指 令 , 比 較 目 前 工 作 檔 案 important.c 與 版 本 1.3<br />

Sol. rcsdiff -r1.3 important.c<br />

5. 如 何 使 用 rcsdiff 指 令 , 比 較 目 前 工 作 檔 案 important.c 與 版 本 1.3, 且<br />

不 包 括 識 別 關 鍵 字 串 <br />

Sol. rcsdiff -r1.3 -kk important.c<br />

6. 使 用 rcsdiff 指 令 , 出 現 訊 息 1a2 代 表 意 義 為 何 <br />

Sol. 兩 版 本 比 較 差 異 為 : 第 1 行 後 , 插 入 了 新 的 第 2 行 。<br />

7. 使 用 rcsdiff 指 令 , 出 現 訊 息 13a16,17 代 表 意 義 為 何 <br />

Sol. 兩 版 本 比 較 差 異 為 : 第 13 行 後 , 插 入 了 新 的 第 16 及 17 行 。<br />

8. 如 何 使 用 rcsdiff 指 令 , 比 較 工 作 檔 案 important.c 版 本 1.3 與 1.4<br />

Sol. rcsdiff -r1.3 -r1.4 important.c<br />

De-Yu Wang CSIE CYUT 214


10.6. 存 取 名 單 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

9. 如 何 使 用 rcsmerge 指 令 , 將 檔 案 important.c 版 本 1.2 與 1.2.1.1 之<br />

差 異 , 整 合 至 目 前 工 作 檔 案 <br />

Sol. rcsmerge -r1.2 -r1.2.1.1 important.c<br />

10. 如 何 使 用 rcsmerge 指 令 , 將 檔 案 important.c 版 本 1.2 與 1.2.1.1 之<br />

差 異 , 整 合 至 目 前 工 作 檔 案 , 且 不 包 括 識 別 關 鍵 字 串 <br />

Sol. rcsmerge -r1.2 -r1.2.1.1 -kk important.c<br />

11. 如 何 使 用 co 指 令 , 將 檔 案 important.c 版 本 1.2 與 1.2.1.1 之 差 異 ,<br />

在 鎖 定 方 式 讀 出 時 即 整 合 至 目 前 工 作 檔 案 <br />

Sol. co -l -j1.2:1.2.1.1 important.c<br />

12. 如 何 使 用 co 指 令 , 一 次 將 檔 案 important.c 版 本 1.2 與 1.2.1.1 之 差<br />

異 及 版 本 1.3 與 1.4 之 差 異 , 在 鎖 定 方 式 讀 出 時 即 整 合 至 目 前 工 作 檔 案 <br />

Sol. co -l -j1.2:1.2.1.1,1.3:1.4 important.c<br />

10.6 存 取 名 單<br />

• 設 定 存 取 名 單 : 只 有 記 錄 在 存 取 名 單 中 的 使 用 者 , 才 能 存 取 該 檔 案 的 版 本 。<br />

1. 將 使 用 者 加 入 可 存 取 名 單<br />

✞<br />

[dywang@dywOffice testrcs]$ rcs -adywang important.c<br />

圲 RCS file: RCS/important.c,v<br />

done<br />

圴 [dywang@dywOffice testrcs]$ cd ../testrcs1<br />

[dywang@dywOffice testrcs1]$ rcs -adywtest f.c<br />

圶 RCS file: f.c,v<br />

done<br />

✡✝<br />

✆<br />

2. 查 看 存 取 名 單<br />

✞<br />

圱 [dywang@dywOffice testrcs1]$ rlog -h f.c<br />

圳 RCS file: f.c,v<br />

Working file: f.c<br />

圵 head: 1.1<br />

branch:<br />

圷 locks: strict<br />

圹<br />

access list:<br />

dywtest<br />

symbolic names:<br />

圱 圱 abc_1: 1.1<br />

keyword substitution: kv<br />

圱 圳 total revisions: 1<br />

====================================================================<br />

De-Yu Wang CSIE CYUT 215


10.6. 存 取 名 單 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

圱 圵 [dywang@dywOffice testrcs]$ cd ../testrcs<br />

[dywang@dywOffice testrcs]$ rlog -h important.c<br />

圱 圷<br />

RCS file: RCS/important.c,v<br />

圱 圹 Working file: important.c<br />

head: 1.6<br />

圲 圱 branch:<br />

locks: strict<br />

圲 圳 access list:<br />

dywang<br />

圲 圵 symbolic names:<br />

r1_5: 1.5<br />

圲 圷 r1_3: 1.3<br />

markSymbol1_6: 1.6<br />

圲 圹 keyword substitution: kv<br />

total revisions: 7<br />

圳 圱 ===================================================================<br />

✡✝<br />

✆<br />

• 複 製 存 取 名 單 : 將 f.c 的 存 取 名 單 複 製 到 important.c。<br />

1. 複 製 存 取 名 單<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rcs -A../testrcs1/f.c important.c<br />

RCS file: RCS/important.c,v<br />

圳 done<br />

✡✝<br />

✆<br />

2. 查 看 存 取 名 單<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rlog -h important.c<br />

圳 RCS file: RCS/important.c,v<br />

Working file: important.c<br />

圵 head: 1.6<br />

branch:<br />

圷 locks: strict<br />

access list:<br />

圹<br />

dywang<br />

dywtest<br />

圱 圱 symbolic names:<br />

r1_5: 1.5<br />

圱 圳 r1_3: 1.3<br />

markSymbol1_6: 1.6<br />

圱 圵 keyword substitution: kv<br />

total revisions: 7<br />

圱 圷 ====================================================================<br />

De-Yu Wang CSIE CYUT 216


10.6. 存 取 名 單 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

✡✝<br />

✆<br />

• 移 除 存 取 名 單<br />

1. 將 使 用 者 dywtest 從 存 取 名 單 中 移 除<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rcs -edywtest important.c<br />

RCS file: RCS/important.c,v<br />

圳 done<br />

✡✝<br />

✆<br />

2. 查 看 存 取 名 單<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rlog -h important.c<br />

圳 RCS file: RCS/important.c,v<br />

Working file: important.c<br />

圵 head: 1.6<br />

branch:<br />

圷 locks: strict<br />

圹<br />

access list:<br />

dywang<br />

symbolic names:<br />

圱 圱 r1_5: 1.5<br />

r1_3: 1.3<br />

圱 圳 markSymbol1_6: 1.6<br />

keyword substitution: kv<br />

圱 圵 total revisions: 7<br />

====================================================================<br />

✡✝<br />

✆<br />

3. 將 存 取 名 單 全 部 移 除<br />

✞<br />

[dywang@dywOffice testrcs]$ rcs -e important.c<br />

圲 RCS file: RCS/important.c,v<br />

done<br />

✡✝<br />

✆<br />

4. 查 看 存 取 名 單<br />

✞<br />

圱 [dywang@dywOffice testrcs]$ rlog -h important.c<br />

圳 RCS file: RCS/important.c,v<br />

Working file: important.c<br />

圵 head: 1.6<br />

De-Yu Wang CSIE CYUT 217


10.6. 存 取 名 單 CHAPTER 10. *RCS 版 本 控 制 系 統<br />

branch:<br />

圷 locks: strict<br />

access list:<br />

圹 symbolic names:<br />

r1_5: 1.5<br />

圱 圱 r1_3: 1.3<br />

markSymbol1_6: 1.6<br />

圱 圳 keyword substitution: kv<br />

total revisions: 7<br />

圱 圵 ====================================================================<br />

✡✝<br />

✆<br />

練 習 題<br />

1. RCS 中 存 取 名 單 之 功 能 為 何 <br />

Sol. 只 有 記 錄 在 存 取 名 單 中 的 使 用 者 , 才 能 存 取 該 檔 案 的 版 本 。<br />

2. 如 何 使 用 rcs 指 令 , 將 使 用 者 csie 加 至 檔 案 important.c 的 存 取 名 單 <br />

Sol. rcs -acsie important.c<br />

3. 如 何 使 用 rlog 指 令 , 查 看 檔 案 important.c 的 存 取 名 單 <br />

Sol. rlog -h important.c<br />

4. 使 用 rlog 指 令 , 查 看 檔 案 important.c 附 註 時 , 出 現 access list:<br />

dywang, 代 表 意 義 為 何 <br />

Sol. 存 取 名 單 中 有 使 用 者 dywang<br />

5. 如 何 使 用 rcs 指 令 , 將 f.c 的 存 取 名 單 複 製 到 important.c<br />

Sol. rcs -Af.c important.c<br />

6. 如 何 使 用 rcs 指 令 , 將 使 用 者 dywtest 從 important.c 的 存 取 名 單 中 移<br />

除 <br />

Sol. rcs -edywtest important.c<br />

7. 如 何 使 用 rcs 指 令 , 將 所 有 使 用 者 從 important.c 的 存 取 名 單 中 移 除 <br />

Sol. rcs -e important.c<br />

De-Yu Wang CSIE CYUT 218


CHAPTER 11.<br />

* 使 用 QT 設 計 KDE 視 窗 程 式<br />

Chapter 11<br />

* 使 用 QT 設 計 KDE 視 窗 程 式<br />

11.1 KDE 和 QT 介 紹<br />

• KDE(K Desktop Environment)<br />

1. KDE 與 GNOME 是 現 今 <strong>Linux</strong> 上 , 兩 個 常 見 的 圖 形 化 使 用 者 介 面 。<br />

2. KDE 是 一 個 開 放 原 始 碼 的 桌 面 環 境 , 它 建 構 於 Qt GUI 函 式 庫 之 上 。<br />

3. KDE 也 提 供 很 多 應 用 程 式 和 工 具 , 包 含 完 整 的 辦 公 軟 體 、 網 頁 瀏 覽 器 、<br />

甚 至 設 計 KDE/Qt 應 用 程 式 的 IDE 工 具 。<br />

4. 因 為 蘋 果 電 腦 的 Mac OS X( 稱 為 Safari) 選 擇 使 用 KDE 網 頁 瀏 覽<br />

器 , 才 讓 業 界 開 始 認 識 KDE 應 用 程 式 。<br />

5. KDE 專 案 的 主 網 頁 , 可 以 找 到 很 多 詳 細 資 訊 、 也 可 以 下 載 KDE 和 KDE<br />

應 用 程 式 、 找 尋 文 件 、 參 與 郵 件 討 論 、 取 得 其 它 設 計 人 員 的 資 訊 。<br />

6. KDE 工 藝 網 頁 , 可 以 下 載 KDE 樣 式 、 按 鈕 、 顏 色 、 桌 面 圖 片 ... 等 材<br />

枓 , 來 裝 飾 KDE。<br />

• GUI 開 發 工 具 :Qt<br />

1. Qt 是 挪 威 公 司 Trolltech 以 C++ 設 計 的 一 種 GUI 開 發 工 具 。<br />

2. Qt 具 有 跨 平 台 的 功 能 , 支 援 <strong>Linux</strong>、UNIX、Windows、Mac OS X、 甚 至<br />

嵌 入 式 的 版 本 。<br />

3. Qt 的 商 業 版 價 格 相 當 高 , 但 Trolltech 另 外 提 供 <strong>Linux</strong>、Windows 和<br />

MacOS 上 的 Qt 免 費 版 本 。<br />

4. Trolltech 的 網 頁 提 供 一 些 API 文 件 。<br />

• QT Designer<br />

1. QT Designer 是 一 個 GUI 的 工 具 。<br />

2. QT Designer 利 用 所 見 既 所 得 的 方 式 , 產 生 QT 程 式 的 GUI 程 式 碼 。<br />

3. 利 用 QT Designer 可 快 速 的 設 計 軟 體 GUI, 再 撰 寫 GUI 相 關 動 作 之 程<br />

式 碼 , 即 可 產 生 一 互 動 式 之 軟 體 。<br />

De-Yu Wang CSIE CYUT 219


11.2. QT 開 發 環 境 建 立 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

• KDE 程 式 開 發 環 境 :KDevelop<br />

1. KDevelop 是 一 個 C 和 C++ 程 式 的 IDE 工 具 。<br />

2. KDevelop 是 一 個 自 由 軟 體 , 下 載 網 站 。<br />

3. KDevelop 包 含 文 件 的 樣 版 、GPL 授 權 文 字 和 一 般 的 安 裝 說 明 。<br />

• 其 它 環 境<br />

環 境 型 態 產 品 的 URL<br />

gbuilder GNOME 的 IDE 開 發 環 境 http:// gbuilder.sourceforge.net/<br />

Anjuta GNOME 的 IDE 開 發 環 境 http:// anjuta.sourceforge.net/<br />

Klint KDE 的 IDE 開 發 環 境 http:// klint.sourceforge.net/<br />

QtEZ KDE 的 IDE 開 發 環 境 http://projects.uid0.sk/qtez/index.php<br />

RHIDE 文 字 模 式 的 IDE 開 發 環 境 http://www.rhide.com/<br />

CRiSP 商 用 的 程 式 設 計 編 輯 器 http://www.crisp.com/<br />

SlickEdit 商 用 的 多 程 式 設 計 編 輯 器 http://www.slickedit.com/<br />

Kylix 商 用 的 C++ 和 Delphi 的 http://www.borland.com/kylix<br />

IDE 開 發 環 境<br />

Eclipse Java 工 具 平 台 和 IDE http://www.eclipse.org<br />

練 習 題<br />

1. 請 現 今 <strong>Linux</strong> 上 , 兩 個 常 見 的 圖 形 化 使 用 者 介 面 。<br />

Sol. KDE 與 GNOME<br />

2. <strong>Linux</strong> KDE 圖 形 介 面 建 構 於 什 麼 GUI 函 式 庫 上 <br />

Sol. QT<br />

3. <strong>Linux</strong> GNOME 圖 形 介 面 建 構 於 什 麼 GUI 函 式 庫 上 <br />

Sol. gtk<br />

4. Qt 是 挪 威 公 司 Trolltech 以 什 麼 程 式 語 言 設 計 的 一 種 GUI 開 發 工 具 <br />

Sol. C++<br />

5. QT Designer 用 途 為 何 <br />

Sol. 利 用 所 見 既 所 得 的 方 式 , 產 生 QT 程 式 的 GUI 程 式 碼 。<br />

11.2 Qt 開 發 環 境 建 立<br />

• QT3 designer<br />

1. 安 裝 QT3 套 件 :<br />

✞<br />

圱 [root@dywHome2 ~]# urpmi libqt3-devel<br />

To satisfy dependencies, the following packages are going to<br />

be installed:<br />

圳 libqt3-3.3.6-18.4mdv2007.0.i586<br />

De-Yu Wang CSIE CYUT 220


11.2. QT 開 發 環 境 建 立 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

libqt3-devel-3.3.6-18.4mdv2007.0.i586<br />

圵 qt3-common-3.3.6-18.4mdv2007.0.i586<br />

Proceed with the installation of the 3 packages (16 MB) (Y/n<br />

)<br />

圷 # urpmi 會 自 動 將 相 關 相 依 套 件 一 併 安 裝<br />

✡✝<br />

✆<br />

2. 檢 查 QTDIR 環 境 變 數 是 否 設 定 到 Qt 的 安 裝 目 錄 :<br />

✞<br />

圱 [root@dywHome2 ~]# echo $QTDIR<br />

/usr/lib/qt3/<br />

✡✝<br />

✆<br />

3. 執 行 命 令 :<br />

✞<br />

[dywang@dywOffice ~]$ ll /usr/bin/designer-qt3<br />

圲 lrwxrwxrwx 1 root root 30 Jan 14 10:48 /usr/bin/designer-qt3<br />

-><br />

../../usr/lib/qt3/bin/designer*<br />

圴 [dywang@dywOffice ~]$ designer-qt3<br />

✡✝<br />

✆<br />

4. 執 行 畫 面 :<br />

• 實 例 :QmainWindow 程 式<br />

1. 輸 入 以 下 程 式 qt1.cpp:<br />

De-Yu Wang CSIE CYUT 221


11.2. QT 開 發 環 境 建 立 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

✞<br />

#include <br />

圲 #include <br />

int main(int argc, char **argv)<br />

圴 {<br />

QApplication app(argc, argv);<br />

圶 QMainWindow window();<br />

app.setMainWidget(window);<br />

圸 window.show();<br />

return app.exec();<br />

圱 地 }<br />

✡✝<br />

✆<br />

2. 編 譯 時 , 需 要 引 用 Qt 的 include 和 lib 目 錄 :<br />

✞<br />

$ g++ -o qt1 qt1.cpp -I$QTDIR/include -L$QTDIR/lib -lqt-mt<br />

✡✝<br />

✆<br />

3. 執 行 這 個 應 用 程 式 , 看 到 一 個 Qt 視 窗 。<br />

✞<br />

圱 $ ./qt1<br />

✡✝<br />

✆<br />

• QmainWindow 程 式 說 明<br />

1. 每 個 Qt 應 用 程 式 必 須 有 一 個 QApplication 物 件 , 且 必 須 在 進 行 其 它<br />

工 作 前 產 生 。<br />

2. QApplication 會 處 理 內 部 的 Qt 運 作 , 例 如 事 件 處 理 、 地 區 語 言 處 理<br />

(localization) 和 控 制 視 窗 外 觀 。<br />

3. QApplication 的 操 作 函 式 :<br />

(a) setMainWidget: 設 定 應 用 程 式 的 主 要 widget;<br />

(b) exec: 開 始 事 件 的 迴 圈 。exec 在 QApplication::quit() 被 呼 叫<br />

前 或 是 主 要 widget 被 關 閉 前 , 都 不 會 回 覆 。<br />

4. QMainWindow 是 基 礎 的 Qt 視 窗 widget, 它 支 援 選 單 、 工 具 列 和 狀 態<br />

列 。<br />

De-Yu Wang CSIE CYUT 222


11.3. GTK+ 開 發 環 境 建 立 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

11.3 gtk+ 開 發 環 境 建 立<br />

1. 安 裝 Glade 套 件 :<br />

✞<br />

圱 [root@dywHome2 ~]# [root@deyu ~]# yum install glade3<br />

✡✝<br />

✆<br />

圱<br />

2. 執 行 glade designer<br />

✞<br />

圖 形 界 面<br />

圳<br />

Applications->Programming->Glade Interface Designer 文 字 界 面<br />

圵<br />

[dywang@deyu glade]$ glade-3<br />

✡✝<br />

✆<br />

3. 相 關 聯 結<br />

(a) GTK+ and Glade3 GUI Programming Tutorial<br />

(b) 用 Libglade 快 速 開 發 GTK+ 視 窗 程 式<br />

(c) Calculator Program using Python and Glade<br />

(d) Python 教 學<br />

4. 下 載 範 例 檔 Calculator Program Download<br />

5. 以 glade-3 開 啟 calculator.glade<br />

✞<br />

1. table1 Rows: 5 -> 6<br />

圲 2. insert ok button in table1 (0,5)<br />

3. rename ok button Label and Name to Sqrt<br />

圴 4. set Sqrt button clicked Signals to on_Sqrt_clicked<br />

5. vim calculatorglade.py<br />

圶<br />

# coding: utf-8<br />

圸 import sys<br />

import math # 匯 入 數 學 模 組<br />

圱 地 try:<br />

import pygtk<br />

圱 圲 pygtk.require(’2.0’)<br />

except:<br />

圱 圴 pass<br />

.... omission ....<br />

圱 圶<br />

class Calculator:<br />

圱 圸 .... omission ....<br />

"on_Add_clicked" : self.displayAdd,<br />

De-Yu Wang CSIE CYUT 223


11.4. SIGNALS 和 SLOTS CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

圲 地<br />

.... omission ....<br />

"on_Sqrt_clicked" : self.displaySqrt, # 定 義 按 鈕 接 受 函<br />

數 sqrt<br />

圲 圲<br />

if operator == ’Sqrt’:<br />

self.firstOperand = self.wTree.get_widget("<br />

displayText").get_text()<br />

圲 圴<br />

result = math.sqrt(float(self.firstOperand))<br />

self.wTree.get_widget("displayText").set_text(str(<br />

result))<br />

圲 圶 .... omission ....<br />

圲 圸<br />

✡✝<br />

def displaySqrt(self,widget): # 定 義 函 數 displaySqrt<br />

self.compute("Sqrt")<br />

✆<br />

6. 執 行<br />

✞<br />

圱 [dywang@deyu glade]$ python calculatorglade.py<br />

✡✝<br />

✆<br />

11.4 Signals 和 Slots<br />

• 何 謂 signals 和 slots<br />

1. Qt 信 號 處 理 的 機 制 。<br />

2. GUI 應 用 程 式 利 用 signals 和 slots 來 回 應 使 用 者 輸 入 。<br />

3. 在 Qt 中 ,signals 和 slots 為 巨 集 關 鍵 字 。<br />

• Signal/slot 與 widget<br />

1. Widget 為 選 單 、 工 具 列 、 按 鈕 、 輸 入 窗 等 GUI 元 件 。<br />

2. 當 使 用 者 與 widget 互 動 時 ,widget 會 發 出 一 個 signal。<br />

3. 將 signal 連 結 到 一 個 回 呼 函 式 slot。<br />

4. 執 行 回 呼 函 式 slot 指 定 動 作 。<br />

• 類 別 使 用 signals 和 slots 成 員 函 式 的 限 制 :<br />

1. 必 須 繼 承 自 QObject 類 別 (class)。<br />

2. 一 定 要 使 用 Q_OBJECT 巨 集 (macro), 即 Q_OBJECT 必 須 出 現 在 類 別<br />

定 義 中 。<br />

3. signals 和 slots 的 參 數 不 可 使 用 函 式 指 標 。<br />

• 類 別 使 用 signals 和 slots 成 員 函 式 :<br />

De-Yu Wang CSIE CYUT 224


11.4. SIGNALS 和 SLOTS CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

1. 編 輯 類 別 定 義 MyWindow.h。<br />

✞<br />

圱 # MyWindow 繼 承 類 別 , 提 供 應 用 程 式 的 主 要 視 窗 功 能 。 QMainWindow<br />

# 若 需 要 一 個 對 話 窗 , 要 繼 承 。 QDialog<br />

圳 class MyWindow : public QMainWindow<br />

{<br />

圵 Q_OBJECT<br />

public:<br />

圷 MyWindow();<br />

virtual ~MyWindow();<br />

圹 signals:<br />

void A_Signal();<br />

圱 圱 # signals A_Signal() 沒 指 定 參 數<br />

private slots:<br />

圱 圳 void doSomething();<br />

# slots doSomething() 沒 指 定 參 數<br />

圱 圵 }<br />

✡✝<br />

✆<br />

2. 呼 叫 emit 發 出 A_Signal() 信 號 :<br />

✞<br />

圱 emit A_Signal();<br />

✡✝<br />

✆<br />

3. 透 過 QObject 類 別 的 connect 成 員 函 式 將 slots 連 結 到 信 號 。<br />

✞<br />

圱 bool QObject::connect (const QObject * sender, const char *<br />

signal,<br />

const QObject * receiver, const char *<br />

member)<br />

圳 # connect 函 式 要 傳 入 擁 有 信 號 的 物 件 ( 傳 送 者 )、 信 號 函 式 、 擁<br />

有 slot 的 物 件 ( 接 收 者 ) 及 slot 名 稱 。<br />

圵<br />

connect (button, SIGNAL(clicked()), this, SLOT(doSomething())<br />

);<br />

# this 在 此 代 表 MyWindow<br />

✡✝<br />

✆<br />

4. 實 作 slot<br />

✞<br />

void MyWindow::doSomething()<br />

圲 {<br />

// Slot code<br />

圴 }<br />

✡✝<br />

✆<br />

• 實 例 : 做 一 個 簡 單 的 按 鈕 , 它 可 以 有 一 個 標 籤 和 位 元 圖 示 , 使 用 者 可 以 透 過<br />

滑 鼠 或 鍵 盤 來 點 選 它 。<br />

De-Yu Wang CSIE CYUT 225


11.4. SIGNALS 和 SLOTS CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

1. 編 輯 ButtonWindow.h 宣 告 類 別 :<br />

✞<br />

#include <br />

圲 class ButtonWindow : public QMainWindow<br />

{<br />

圴 Q_OBJECT<br />

public:<br />

圶 ButtonWindow(QWidget *parent = 0, const char *name = 0);<br />

virtual ~ButtonWindow();<br />

圸 private slots:<br />

void Clicked();<br />

圱 地 };<br />

✡✝<br />

✆<br />

2. 編 輯 ButtonWindow 建 構 函 式<br />

✞<br />

ButtonWindow::ButtonWindow(QWidget *parent, const char *name)<br />

圲<br />

: QMainWindow(parent, name)<br />

{<br />

圴 # setCaption 是 QMainWindow 的 成 員 函 式 , 可 設 定 視 窗 標 題 。<br />

this->setCaption("This is the window Title");<br />

圶 # 產 生 按 鈕 、 將 按 鈕 的 clicked 信 號 連 結 到 Clicked() slot 中 。<br />

QPushButton *button = new QPushButton("Click Me!", this, "<br />

Button1");<br />

圸 # 設 定 按 鈕 的 幾 何 大 小 。<br />

button->setGeometry(50,30,70,20);<br />

圱 地 # 將 按 鈕 的 clicked signal 連 結 到 Clicked() slot 中 。<br />

connect (button, SIGNAL(clicked()), this, SLOT(Clicked()));<br />

圱 圲 }<br />

✡✝<br />

✆<br />

3. 編 輯 ~ButtonWindow 解 構 函 式<br />

✞<br />

ButtonWindow::~ButtonWindow()<br />

圲 {<br />

# Qt 自 動 管 理 widget 的 解 構 工 作 , 所 以 解 構 函 式 是 空 的 。<br />

圴 }<br />

✡✝<br />

✆<br />

4. 編 輯 slot Clicked():<br />

✞<br />

void ButtonWindow::Clicked(void)<br />

圲 {<br />

std::cout


11.4. SIGNALS 和 SLOTS CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

5. 編 輯 main 程 式 ButtonWindow.cpp<br />

✞<br />

#include "ButtonWindow.moc"<br />

圲 #include <br />

#include <br />

圴 #include <br />

圶 int main(int argc, char **argv)<br />

{<br />

圸 QApplication app(argc,argv);<br />

# 產 生 一 個 ButtonWindow 的 物 件 , 設 定 應 用 程 式 的 主 視 窗 , 並 將 視 窗<br />

顯 示 在 螢 幕 上 。<br />

圱 地 ButtonWindow *window = new ButtonWindow();<br />

# 設 定 應 用 程 式 的 主 視 窗 。<br />

圱 圲 app.setMainWidget(window);<br />

# 將 視 窗 顯 示 在 螢 幕 上 。<br />

圱 圴 window->show();<br />

return app.exec();<br />

圱 圶 }<br />

✡✝<br />

✆<br />

6. 編 譯 前 , 執 行 前 置 處 理 器 moc:<br />

✞<br />

$ moc ButtonWindow.h -o ButtonWindow.moc<br />

圲<br />

# Qt 的 MOC( Meta-Object System )<br />

圴 ## 標 準 的 C++ 無 法 提 供 signal/slot 連 結 所 需 之 meta 訊 息 。<br />

## 標 頭 檔 若 包 含 \verb|Q_OBJECT| 巨 集 ,MOC 會 解 析 巨 集 定 義 ,<br />

圶 ## 並 產 生 Qt meta-object 相 關 的 C++ 程 式 碼 。<br />

## 使 用 qmake 產 生 , 就 會 包 括 Makefile moc 的 使 用 。<br />

✡✝<br />

✆<br />

7. 編 譯 程 式 , 並 連 結 moc 的 結 果 :<br />

✞<br />

圱 $ g++ -o button ButtonWindow.cpp -I$QTDIR/include -L$QTDIR/<br />

lib -lqt-mt<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 227


11.4. SIGNALS 和 SLOTS CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

8. 執 行 程 式 :<br />

• QPushButton 建 構 函 式 說 明 :<br />

1. QPushButton 的 建 構 函 式 :<br />

✞<br />

圱 QPushButton::QPushButton(const QString &text, QWidget *parent<br />

,<br />

const char* name=0 )<br />

✡✝<br />

✆<br />

(a) 第 一 個 參 數 是 按 鈕 的 文 字 標 籤 ,<br />

(b) 隨 後 是 它 的 父 親 widget,<br />

(c) 最 後 就 是 Qt 內 部 認 定 的 按 鈕 名 稱 。<br />

2. parent 參 數<br />

(a) 在 Qwidget 很 常 見 , 父 親 widget 可 以 控 制 何 時 顯 示 或 破 壞 它 ,<br />

包 含 不 同 的 屬 性 。<br />

(b) 如 果 在 parent 參 數 傳 入 NULL, 表 示 這 個 widget 是 最 上 層 的<br />

widget, 而 且 產 生 一 個 空 白 視 窗 來 包 含 它 。<br />

(c) 範 例 中 用 this 來 代 表 ButtonWindow 物 件 , 按 鈕 就 會 加 到<br />

ButtonWindow 的 主 要 區 域 。<br />

3. name 參 數 設 定 Qt 內 部 使 用 的 widget 名 稱 。 如 果 Qt 遇 到 一 個 錯<br />

誤 , 這 個 widget 名 稱 就 會 被 印 在 錯 誤 訊 息 上 , 所 以 最 好 輸 入 適 切 的<br />

widget 名 稱 , 方 便 往 後 除 錯 。<br />

4. setGeometry 決 定 絕 對 位 置 , 但 很 少 用 , 因 為 它 無 法 隨 視 窗 自 動 調 整 大<br />

小 。<br />

• 類 別 QLayout 與 box widget<br />

1. 利 用 QLayout 或 box widget , 給 定 區 域 和 widget 之 間 的 空 間 之<br />

後 , 它 會 自 動 調 整 。<br />

De-Yu Wang CSIE CYUT 228


11.4. SIGNALS 和 SLOTS CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

2. QLayout 類 別 和 box widget 之 間 的 關 鍵 性 差 異 就 是 layout 物 件 不 是<br />

widget。<br />

3. layout 類 別 從 QObject 衍 伸 而 來 。<br />

4. Box widget( 即 QHBox 和 QVBox) 衍 伸 自 QWidget, 可 以 把 它 當 成 一<br />

般 的 widget 來 處 理 。<br />

5. QLayout 有 自 動 調 整 大 小 的 優 點 , 而 如 果 widget 要 改 變 大 小 時 , 必 須<br />

人 工 呼 叫 QWidget::resizeEvent()。<br />

• QVBoxLayout 建 構 函 式 說 明 :<br />

1. QVBoxLayout 建 構 函 式 (QHBoxLayout 也 擁 有 相 同 的 API)。<br />

✞<br />

# QLayout 的 parent 參 數 , 可 以 是 widget 或 其 他 的 。 QLayout<br />

圲 QVBoxLayout::QVBoxLayout (QWidget *parent, int margin,<br />

int spacing, const char *name)<br />

圴 QVBoxLayout::QVBoxLayout (QLayout *parentLayout, int spacing,<br />

const char * name)<br />

圶 QVBoxLayout::QVBoxLayout (int spacing, const char *name)<br />

✡✝<br />

✆<br />

2. 若 沒 指 定 parent, 只 能 藉 由 成 員 函 式 addLayout 加 到 其 他 QLayout<br />

中 。<br />

✞<br />

QBoxLayout::addWidget (QWidget *widget, int stretch = 0,<br />

圲 int alignment = 0 )<br />

QBoxLayout::addLayout (QLayout *layout, int stretch = 0)<br />

✡✝<br />

✆<br />

3. margin 和 spacing 的 單 位 為 像 素 (pixel), 分 別 用 來 指 定 QLayout<br />

外 圍 和 widget 之 間 的 空 白 空 間 。<br />

• 實 例 : 使 用 QBoxLayout 類 別 , 設 計 三 個 QLabel, 讓 視 窗 大 小 改 變 時 ,<br />

label 自 動 被 放 大 或 縮 小 來 符 合 可 用 的 空 間 。<br />

1. 程 式 的 標 頭 檔 案 LayoutWindow.h。<br />

✞<br />

圱 #include <br />

class LayoutWindow : public QMainWindow<br />

圳 {<br />

Q_OBJECT<br />

圵 public:<br />

LayoutWindow(QWidget *parent = 0, const char *name = 0);<br />

圷 virtual ~LayoutWindow();<br />

};<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 229


11.4. SIGNALS 和 SLOTS CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

2. 程 式 LayoutWindow.cpp。<br />

✞<br />

#include <br />

圲 #include <br />

#include <br />

圴 #include "LayoutWindow.moc"<br />

LayoutWindow::LayoutWindow(QWidget *parent, const char *name)<br />

:<br />

圶 QMainWindow(parent, name)<br />

{<br />

圸 this->setCaption("Layouts");<br />

圱 地<br />

圱 圲<br />

圱 圴<br />

# 因 為 不 能 直 接 將 QLayout 加 到 , 所 以 產 生 一 個 假<br />

的 QMainWindow 。QWidget<br />

QWidget *widget = new QWidget(this);<br />

setCentralWidget(widget);<br />

QHBoxLayout *horizontal = new QHBoxLayout(widget, 5, 10,\"<br />

horizontal);<br />

QVBoxLayout *vertical = new QVBoxLayout();<br />

圱 圶 QLabel* label1 = new QLabel("Top", widget, "textLabel1" );<br />

QLabel* label2 = new QLabel("Bottom", widget, "textLabel2")<br />

;<br />

圱 圸<br />

圲 地<br />

圲 圲<br />

圲 圴 }<br />

QLabel* label3 = new QLabel("Right", widget, "textLabel3");<br />

vertical->addWidget(label1);<br />

vertical->addWidget(label2);<br />

horizontal->addLayout(vertical);<br />

horizontal->addWidget(label3);<br />

resize( 150, 100 );<br />

圲 圶 LayoutWindow::~LayoutWindow()<br />

{<br />

圲 圸 }<br />

圳 地 int main(int argc, char **argv)<br />

{<br />

圳 圲 QApplication app(argc,argv);<br />

LayoutWindow *window = new LayoutWindow();<br />

圳 圴 app.setMainWidget(window);<br />

window->show();<br />

圳 圶 return app.exec();<br />

}<br />

✡✝<br />

✆<br />

3. 編 譯 前 , 在 標 頭 檔 案 上 執 行 moc:<br />

✞<br />

圱 $ moc LayoutWindow.h -o LayoutWindow.moc<br />

$ g++ -o layout LayoutWindow.cpp -I$QTDIR/include -L$QTDIR/<br />

lib -lqt-mt<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 230


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

4. 執 行 程 式 :<br />

11.5 QT Widget<br />

• QLineEdit: 單 行 文 字 輸 入 的 widget。<br />

1. 建 構 函 式 和 常 用 成 員 函 式 :<br />

✞<br />

#include <br />

圲 QLineEdit::QlineEdit (QWidget *parent, const char* name = 0 )<br />

QLineEdit::QLineEdit (const QString &contents, QWidget *<br />

parent,<br />

圴 const char *name = 0 )<br />

QLineEdit::QLineEdit (const QString &contents,<br />

圶<br />

const QString &inputMask,<br />

QWidget *parent, const char *name = 0<br />

)<br />

圸 void setInputMask (const QString &inputMask)<br />

void insert (const QString &newText )<br />

圱 地 bool isModified (void)<br />

void setMaxLength (int length)<br />

圱 圲 void setReadOnly (bool read)<br />

void setText (const QString &text)<br />

圱 圴 QString text (void)<br />

void<br />

✡✝<br />

setEchoMode(EchoMode mode)<br />

✆<br />

2. 屬 性 EchoMode 決 定 文 字 如 何 顯 示 在 widget 上 。 它 可 以 有 以 下 三 種 數<br />

值 :<br />

(a) QLineEdit::Normal: 顯 示 輸 入 字 元 ( 預 設 值 )。<br />

(b) QLineEdit::Password: 顯 示 星 號 , 取 代 真 正 的 字 元 。<br />

(c) QLineEdit::NoEcho: 不 顯 示 任 何 東 西 。<br />

3. 使 用 setEchoMode 設 定 EchoMode 模 式 :<br />

✞<br />

圱 lineEdit->setEchoMode(QLineEdit::Password);<br />

✡✝<br />

✆<br />

4. inputMask 是 字 元 構 成 的 字 串 , 用 來 說 明 接 受 的 字 元 , 其 與 正 規 表 示 式<br />

使 用 相 同 的 原 則 。<br />

De-Yu Wang CSIE CYUT 231


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

(a) inputMask 字 元 代 表 能 不 能 存 在 某 字 元 。<br />

意 義 必 要 性 字 元 選 擇 性 字 元<br />

ASCII A-Z,a-z A a<br />

ASCII A-Z,a-z,0-9 N n<br />

任 何 字 元 X x<br />

數 值 0-9 9 0<br />

數 值 1-9 D d<br />

(b) inputMask 結 尾 可 以 選 擇 性 加 上 分 號 。<br />

(c) inputMask 進 階 的 特 殊 字 元 :<br />

# 數 字 或 +, - 符 號 之 選 擇 性 字 元 。<br />

> 將 隨 後 的 字 元 變 成 大 寫 。<br />

< 將 隨 後 的 字 元 變 成 小 寫 。<br />

! 停 止 轉 換 。<br />

\ 跳 脫 字 元<br />

5. 遮 罩 範 例 :<br />

(a) \AAAAAA-999D"<br />

i. 可 接 受 Athens-2004,<br />

ii. 但 不 能 接 受 Sydney-2000 或 Atlanta-1996。<br />

(b) \AAAAnn-99-99;"<br />

i. 可 接 受 March-03-12,<br />

ii. 但 不 能 接 受 May-03-12 或 September-03-12。<br />

(c) \000.000.000.000": 允 許 IP 位 址 , 例 如 192.168.0.1。<br />

• 實 例 :QLineEdit<br />

1. 標 頭 檔 案 LineEdit.h。<br />

✞<br />

圱 #include <br />

#include <br />

圳 #include <br />

class LineEdit : public QMainWindow<br />

圵 {<br />

Q_OBJECT<br />

圷 public:<br />

LineEdit(QWidget *parent = 0, const char *name = 0);<br />

圹 QLineEdit *password_entry;<br />

private slots:<br />

圱 圱 void Clicked();<br />

};<br />

✡✝<br />

✆<br />

2. 程 式 檔 案 LineEdit.cpp。<br />

✞<br />

#include "LineEdit.moc"<br />

De-Yu Wang CSIE CYUT 232


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

圲<br />

圴<br />

圶<br />

圸<br />

圱 地<br />

圱 圲<br />

圱 圴<br />

圱 圶<br />

圱 圸<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

LineEntry::LineEntry(QWidget *parent, const char *name) :<br />

QMainWindow(parent, name)<br />

{<br />

QWidget *widget = new QWidget(this);<br />

setCentralWidget(widget);<br />

# 使 用 QGridLayout 來 安 排 。 指 定 行 數 、 列 數 、 邊 界 設 定 和 間<br />

隔 。 widget<br />

QGridLayout *grid = new QGridLayout(widget,3,2,10, 10,"grid<br />

");<br />

QLineEdit *username_entry = new QLineEdit( widget,<br />

"username_entry");<br />

password_entry = new QLineEdit( widget, "password_entry");<br />

password_entry->setEchoMode(QLineEdit::Password);<br />

圲 地 # 在 方 格 中 加 入 一 個 , 必 須 告 知 行 編 號 、 列 編 號 , 而 起 始 值 為 (,) 代 表<br />

左 上 方 的 格 子 。 widget00<br />

grid->addWidget(new QLabel("Username", widget, "userlabel")<br />

,<br />

圲 圲 0, 0, 0);<br />

grid->addWidget(new QLabel("Password", widget, "<br />

passwordlabel"),<br />

圲 圴 1, 0, 0);<br />

grid->addWidget(username_entry, 0,1, 0);<br />

圲 圶 grid->addWidget(password_entry, 1,1, 0);<br />

QPushButton *button = new QPushButton ("Ok", widget, "<br />

button");<br />

圲 圸 grid->addWidget(button, 2,1,Qt::AlignRight);<br />

resize( 350, 200 );<br />

圳 地 connect (button, SIGNAL(clicked()), this, SLOT(Clicked()));<br />

}<br />

圳 圲 void LineEntry::Clicked(void)<br />

{<br />

圳 圴 std::cout text() show();<br />

圴 圲<br />

}<br />

✡✝<br />

return app.exec();<br />

✆<br />

3. 程 式 執 行 結 果 :<br />

De-Yu Wang CSIE CYUT 233


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

✞<br />

圱 [dywang@dywOffice chapter17]$ moc LineEdit.h -o LineEdit.moc<br />

[dywang@dywOffice chapter17]$ g++ -o lineedit LineEdit.cpp \<br />

圳 -I$QTDIR/include -L$QTDIR/lib -lqt-mt<br />

[dywang@dywOffice chapter17]$ ./lineedit<br />

✡✝<br />

✆<br />

4. 結 果 說 明 :<br />

(a) 產 生 兩 個 QLineEdit widget, 其 中 一 個 設 定 EchoMode 讓 它 變 成<br />

密 碼 輸 入 的 視 窗 ;<br />

(b) 按 下 按 鈕 時 就 會 印 出 結 果 。<br />

• Qt 按 鈕 (Buttons)<br />

1. QButton 的 成 員 函 式 :<br />

✞<br />

#include <br />

圲 virtual void QButton::setText ( const QString & )<br />

virtual void QButton::setPixmap ( const QPixmap & )<br />

圴 bool QButton::isToggleButton () const<br />

圶<br />

virtual void QButton::setDown ( bool )<br />

bool QButton::isDown () const<br />

bool QButton::isOn () const<br />

圸 enum QButton::ToggleState { Off, NoChange, On }<br />

ToggleState QButton::state () const<br />

✡✝<br />

✆<br />

2. 函 式 說 明 :<br />

(a) isToggleButton 函 式 表 示 按 鈕 是 否 為 雙 態 (toggle) 的 按 鈕 ( 亦<br />

即 有 on 或 off 狀 態 ), 預 設 為 FALSE。<br />

(b) isDown 函 式 表 示 按 鈕 被 按 下 就 回 覆 TRUE。<br />

(c) 如 果 按 鈕 拴 牢 ( toggled ), isOn 函 式 回 傳 TRUE。<br />

3. QButton 三 個 子 類 別 :PushButton、CheckBox 和 RadioButton。<br />

De-Yu Wang CSIE CYUT 234


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

• QPushButton: 簡 單 的 按 鈕 widget, 被 按 下 時 就 會 執 行 一 些 動 作 。<br />

1. 建 構 函 式 和 有 用 的 成 員 函 式 :<br />

✞<br />

圱 #include <br />

QPushButton (QWidget *parent, const char *name = 0)<br />

圳 QPushButton (const QString &text, QWidget *parent,<br />

const char *name = 0)<br />

圵 QPushButton (const QIconSet &icon, const QString &text,<br />

QWidget *parent, const char * name = 0 )<br />

圷 void QPushButton::setToggleButton (bool);<br />

✡✝<br />

✆<br />

2. 按 鈕 上 可 以 有 文 字 或 圖 示 。 例 如 OK 或 Cancle。<br />

3. 可 呼 叫 setToggleButton, 從 無 狀 態 (stateless) 按 鈕 變 成 雙 態<br />

(toggle) 按 鈕 。<br />

• QCheckBox<br />

1. 建 構 函 式 和 有 用 的 成 員 函 式 :<br />

✞<br />

圱 #include <br />

QCheckBox (QWidget *parent, const char *name = 0 )<br />

圳 QCheckBox (const QString &text, QWidget *parent,<br />

const char *name = 0 )<br />

圵 bool QCheckBox::isChecked ()<br />

void QCheckBox::setTristate ( bool y = TRUE )<br />

圷 bool QCheckBox::isTristate ()<br />

✡✝<br />

✆<br />

2. 一 般 只 有 on 或 off 狀 態 資 訊 ;<br />

3. 也 可 變 成 三 種 狀 態 , 中 間 的 狀 態 代 表 \ 沒 有 改 變 "。<br />

• QRadioButton<br />

1. 建 構 函 式 和 一 個 成 員 函 式 :<br />

✞<br />

圱 #include <br />

QRadioButton (QWidget *parent, const char *name = 0 )<br />

圳 QRadioButton (const QString &text, QWidget *parent,<br />

const char *name = 0 )<br />

圵 bool QRadioButton::isChecked ()<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 235


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

2. 通 常 是 成 群 的 , 在 同 一 個 時 間 只 能 按 下 群 組 中 的 一 個 按 鈕 。<br />

3. 還 要 透 過 QButtonGroup 類 別 來 控 制 群 組 和 唯 一 選 擇 性 。<br />

• QButtonGroup<br />

1. 建 構 函 式 和 一 個 成 員 函 式 :<br />

✞<br />

圱 #include <br />

QButtonGroup (QWidget *parent = 0, const char * name = 0 )<br />

圳 QButtonGroup (const QString & title, QWidget * parent = 0,<br />

const char * name = 0 )<br />

圵 int insert (QButton *button, int id = -1)<br />

void remove (QButton *button)<br />

圷 int id (QButton *button) const<br />

int count () const<br />

圹 int<br />

✡✝<br />

selectedId () const<br />

✆<br />

2. 要 將 按 鈕 加 入 QButtonGroup 可 以 使 用 insert(), 或 指 定<br />

QButtonGroup 為 要 按 鈕 的 父 親 widget。<br />

3. 在 insert() 中 , 還 可 以 指 定 一 個 id, 以 辨 識 每 個 按 鈕 。<br />

4. selectedId 會 回 傳 被 選 擇 按 鈕 的 id。<br />

5. 加 入 群 組 的 QRadioButton 都 會 自 動 設 成 排 他 性 , 不 會 有 重 複 選 擇 的 問<br />

題 。<br />

• 實 例 :QButtons<br />

1. 檔 案 Buttons.h:<br />

✞<br />

圱 #include <br />

#include <br />

圳 #include <br />

#include <br />

圵 class Buttons : public QMainWindow<br />

{<br />

圷 Q_OBJECT<br />

public:<br />

圹 Buttons(QWidget *parent = 0, const char *name = 0);<br />

De-Yu Wang CSIE CYUT 236


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

圱 圱<br />

圱 圳<br />

圱 圵<br />

圱 圷<br />

# 在 slot 函 式 中 會 查 詢 按 鈕 的 狀 態 , 所 以 在 類 別 定 義 中 宣 告 按 鈕 指 標 為<br />

私 有 的 。<br />

private:<br />

void PrintActive(QButton *button);<br />

QCheckBox *checkbox;<br />

QRadioButton *radiobutton1, *radiobutton2;<br />

private slots:<br />

};<br />

✡✝<br />

void Clicked();<br />

✆<br />

2. 檔 案 Buttons.cpp:<br />

✞<br />

#include "Buttons.moc"<br />

圲 #include <br />

#include <br />

圴 #include <br />

#include <br />

圶 #include <br />

#include <br />

圸 Buttons::Buttons(QWidget *parent, const char *name) :<br />

QMainWindow(parent, name)<br />

圱 地 {<br />

QWidget *widget = new QWidget(this);<br />

圱 圲 setCentralWidget(widget);<br />

QVBoxLayout *vbox = new QVBoxLayout(widget,5, 10,"vbox");<br />

圱 圴 checkbox = new QCheckBox("CheckButton", widget, "check");<br />

vbox->addWidget(checkbox);<br />

圱 圶<br />

# 為 兩 個 radio 按 鈕 , 產 生 一 個 : QButtonGroup<br />

圱 圸 QButtonGroup *buttongroup = new QButtonGroup(0);<br />

radiobutton1 = new QRadioButton("RadioButton1", widget, "<br />

radio1");<br />

圲 地<br />

buttongroup->insert(radiobutton1);<br />

vbox->addWidget(radiobutton1);<br />

圲 圲 radiobutton2 = new QRadioButton("RadioButton2", widget, "<br />

radio2");<br />

buttongroup->insert(radiobutton2);<br />

圲 圴<br />

圲 圶<br />

圲 圸<br />

}<br />

✡✝<br />

vbox->addWidget(radiobutton2);<br />

QPushButton *button = new QPushButton ("Ok", widget, "<br />

button");<br />

vbox->addWidget(button);<br />

resize( 350, 200 );<br />

connect (button, SIGNAL(clicked()), this, SLOT(Clicked()));<br />

✆<br />

3. 印 出 按 鈕 狀 態 的 成 員 函 式 :<br />

✞<br />

圱 void Buttons::PrintActive(QButton *button)<br />

De-Yu Wang CSIE CYUT 237


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

{<br />

圳 if (button->isOn())<br />

std::cout name()


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

• QComboBox<br />

1. Radio 按 鈕 有 六 個 以 上 的 選 項 時 , 會 讓 視 窗 難 以 調 整 。<br />

2. 建 構 函 式<br />

✞<br />

圱 # QComboBox 建 構 函 式 中 的 布 林 參 數 , 指 定 TRUE QComboBox 為 可 讀<br />

寫 。<br />

QComboBox *combo = new QComboBox(TRUE, parent, \"widgetname);<br />

✡✝<br />

✆<br />

3. 加 入 選 項 , 輸 入 型 態 可 以 為 QStrings 或 使 用 傳 統 的 char * 格 式 。<br />

✞<br />

combo->insertItem(QString\(An "Item), 1);<br />

圲 # 數 值 1 代 表 設 定 這 個 選 項 為 串 列 中 的 第 一 個 選 項 。<br />

# 如 果 要 將 加 到 串 列 尾 端 , 只 要 傳 入 任 何 負 的 整 數 。<br />

✡✝<br />

✆<br />

4. 利 用 char * 陣 列 加 入 多 個 選 項 :<br />

✞<br />

圱 char* weather[] = \{"Thunder, \"Lightning, \"Rain, 0};<br />

combo->insertStrList(weather, 3);<br />

✡✝<br />

✆<br />

5. 呼 叫 QComboBox 的 setInsertionPolicy() 成 員 函 式 :<br />

De-Yu Wang CSIE CYUT 239


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

✞<br />

combo->setInsertionPolicy(QComboBox::AtTop);<br />

✡✝<br />

✆<br />

關 鍵 字 串<br />

插 入 策 略<br />

QComboBox::AtTop 將 新 項 目 插 到 串 列 的 第 一 個 選 項 。<br />

QComboBox::AtBottom 將 新 項 目 插 到 串 列 的 最 後 一 個 選 項 。<br />

QComboBox::AtCurrent 取 代 先 前 選 擇 的 選 項 。<br />

QComboBox::BeforeCurrent 將 新 項 目 插 到 先 前 選 擇 的 選 項 之 前 。<br />

QComboBox::AfterCurrent 將 新 項 目 插 到 先 前 選 擇 的 選 項 之 後 。<br />

QComboBox::NoInsertion 不 要 將 新 選 項 插 入 串 列 中 。<br />

6. QComboBox 的 建 構 函 式 和 其 他 成 員 函 式 :<br />

✞<br />

圱 #include <br />

QComboBox (QWidget *parent = 0, const char *name = 0)<br />

圳 QComboBox (bool readwrite, QWidget *parent = 0, const char *<br />

name = 0)<br />

# count 回 覆 串 列 選 項 的 數 量 。<br />

圵 int count ()<br />

# QStringList 和 QStrList 是 Qt 字 串 集 合 類 別 , 可 以 用 來 加 入 多 個<br />

圷<br />

選 項 。<br />

void insertStringList (const QStringList &list, int index<br />

= -1)<br />

void insertStrList (const QStrList &list, int index = -1)<br />

圹 void insertStrList (const QStrList *list, int index = -1)<br />

void insertStrList (const char **strings, int numStrings<br />

= -1,<br />

圱 圱 int index = -1)<br />

# insertItem 加 入 選 項 ;<br />

圱 圳 void insertItem (const QString &t, int index = -1)<br />

# removeItem() 移 除 選 項 ;<br />

圱 圵 void removeItem (int index)<br />

# CurrrentItem() 取 得 目 前 選 項 ;<br />

圱 圷<br />

virtual void setCurrentItem (int index)<br />

# CurrrentText() 取 得 目 前 選 項 內 容 ;<br />

圱 圹 QString currentText ()<br />

virtual void setCurrentText (const QString &)<br />

圲 圱 # setEditable() 切 換 可 編 輯 的 狀 態 。<br />

void<br />

✡✝<br />

setEditable (bool)<br />

✆<br />

• 實 例 : 設 計 兩 個 QComboBox widget, 一 個 可 以 編 輯 , 另 一 個 是 唯 讀 。<br />

1. 程 式 檔 案 ComboBox.cpp:<br />

✞<br />

#include "ComboBox.moc"<br />

圲 #include <br />

#include <br />

De-Yu Wang CSIE CYUT 240


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

圴 ComboBox::ComboBox(QWidget *parent, const char *name) :<br />

QMainWindow(parent, name)<br />

圶 {<br />

QWidget *widget = new QWidget(this);<br />

圸<br />

setCentralWidget(widget);<br />

QVBoxLayout *vbox = new QVBoxLayout(widget, 5, 10,"vbox");<br />

圱 地 QComboBox *editablecombo = new QComboBox(TRUE, widget, "<br />

editable");<br />

vbox->addWidget(editablecombo);<br />

圱 圲 QComboBox *readonlycombo = new QComboBox(FALSE, widget, "<br />

readonly");<br />

vbox->addWidget(readonlycombo);<br />

圱 圴<br />

圱 圶<br />

圱 圸<br />

圲 地<br />

圲 圲 }<br />

static const char* items[] = { "Macbeth",<br />

"Twelfth Night", "Othello", 0 };<br />

editablecombo->insertStrList (items);<br />

readonlycombo->insertStrList (items);<br />

# 當 一 個 新 選 項 被 選 擇 之 後 ,QComboBox 會 發<br />

出 textChanged(QString &) 信 號 。<br />

connect (editablecombo, SIGNAL(textChanged(const QString&))<br />

,<br />

this, SLOT(Changed(const QString&)));<br />

resize( 350, 200 );<br />

圲 圴 # QString 參 數 , 會 被 信 號 傳 送 。 s<br />

void ComboBox::Changed(const QString& s)<br />

圲 圶 {<br />

std::cout -I$QTDIR/include -L$QTDIR/lib -lqt-mt<br />

[dywang@dywOffice chapter17]$ ./combobox<br />

圵 Twelfth Night<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 241


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

• QListView<br />

1. QListView 能 以 目 錄 架 構 的 方 式 顯 示 , 按 下 加 號 和 減 號 擴 展 或 緊 縮 子 元<br />

件 , 與 檔 案 顯 示 程 式 一 樣 。<br />

2. 建 構 函 式 : 只 要 指 定 父 親 和 widget 名 稱 。<br />

✞<br />

圱 QListView *view = new QListView(parent, \"name);<br />

✡✝<br />

✆<br />

3. 設 定 欄 位 的 標 題 , 要 利 用 addColumn() 成 員 函 式 :<br />

✞<br />

圱 view->addColumn("Left Column", width1 ); // Fixed width<br />

view->addColumn("Right Column"); // Width autosizes<br />

✡✝<br />

✆<br />

• QListViewItem: 將 列 元 件 傳 入 QListView 中 :<br />

1. 建 構 函 式 :<br />

✞<br />

QListViewItem::QListViewItem ( QListView * parent, QString<br />

label1,<br />

圲 QString label2 = QString::null, QString label3 = QString::<br />

null,<br />

QString label4 = QString::null, QString label5 = QString::<br />

null,<br />

圴 QString label6 = QString::null, QString label7 = QString::<br />

null,<br />

QString label8 = QString::null )<br />

圶 # 可 以 提 供 八 個 行 的 標 籤 , 若 不 需 要 可 不 給 參 數 或 指 定 NULL<br />

✡✝<br />

✆<br />

2. 將 列 元 件 傳 入 view :<br />

圲<br />

✞<br />

QListViewItem *toplevel = new QListViewItem(view, "Left Data"<br />

,<br />

"Right Data");<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 242


11.5. QT WIDGET CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

3. 將 列 元 件 傳 入 toplevel 子 節 點 :<br />

✞<br />

new QListViewItem(toplevel, "Left Data", "Right Data");<br />

圲<br />

// A Child of<br />

toplevel<br />

✡✝<br />

✆<br />

4. QListViewItem 成 員 函 式 :<br />

✞<br />

#include <br />

圲 virtual void insertItem ( QListViewItem * newChild )<br />

virtual void setText ( int column, const QString & text )<br />

圴 virtual QString text ( int column ) const<br />

QListViewItem *firstChild () const<br />

圶 QListViewItem *nextSibling () const<br />

QListViewItem *parent () const<br />

圸 QListViewItem *itemAbove ()<br />

QListViewItem<br />

✡✝<br />

*itemBelow ()<br />

✆<br />

5. 實 例 : 印 出 上 層 節 點 的 第 一 欄<br />

✞<br />

圱 QListViewItem *child = view->firstChild();<br />

while(child)<br />

圳 {<br />

cout text(1) nextSibling();<br />

}<br />

✡✝<br />

✆<br />

• 實 例 :QListView<br />

1. 跳 過 標 頭 檔 案 ListView.h, 直 接 看 類 別 檔 案 ListView.cpp:<br />

✞<br />

#include "ListView.moc"<br />

圲 ListView::ListView(QWidget *parent, const char *name) :<br />

QMainWindow(parent, name)<br />

圴 {<br />

listview = new QListView(this, "listview1");<br />

圶 listview->addColumn("Artist");<br />

listview->addColumn("Title");<br />

圸 listview->addColumn("Catalogue");<br />

listview->setRootIsDecorated(TRUE);<br />

圱 地 QListViewItem *toplevel = new QListViewItem(listview,<br />

"Avril Lavigne", "Let Go", "AVCD01");<br />

圱 圲 new QListViewItem(toplevel, "Complicated");<br />

new QListViewItem(toplevel, "Sk8er Boi");<br />

圱 圴 setCentralWidget(listview);<br />

De-Yu Wang CSIE CYUT 243


11.6. 對 話 窗 DIALOG CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

}<br />

圱 圶<br />

int main(int argc, char **argv)<br />

圱 圸 {<br />

QApplication app(argc,argv);<br />

圲 地 ListView *window = new ListView();<br />

app.setMainWidget(window);<br />

圲 圲 window->show();<br />

return app.exec();<br />

圲 圴 }<br />

✡✝<br />

✆<br />

2. 編 譯 和 執 行 ListView<br />

✞<br />

[dywang@dywOffice chapter17]$ moc ListView.h -o ListView.moc<br />

圲 [dywang@dywOffice chapter17]$ g++ -o listview ListView.cpp \<br />

-I$QTDIR/include -L$QTDIR/lib -lqt-mt<br />

圴 [dywang@dywOffice chapter17]$ ./listview<br />

✡✝<br />

✆<br />

11.6 對 話 窗 dialog<br />

• Modal 與 Nonnodal 對 話 視 窗 :<br />

1. Modal 對 話 視 窗 : 在 使 用 者 回 應 對 話 視 窗 之 前 , 擱 置 其 它 視 窗 的 輸 入 。<br />

對 於 立 即 抓 取 使 用 者 的 回 應 和 顯 示 重 要 的 錯 誤 訊 息 , 這 類 型 的 對 話 視 窗<br />

就 很 有 用 。<br />

2. Nonmodal 對 話 視 窗 : 非 擱 置 視 窗 , 與 一 般 應 用 程 式 視 窗 相 同 。 對 於 搜<br />

尋 視 窗 或 輸 入 視 窗 就 很 有 用 。<br />

• QDialog:Qt 的 基 本 對 話 視 窗 類 別<br />

1. 實 例 : 一 般 會 產 生 一 個 繼 承 自 QDialog 的 對 話 視 窗 類 別 , 並 加 上 一 些<br />

widget 來 構 成 對 話 視 窗 介 面 。<br />

De-Yu Wang CSIE CYUT 244


11.6. 對 話 窗 DIALOG CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

✞<br />

#include <br />

圲 MyDialog::MyDialog(QWidget *parent, const char *name) :<br />

QDialog(parent, name)<br />

圴 {<br />

QHBoxLayout *hbox = new QHBoxLayout(this);<br />

圶 hbox->addWidget(new Qlabel("Enter your name"));<br />

hbox->addWidget(new QLineEdit());<br />

圸 hbox->addWidget(ok_pushbutton);<br />

hbox->addWidget(cancel_pushbutton);<br />

圱 地 connect (ok_pushbutton, SIGNAL(clicked()), this, SLOT(<br />

accept()));<br />

connect (cancel_pushbutton, SIGNAL(clicked()), this,<br />

圱 圲<br />

}<br />

✡✝<br />

SLOT(reject()));<br />

✆<br />

2. Modal 對 話 窗 : 呼 叫 exec(), 所 有 處 理 都 會 被 擱 置 。<br />

✞<br />

圱 MyDialog *dialog = new MyDialog(this, "mydialog");<br />

if (dialog->exec() == QDialog::Accepted)<br />

圳 {<br />

// User clicked ‘’Ok<br />

圵 doSomething();<br />

}<br />

圷 else<br />

{<br />

圹 // user clicked ‘’Cancel or dialog killed<br />

doSomethingElse();<br />

圱 圱 }<br />

delete dialog;<br />

✡✝<br />

✆<br />

3. signal/slot 連 結 方 式 如 同 modal 對 話 視 窗 。<br />

✞<br />

MyDialog::MyDialog(QWidget *parent, const char *name) :<br />

圲 QDialog(parent, name)<br />

{<br />

圴 ...<br />

connect (ok_pushbutton, SIGNAL(clicked()), this, SLOT(<br />

圶<br />

OkClicked()));<br />

connect (cancel_pushbutton, SIGNAL(clicked()), this,<br />

SLOT(CancelClicked()));<br />

圸 }<br />

MyDialog::OkClicked()<br />

圱 地 {<br />

//Do some processing<br />

圱 圲 }<br />

MyDialog::CancelClicked()<br />

圱 圴 {<br />

De-Yu Wang CSIE CYUT 245


11.6. 對 話 窗 DIALOG CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

圱 圶 }<br />

✡✝<br />

//Do some other processing<br />

✆<br />

4. NonModal 對 話 窗 : 呼 叫 show(), 顯 示 對 話 窗 並 立 刻 回 覆 , 繼 續 主 要 的<br />

處 理 迴 圈 。<br />

✞<br />

MyDialog *dialog = new MyDialog(this, "mydialog");<br />

圲 dialog->show();<br />

✡✝<br />

✆<br />

• QMessageBox<br />

1. QMessageBox 是 一 個 modal 對 話 窗 , 顯 示 一 個 簡 單 的 訊 息 , 加 上 一 個<br />

小 圖 示 和 按 鈕 。QMessageBox 一 般 的 訊 息 、 警 告 訊 息 、 其 它 關 鍵 訊 息 成<br />

員 函 式 :<br />

✞<br />

#include <br />

圲 int information (QWidget *parent, const QString &caption,<br />

const QString &text,<br />

圴<br />

int button0, int button1=0, int button2=0)<br />

int warning (QWidget *parent, const QString &caption,<br />

圶<br />

const QString &text,<br />

int button0, int button1, int button2=0)<br />

圸 int critical (QWidget *parent, const QString &caption,<br />

const QString &text,<br />

圱 地<br />

✡✝<br />

int button0, int button1, int button2=0)<br />

✆<br />

2. Each of the buttons, button0, button1 and button2 may be set<br />

to one of the following values:<br />

✞<br />

QMessageBox::Ok<br />

圲 QMessageBox::Cancel<br />

QMessageBox::Yes<br />

圴 QMessageBox::No<br />

QMessageBox::Abort<br />

圶 QMessageBox::Retry<br />

QMessageBox::Ignore<br />

✡✝<br />

✆<br />

3. 實 例 :QMessageBox 的 使 用<br />

✞<br />

圱 int result = QMessageBox::information(this,<br />

"Engine Room Query",<br />

圳<br />

"Do you wish to engage the HyperDrive",<br />

De-Yu Wang CSIE CYUT 246


11.6. 對 話 窗 DIALOG CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

QMessageBox::Yes | QMessageBox::Default,<br />

圵<br />

QMessageBox::No | QMessageBox::Escape);<br />

switch (result) {<br />

圷 case QMessageBox::Yes:<br />

hyperdrive->engage();<br />

圹 break;<br />

case QMessageBox::No:<br />

圱 圱 // do something else<br />

break;<br />

圱 圳 }<br />

✡✝<br />

✆<br />

4. 對 話 視 窗 的 結 果 。<br />

• QInputDialog<br />

1. 類 似 QMessageBox, 但 多 一 個 QLineEdit 可 讓 使 用 者 輸 入 。<br />

2. 可 輸 入 文 字 、 布 林 、 整 數 及 浮 點 數 , 但 分 別 使 用 不 同 的 建 構 函 式 :<br />

✞<br />

圱 #include <br />

QString getText (const QString &caption, const QString &<br />

label,<br />

圳<br />

QLineEdit::EchoMode mode=QLineEdit::Normal,<br />

const QString &text=QString::null, bool *<br />

ok = 0,<br />

圵 QWidget * parent = 0, const char * name =<br />

0)<br />

QString getItem (const QString &caption, const QString &<br />

label,<br />

圷<br />

const QStringList &list, int current=0,<br />

bool editable=TRUE,<br />

圹<br />

bool * ok=0, QWidget *parent = 0, const<br />

char *name=0)<br />

int getInteger (const QString &caption, const QString &<br />

label,<br />

圱 圱<br />

int num=0,<br />

int from = -2147483647, int to =<br />

2147483647,<br />

圱 圳 int step = 1,<br />

De-Yu Wang CSIE CYUT 247


11.6. 對 話 窗 DIALOG CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

bool * ok = 0, QWidget * parent = 0,<br />

圱 圵 const char * name = 0)<br />

double getDouble (const QString &caption, const QString &<br />

label,<br />

圱 圷 double num = 0,<br />

double from = -2147483647, double to =<br />

2147483647,<br />

圱 圹 int decimals = 1, bool * ok = 0,<br />

QWidget * parent = 0,<br />

圲 圱 const char * name = 0 )<br />

✡✝<br />

✆<br />

3. 實 例 : 輸 入 一 行 的 文 字 :<br />

✞<br />

圱 bool result;<br />

QString text = QInputDialog::getText("Question",<br />

圳<br />

"What is your Quest:<br />

",<br />

QLineEdit::Normal,<br />

圵<br />

QString::null, &<br />

result, this,<br />

"input" );<br />

圷 if (result) {<br />

doSomething(text);<br />

圹 } else {<br />

// user pressed cancel<br />

圱 圱 }<br />

✡✝<br />

✆<br />

(a) getText 利 用 一 個 QLineEdit, 可 以 設 定 EchoMode, 也 可 以 指 定<br />

預 設 文 字 或 清 成 空 白 。<br />

(b) 每 個 QInputDialog 都 有 Ok 和 Cancel 按 鈕 , 必 須 傳 入 一 個<br />

bool 指 標 , 才 能 知 道 哪 個 按 鈕 被 按 下 , 如 果 使 用 者 按 下<br />

Ok,result 就 是 TRUE。<br />

4. getItem 透 過 QComboBox, 提 供 使 用 者 一 系 列 的 選 項 。<br />

✞<br />

圱 bool result;<br />

QStringList options;<br />

圳 options


11.7. 選 單 和 工 具 列 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

5. 對 話 窗 的 結 果 。<br />

• 使 用 qmake 簡 化 makefile 的 設 計<br />

1. Qt 提 供 一 個 工 具 稱 為 qmake, 可 以 產 生 makefile。<br />

2. qmake 需 要 一 個 .pro 的 輸 入 檔 案 。 這 個 檔 案 包 含 基 本 的 資 訊 , 例 如 :<br />

原 始 碼 、 標 頭 檔 案 、 目 的 檔 案 和 KDE/Qt 函 式 庫 位 置 。 一 般 KDE 的<br />

.pro 檔 案 如 下 :<br />

✞<br />

圱 TARGET = app<br />

MOC_DIR = moc<br />

圳 OBJECTS_DIR = obj<br />

INCLUDEPATH = /usr/include/kde<br />

圵 QMAKE_LIBDIR_X11 += /usr/lib<br />

QMAKE_LIBS_X11 += -lkdeui -lkdecore<br />

圷 SOURCES = main.cpp window.cpp<br />

HEADERS = window.h<br />

✡✝<br />

✆<br />

3. 產 生 makefile。<br />

✞<br />

$qmake file.pro -o Makefile<br />

✡✝<br />

✆<br />

11.7 選 單 和 工 具 列<br />

• KAction widget<br />

1. KAction 的 建 構 函 式 :<br />

✞<br />

圱 #include <br />

KAction (const QString &text, const KShortcut &cut,<br />

圳<br />

const QObject *receiver,<br />

const char *slot, QObject *parent, const char *name<br />

= 0)<br />

圵 # 必 須 輸 入 文 字 、 快 速 鍵 、 圖 示 和 一 個 , slotslot 為 KAction 被 選 定<br />

時 被 呼 叫 。<br />

✡✝<br />

✆<br />

2. 實 例 : 產 生 一 個 New 選 單 和 工 具 列 , 當 它 們 被 按 下 時 就 會 呼 叫<br />

newFile()。<br />

De-Yu Wang CSIE CYUT 249


11.7. 選 單 和 工 具 列 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

✞<br />

圱 KAction *new_file = new KAction("New", "filenew",<br />

KstdAccel::key(KstdAccel<br />

::New),<br />

圳<br />

this, SLOT(newFile()),<br />

this,<br />

"newaction");<br />

✡✝<br />

✆<br />

3. 為 KAction new_file 加 入 選 單 、 工 具 列 :<br />

✞<br />

new_file->plug(a_menu);<br />

圲 new_file->plug(a_toolbar);<br />

✡✝<br />

✆<br />

4. 取 消 KAction new_file。<br />

✞<br />

new_file->setEnabled(FALSE);<br />

✡✝<br />

✆<br />

5. KDE 提 供 一 些 標 準 KAction 物 件<br />

✞<br />

圱 #include <br />

KAction * openNew (const QObject *recvr, const char *slot,<br />

圳<br />

KActionCollection* parent,<br />

const char *name = 0 )<br />

圵 KAction * save ...<br />

KAction * saveAs ...<br />

圷 KAction * revert ...<br />

KAction * close ...<br />

圹 KAction * print ...<br />

etc...<br />

✡✝<br />

✆<br />

6. KActionCollection 物 件 用 來 管 理 一 個 視 窗 中 的 KAction, 利 用<br />

KMainWindow 的 actionCollection() 成 員 函 式 來 取 得 目 前 的 物 件 。<br />

✞<br />

KAction *saveas = KStdAction::saveAs(this, SLOT(saveAs()),<br />

圲<br />

actionCollection(),"saveas");<br />

✡✝<br />

✆<br />

• 實 例 : 含 有 選 單 和 工 具 列 的 KDE 應 用 程 式<br />

1. 標 頭 檔 案 KDEMenu.h<br />

De-Yu Wang CSIE CYUT 250


11.7. 選 單 和 工 具 列 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

✞<br />

#include <br />

圲 class KDEMenu : public KMainWindow<br />

{<br />

圴 Q_OBJECT<br />

public:<br />

圶 KDEMenu(const char * name = 0);<br />

private slots:<br />

圸 void newFile();<br />

void aboutApp();<br />

圱 地 };<br />

✡✝<br />

✆<br />

2. 在 KDEMenu.cpp 中 引 入 widget 相 關 的 檔 案 :<br />

✞<br />

#include "KDEMenu.h"<br />

圲 #include <br />

#include <br />

圴 #include <br />

#include <br />

圶 #include<br />

✡✝<br />

<br />

✆<br />

3. 在 建 構 函 式 中 產 生 三 個 KAction widget。<br />

✞<br />

KDEMenu::KDEMenu(const char *name = 0) : KMainWindow (0L,<br />

name )<br />

圲 {<br />

KAction *new_file = new KAction("New", "filenew",<br />

圴<br />

KstdAccel::key(KstdAccel::New),<br />

this, SLOT(newFile()), this, "<br />

newaction");<br />

圶 KAction *quit_action = KStdAction::quit(<br />

KApplication::kApplication<br />

(),<br />

圸<br />

SLOT(quit()),<br />

actionCollection());<br />

KAction *help_action = KStdAction::aboutApp(this, SLOT(<br />

aboutApp()),<br />

圱 地<br />

actionCollection<br />

());<br />

✡✝<br />

✆<br />

4. 產 生 兩 層 的 選 單 , 並 將 它 插 入 KApplication 的 選 單 列 中 :<br />

✞<br />

QPopupMenu *file_menu = new QPopupMenu;<br />

圲 QPopupMenu *help_menu = new QPopupMenu;<br />

menuBar()->insertItem("&File", file_menu);<br />

圴 menuBar()->insertItem("&Help", help_menu);<br />

De-Yu Wang CSIE CYUT 251


11.7. 選 單 和 工 具 列 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

✡✝<br />

✆<br />

5. 將 action 都 插 入 選 單 和 工 具 列 中 , 並 在 new_file 和 quit_action<br />

之 間 插 入 一 個 分 隔 行 :<br />

圲<br />

圴<br />

圶<br />

✞<br />

}<br />

✡✝<br />

new_file->plug(file_menu);<br />

file_menu->insertSeparator();<br />

quit_action->plug(file_menu);<br />

help_action->plug(help_menu);<br />

new_file->plug(toolBar());<br />

quit_action->plug(toolBar());<br />

✆<br />

6. slot 的 定 義 :aboutApp 產 生 一 個 KAbout 對 話 窗 , 顯 示 程 式 的 相 關 資<br />

訊 。<br />

✞<br />

圱 void KDEMenu::newFile()<br />

{<br />

圳 // Create new File<br />

}<br />

圵 void KDEMenu::aboutApp()<br />

{<br />

圷 KAboutDialog *about = new KAboutDialog(this, "dialog");<br />

about->setAuthor(QString("A. N. Author"), QString("<br />

an@email.net"),<br />

圹<br />

QString("http://url.com"), QString("work"<br />

));<br />

about->setVersion("1.0");<br />

圱 圱 about->show();<br />

}<br />

圱 圳<br />

int main(int argc, char **argv)<br />

圱 圵 {<br />

KApplication app( argc, argv, "cdapp" );;<br />

圱 圷 KDEMenu *window = new KDEMenu("kdemenu");<br />

app.setMainWidget(window);<br />

圱 圹 window->show();<br />

return app.exec();<br />

圲 圱 }<br />

✡✝<br />

✆<br />

7. 提 供 一 個 menu.pro 檔 案 給 予 qmake:<br />

✞<br />

圱 TARGET = kdemenu<br />

MOC_DIR = moc<br />

圳 OBJECTS_DIR = obj<br />

De-Yu Wang CSIE CYUT 252


11.7. 選 單 和 工 具 列 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

INCLUDEPATH = /usr/include/kde<br />

圵 QMAKE_LIBDIR_X11 += -L$KDEDIR/lib<br />

QMAKE_LIBS_X11 += -lkdeui -lkdecore<br />

圷 SOURCES = KDEMenu.cpp<br />

HEADERS = KDEMenu.h<br />

✡✝<br />

✆<br />

8. 執 行 qmake 來 產 生 Makefile, 隨 後 再 進 行 編 譯 、 執 行 程 式 。<br />

✞<br />

$ qmake menu.prop -o Makefile<br />

圲 $ make<br />

$ ./kdemenu<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 253


11.7. 選 單 和 工 具 列 CHAPTER 11. * 使 用 QT 設 計 KDE 視 窗 程 式<br />

De-Yu Wang CSIE CYUT 254


CHAPTER 12.<br />

PYTHON<br />

Chapter 12<br />

Python<br />

12.1 Python 簡 介<br />

1. Python 特 色<br />

(a) 與 shell scripts 相 似 , 是 直 譯 式 程 式 。<br />

(b) 互 動 式 程 式 , 執 行 過 程 中 可 與 程 式 互 動 。<br />

(c) 物 件 導 向 程 式 。<br />

(d) 跨 平 台 , 未 經 修 改 下 可 在 <strong>Linux</strong>,Windows,MacOS X 和 其 他 平 台 上 使<br />

用 。<br />

(e) 易 讀 、 易 學 、 易 維 護 , 適 合 初 學 者 。<br />

(f) 可 設 計 各 種 應 用 程 式 , 從 文 字 處 理 、www 網 頁 瀏 覽 器 至 遊 戲 都 可 完 成 。<br />

2. Python 歷 史<br />

(a) Python 構 想 起 於 1980 年 代 後 期 ,1989 年 12 月 Guido van Rossum<br />

於 荷 蘭 國 家 數 學 及 計 算 機 科 學 研 究 所 發 展 出 來 。<br />

(b) Python 由 許 多 程 式 語 言 發 展 出 來 , 包 含 ABC, Modula-3, C, C++,<br />

Algol-68, SmallTalk, <strong>Unix</strong> shell 及 其 他 腳 本 語 言 。<br />

(c) Python 由 GNU General Public License (GPL) 授 權 , 原 始 碼 可 自 由<br />

獲 得 。<br />

(d) 1994 年 1 月 釋 出 1.0 版 。<br />

3. python 發 展 前 景 參 考 資 料 來 源<br />

(a) Python 對 於 <strong>Linux</strong> 管 理 員 是 否 必 要 <br />

<strong>Linux</strong>Career.com 在 大 約 20% 的 職 位 中 將 Python 能 力 作 為 關 鍵 性 技<br />

術 加 以 考 量 。<br />

De-Yu Wang CSIE CYUT 255


12.1. PYTHON 簡 介 CHAPTER 12. PYTHON<br />

(b) <strong>Linux</strong> 社 群 如 何 看 待 Python<br />

<strong>Linux</strong> Journal 在 2011 年 9 月 , 網 路 所 進 行 的 調 查 ,24% 將 Python<br />

Language Number of votes %<br />

Python 2,025 24%<br />

C 1,661 19%<br />

C++ 1,488 17%<br />

Java 1,118 13%<br />

列 為 自 己 最 喜 歡 的 程 式 語 言 。<br />

Perl 674 8%<br />

Other 670 8%<br />

C# 399 5%<br />

Ruby 361 4%<br />

Haskell 126 1%<br />

Ocaml 47 1%<br />

Totals 8,569 100%<br />

(c) Python 目 前 已 經 由 Google 大 範 圍 使 用 。<br />

(d) Python 是 一 種 大 而 全 面 的 程 式 語 言 , 根 據 TIOBE 的 索 引 , 截 至 2011<br />

年 8 月 止 ,Python 排 在 十 大 程 式 語 言 榜 中 的 第 八 位 。<br />

(e) Python 能 在 跨 平 台 的 系 統 中 使 用 , 且 具 備 良 好 的 擴 展 性 , 相 信 Python<br />

的 前 景 是 成 長 。<br />

4. python 的 安 裝 與 執 行<br />

(a) 在 CentOS 6 安 裝 python<br />

✞<br />

圱 [root@deuu ~]# yum install python -y<br />

[root@deuu ~]# yum install glade3 -y<br />

✡✝<br />

✆<br />

(b) 執 行 python<br />

✞<br />

[dywang@deyu glade]$ python<br />

圲 Python 2.6.5 (r265:79063, Nov 12 2010, 00:52:45)<br />

[GCC 4.4.4 20100525 (Red Hat 4.4.4-5)] on linux2<br />

圴<br />

Type "help", "copyright", "credits" or "license" for more<br />

information.<br />

>>> a=3<br />

圶 >>> b=4<br />

>>> a+b<br />

圸 7<br />

>>><br />

圱 地<br />

圱 圲<br />

>>> quit<br />

Use quit() or Ctrl-D (i.e. EOF) to exit<br />

>>> quit()<br />

[dywang@deyu glade]$<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 256


12.1. PYTHON 簡 介 CHAPTER 12. PYTHON<br />

(c) 寫 成 python 腳 本 abc.py 執 行 :<br />

✞<br />

圱 [dywang@deyu glade]$ vim abc.py<br />

a=4<br />

圳 b=3<br />

print a+b<br />

圵 [dywang@deyu glade]$ python abc.py<br />

7<br />

✡✝<br />

✆<br />

(d) 在 腳 本 第 一 行 宣 告 使 用 python 執 行 abc.py:<br />

✞<br />

[dywang@deyu glade]$ vim abc.py<br />

圲 #!/usr/bin/python<br />

a=4<br />

圴 b=3<br />

print a+b<br />

圶 [dywang@deyu glade]$ chmod a+x abc.py<br />

[dywang@deyu glade]$ ./abc.py<br />

圸 7<br />

✡✝<br />

✆<br />

5. python 內 縮 語 法 :<br />

(a) 一 般 程 式 語 言 對 於 控 制 流 程 、 函 式 、 類 別 等 區 塊 程 式 碼 , 開 始 與 結 束 會<br />

以 指 定 的 碼 來 對 應 。 例 如 :shell script 的 if 判 斷 式 , 結 束 程 式 碼<br />

為 fi。 但 對 於 程 式 碼 的 內 縮 排 列 則 不 規 定 。<br />

(b) python 最 特 別 的 設 計 是 以 內 縮 來 判 斷 控 制 流 程 、 函 式 等 區 塊 程 式 碼 的<br />

開 始 與 結 束 , 因 此 每 段 區 塊 程 式 碼 都 沒 有 結 束 程 式 碼 的 設 計 。<br />

(c) 我 認 為 這 是 相 當 好 的 設 計 , 這 種 設 計 不 但 可 減 少 程 式 碼 , 更 可 強 迫 程 式<br />

撰 寫 者 以 階 層 式 撰 寫 , 讓 程 式 更 容 易 解 讀 。<br />

(d) 強 烈 建 議 以 tab 鍵 進 行 內 縮 , 不 要 使 用 空 白 內 縮 內 縮 。 要 對 齊 才 算 是<br />

同 區 塊 程 式 碼 , 若 用 4 個 空 白 內 縮 , 則 同 區 塊 程 式 都 要 用 4 個 空 白 對<br />

齊 , 即 使 tab 設 定 為 4 個 空 白 位 置 , 也 無 法 執 行 。<br />

(e) 錯 誤 的 python 程 式 碼<br />

✞<br />

[dywang@deyu glade]$ vim error.py<br />

圲 [dywang@deyu glade]$ cat error.py<br />

if True:<br />

圴 print "Yes"<br />

else:<br />

圶 print "NO"<br />

[dywang@deyu glade]$ python error.py<br />

圸 File "error.py", line 2<br />

print "Yes"<br />

圱 地<br />

^<br />

De-Yu Wang CSIE CYUT 257


12.1. PYTHON 簡 介 CHAPTER 12. PYTHON<br />

IndentationError: expected an indented block<br />

✡✝<br />

✆<br />

(f) 正 確 的 python 程 式 :<br />

✞<br />

圱 [dywang@deyu glade]$ vim correct.py<br />

[dywang@deyu glade]$ cat crooect.py<br />

圳 if True:<br />

print "Yes"<br />

圵 else:<br />

print "NO"<br />

圷 [dywang@deyu glade]$ python crooect.py<br />

Yes<br />

✡✝<br />

✆<br />

6. python 括 號 、 引 號 、 換 行 、 註 解<br />

(a) 與 shell script 一 樣 , 可 使 用 倒 斜 線 \ 沿 續 下 一 行 。<br />

✞<br />

[dywang@deyu glade]$ vim correct.py<br />

圲 [dywang@deyu glade]$ cat correct.py<br />

if True:<br />

圴 print "Yes \<br />

new line"<br />

圶 else:<br />

print "NO"<br />

圸 [dywang@deyu glade]$ python correct.py<br />

Yes new line<br />

✡✝<br />

✆<br />

(b) 大 中 小 括 號 {} [] () 可 以 不 在 同 一 行 。<br />

✞<br />

圱 days = [’Monday’, ’Tuesday’, ’Wednesday’,<br />

’Thursday’, ’Friday’]<br />

✡✝<br />

✆<br />

(c) 註 解 :<br />

✞<br />

# 空 白 行 視 為 註 解<br />

圲 # 符 號 # 後 的 文 字 為 註 解 這 是 註 解<br />

’’<br />

圴 " 這 是 註 解 " 這 是 註 解<br />

’’’’<br />

圶 "" 這 是 註 解 ""<br />

""" 這 是 註 解 這 是 也 是 註 解<br />

圸<br />

""" 與 """ 之 間 文 字 都 為 註 解<br />

De-Yu Wang CSIE CYUT 258


12.2. PYTHON 變 數 CHAPTER 12. PYTHON<br />

圱 地 """<br />

# 成 對 的 單 引 號 雙 引 號 之 間 為 字 串 , 且 可 換 行 。 因 不 執 行 故 都 為 註 解 。<br />

圱 圲<br />

days = [’Monday’, ’Tuesday’, ’Wednesday’,<br />

圱 圴<br />

’Thursday’, ’Friday’]<br />

✡✝<br />

✆<br />

(d) 與 shell script 一 樣 , 可 以 使 用 分 號 ; 將 多 個 命 令 放 在 同 一 行 。<br />

✞<br />

a=4; b=3; print a+b<br />

✡✝<br />

✆<br />

12.2 Python 變 數<br />

1. python 變 數<br />

(a) 變 數 直 接 使 用 , 不 需 宣 告 :<br />

✞<br />

圱 #!/usr/bin/python<br />

圳 counter = 100 # An integer assignment<br />

miles = 1000.0 # A floating point<br />

圵 name<br />

✡✝<br />

= "Devid" # A string<br />

✆<br />

(b) 多 個 變 數 一 起 指 定 :<br />

✞<br />

圱 a=b=c=1<br />

a,b,c=1,2,"Devid"<br />

✡✝<br />

✆<br />

(c) 變 數 指 定 後 , 變 數 型 態 就 固 定 , 重 新 指 定 新 型 態 的 值 , 等 同 重 新 宣 告 :<br />

✞<br />

a=1<br />

圲 a="Devid"<br />

✡✝<br />

✆<br />

(d) 變 數 的 刪 除 :<br />

✞<br />

a=b=c=1<br />

圲 del a<br />

✡✝<br />

✆<br />

2. python 字 串 處 理<br />

De-Yu Wang CSIE CYUT 259


12.2. PYTHON 變 數 CHAPTER 12. PYTHON<br />

(a) 字 串 變 數 以 單 引 號 ’ 或 雙 引 號 " 括 起 來 。<br />

✞<br />

name<br />

✡✝<br />

= "Devid" # A string<br />

✆<br />

(b) 字 串 變 數 為 字 元 陣 列 :<br />

✞<br />

圱 [dywang@deyu glade]$ cat str.py<br />

#/usr/bin/python<br />

圳 # coding: utf-8<br />

圵 name = "David"<br />

print name<br />

# 印 出 整 個 字 串<br />

圷 print name[0] # 印 出 第 1 個 字 元<br />

print name[1:3] # 印 出 第 2 至 4 個 字 元<br />

圹 print name[1:] # 印 出 第 2 至 最 後 一 個 字 元<br />

print name * 3<br />

# 印 出 字 串 三 次<br />

圱 圱 print name + " csie" # 印 出 連 續 字 串<br />

圱 圳 [dywang@deyu glade]$ python str.py<br />

David<br />

圱 圵 D<br />

av<br />

圱 圷 avid<br />

DavidDavidDavid<br />

圱 圹 David csie<br />

✡✝<br />

✆<br />

3. python 陣 列 處 理<br />

(a) lists 陣 列<br />

✞<br />

圱 [dywang@deyu glade]$ cat lists.py<br />

#/usr/bin/python<br />

圳 # coding: utf-8<br />

圵 list = [ "David", 123, 23.4, ’abc’, 4.321 ]<br />

tinylist = [ 98, ’Rita’ ]<br />

圷 print list # 印 出 整 個 陣 列<br />

print list[0]<br />

# 印 出 陣 列 第 1 個 元 素<br />

圹 print list[1:3] # 印 出 陣 列 第 2 至 4 個 元 素<br />

print list[1:]<br />

# 印 出 陣 列 第 2 至 最 後 一 個 元 素<br />

圱 圱 print tinylist * 2 # 印 出 陣 列 二 次<br />

print tinylist + list # 印 出 連 續 陣 列<br />

圱 圳<br />

[dywang@deyu glade]$ python lists.py<br />

圱 圵 [’David’, 123, 23.399999999999999, ’abc’, 4.3209999999999997]<br />

David<br />

De-Yu Wang CSIE CYUT 260


12.2. PYTHON 變 數 CHAPTER 12. PYTHON<br />

圱 圷 [123, 23.399999999999999]<br />

[123, 23.399999999999999, ’abc’, 4.3209999999999997]<br />

圱 圹 [98, ’Rita’, 98, ’Rita’]<br />

[98, ’Rita’, ’David’, 123, 23.399999999999999, ’abc’,<br />

4.3209999999999997]<br />

✡✝<br />

✆<br />

(b) tuples 陣 列 : 唯 讀 的 lists<br />

✞<br />

[dywang@deyu glade]$ cat tuples.py<br />

圲 #/usr/bin/python<br />

# coding: utf-8<br />

圴<br />

list = ( "David", 123, 23.4, ’abc’, 4.321 )<br />

圶 tinylist = ( 98, ’Rita’ )<br />

print list<br />

# 印 出 整 個 陣 列<br />

圸 print list[0] # 印 出 陣 列 第 1 個 元 素<br />

print list[1:3] # 印 出 陣 列 第 2 至 4 個 元 素<br />

圱 地 print list[1:] # 印 出 陣 列 第 2 至 最 後 一 個 元 素<br />

print tinylist * 2 # 印 出 陣 列 二 次<br />

圱 圲 print tinylist + list # 印 出 連 續 陣 列<br />

[dywang@deyu glade]$ python tuples.py<br />

圱 圴 (’David’, 123, 23.399999999999999, ’abc’, 4.3209999999999997)<br />

David<br />

圱 圶 (123, 23.399999999999999)<br />

(123, 23.399999999999999, ’abc’, 4.3209999999999997)<br />

圱 圸 (98, ’Rita’, 98, ’Rita’)<br />

(98, ’Rita’, ’David’, 123, 23.399999999999999, ’abc’,<br />

✡✝<br />

4.3209999999999997)<br />

✆<br />

(c) lists 與 tuples 陣 列 比 較<br />

✞<br />

圱 [dywang@deyu glade]$ cat list_tuple.py<br />

#/usr/bin/python<br />

圳 # coding: utf-8<br />

圵 list = [ "David", 123, 23.4, ’abc’, 4.321 ]<br />

tuple = ( "David", 123, 23.4, ’abc’, 4.321 )<br />

圷 list[3] = ’xyz’ # 有 效 語 法<br />

tuple[3] = ’xyz’ # 無 效 語 法<br />

圹 [dywang@deyu glade]$ python list_tuple.py<br />

Traceback (most recent call last):<br />

圱 圱 File "list_tuple.py", line 7, in <br />

tuple[3] = ’xyz’ # 無 效 語 法<br />

圱 圳 TypeError: ’tuple’ object does not support item assignment<br />

✡✝<br />

✆<br />

(d) dictionaries 陣 列 :<br />

De-Yu Wang CSIE CYUT 261


12.2. PYTHON 變 數 CHAPTER 12. PYTHON<br />

圱<br />

圳<br />

✞<br />

[dywang@deyu glade]$ cat dict.py<br />

#/usr/bin/python<br />

# coding: utf-8<br />

圵 dict = {}<br />

dict[’peter’] = "1234"<br />

圷 dict[2] = "rita"<br />

圹<br />

tinydict = {’name’: ’devid’,’code’:4538, ’dept’: ’csie’}<br />

圱 圱 print dict[’peter’] # Prints value for ’peter’ key<br />

print dict[2]<br />

# Prints value for 2 key<br />

圱 圳 print tinydict # Prints complete dictionary<br />

print tinydict.keys() # Prints all the keys<br />

圱 圵 print tinydict.values() # Prints all the values<br />

圱 圷 [dywang@deyu glade]$ python dict.py<br />

1234<br />

圱 圹 rita<br />

{’dept’: ’csie’, ’code’: 4538, ’name’: ’devid’}<br />

圲 圱 [’dept’, ’code’, ’name’]<br />

[’csie’, 4538, ’devid’]<br />

圲 圳 # dictionaries 沒 有 順 序 概 念<br />

✡✝<br />

✆<br />

4. if __name__ == "__main__":<br />

✞<br />

圱 [dywang@deyu python]$ cat mypy.py<br />

#!/usr/bin/python<br />

圳 # coding: utf-8<br />

圵<br />

圷<br />

圹<br />

圱 圱<br />

圱 圳<br />

圱 圵<br />

圱 圷<br />

圱 圹<br />

圲 圱<br />

class myPy:<br />

print "class my first python"<br />

if __name__ == "__main__":<br />

print __name__<br />

myPy()<br />

else:<br />

print __name__<br />

[dywang@deyu python]$ cat test.py<br />

#!/usr/bin/python<br />

import mypy<br />

mypy.__name__<br />

[dywang@deyu python]$ python test.py<br />

mypy<br />

De-Yu Wang CSIE CYUT 262


12.3. PYTHON 運 算 子 CHAPTER 12. PYTHON<br />

圲 圳<br />

[dywang@deyu python]$ python mypy.py<br />

圲 圵 __main__<br />

✡✝<br />

✆<br />

12.3 python 運 算 子<br />

1. Python - Basic Operators<br />

12.4 python 流 程 控 制<br />

1. Python - IF...ELIF...ELSE Statement<br />

2. Python - while Loop Statements<br />

3. Python - for Loop Statements<br />

4. Python - break,continue and pass Statements<br />

12.5 python 函 式 與 模 組<br />

1. Python - Functions<br />

2. Python - Modules<br />

3. Python - Regular Expressions<br />

12.6 python I/O 與 Exceptions<br />

1. Python - Files I/O<br />

2. Python - Expections Handling<br />

De-Yu Wang CSIE CYUT 263


12.6. PYTHON I/O 與 EXCEPTIONS CHAPTER 12. PYTHON<br />

De-Yu Wang CSIE CYUT 264


CHAPTER 13.<br />

PYGTK<br />

Chapter 13<br />

PyGTK<br />

13.1 PyGTK 簡 介 與 開 始<br />

1. PyGTK 簡 介<br />

(a) PyGTK 是 GNOME 專 案 的 一 部 分 , 作 者 是 著 名 的 GNOME 開 發 者 James<br />

Henstridge。<br />

(b) PyGTK 是 一 套 用 Python 封 裝 的 , 用 於 GTK+ 的 GUI 庫 。<br />

(c) PyGTK 是 在 LGPL 授 權 下 的 自 由 軟 體 , 可 以 自 由 修 改 、 散 佈 及 研 究 。<br />

(d) PyGTK 跨 平 台 , 未 經 修 改 下 可 在 <strong>Linux</strong>,Windows,MacOS X 和 其 他 平 台<br />

上 使 用 。<br />

(e) PyGTK 所 開 發 的 應 用 程 式 更 已 被 選 應 用 於 每 童 一 電 腦 (One Laptop Per<br />

Child,OLPC) 的 系 統 之 上 。<br />

(f) PyGTK 非 常 容 易 使 用 , 是 最 受 歡 迎 的 GTK+ 函 式 庫 之 一 。<br />

(g) PyGTK 提 供 所 有 圖 形 界 面 元 件 及 有 用 的 程 式 設 施 來 產 生 桌 面 應 用 程 式 。<br />

2. 第 一 支 程 式<br />

✞<br />

圱 [dywang@deyu python]$ cat mypy.py<br />

#!/usr/bin/python<br />

圳 # coding: utf-8<br />

圵<br />

圷<br />

圹<br />

圱 圱<br />

圱 圳<br />

圱 圵<br />

import gtk<br />

class myPy:<br />

def __init__(self):<br />

window = gtk.Window(gtk.WINDOW_TOPLEVEL)<br />

"lambda 是 匿 名 函 式 x 為 其 參 數 "<br />

window.connect("destroy", lambda x: gtk.main_quit())<br />

window.set_title 視 窗 抬 頭 (’’)<br />

window.set_keep_above(True)<br />

window.show()<br />

De-Yu Wang CSIE CYUT 265


13.2. BUTTONS 與 LAYOUT CHAPTER 13. PYGTK<br />

myPy()<br />

圱 圷 gtk.main()<br />

✡✝<br />

✆<br />

3. 類 別 相 關 聯 結<br />

(a) gtk.Widget class<br />

(b) gtk.Window class<br />

(c) gtk Functions<br />

(d) python:<br />

Lambda Functions<br />

13.2 Buttons 與 Layout<br />

1. Example<br />

✞<br />

圱 #!/usr/bin/python<br />

# coding: utf-8<br />

圳<br />

#import pygtk<br />

圵 import gtk<br />

圷<br />

圹<br />

圱 圱<br />

圱 圳<br />

class myPy:<br />

def __init__(self):<br />

window = gtk.Window(gtk.WINDOW_TOPLEVEL)<br />

"lambda 是 匿 名 函 式 x 為 其 參 數 "<br />

window.connect("destroy", lambda x: gtk.main_quit())<br />

window.set_title 視 窗 抬 頭 (’’)<br />

window.set_keep_above(True)<br />

圱 圵 vbox1 = gtk.VBox(False, 2)<br />

"homogeneous=True 則 內 含 物 件 平 均 分 佈 ,spaceing=5 間 隔 5<br />

圱 圷<br />

hbox1 = gtk.HBox(homogeneous=True,spacing=5)<br />

hbox2 = gtk.HBox(homogeneous=True,spacing=5)<br />

圱 圹<br />

hbox3 = gtk.HBox(homogeneous=True,spacing=5)<br />

yes = gtk.Button("yes")<br />

圲 圱<br />

no = gtk.Button("no")<br />

close = gtk.Button(None,gtk.STOCK_CLOSE)<br />

圲 圳<br />

hbox1.add(yes)<br />

hbox1.add(no)<br />

圲 圵<br />

hbox2.add(close)<br />

vbox1.pack_start(hbox1, True, True, 0)<br />

圲 圷 vbox1.pack_start(hbox2, True, True, 0)<br />

vbox1.pack_start(hbox3, True, True, 0)<br />

圲 圹<br />

window.add(vbox1)<br />

圳 圱<br />

window.show_all()<br />

De-Yu Wang CSIE CYUT 266


13.3. SIGNALS, EVENTS AND FUNCTIONS CHAPTER 13. PYGTK<br />

圳 圳<br />

myPy()<br />

gtk.main()<br />

✡✝<br />

✆<br />

2. 類 別 相 關 聯 結<br />

(a) gtk.Vbox class<br />

(b) gtk.Box class<br />

(c) gtk.Hbox class<br />

(d) gtk.Button class<br />

(e) Stock Items<br />

13.3 Signals, Events and Functions<br />

1. Example1<br />

✞<br />

#!/usr/bin/python<br />

圲 # coding: utf-8<br />

圴<br />

圶<br />

圸<br />

圱 地<br />

圱 圲<br />

圱 圴<br />

#import pygtk<br />

import gtk<br />

class myPy:<br />

def callback(self, widget, data):<br />

if data == "yes":<br />

print "yes"<br />

elif data == "no":<br />

print "no"<br />

else:<br />

print "yes|no"<br />

圱 圶 def __init__(self):<br />

window = gtk.Window(gtk.WINDOW_TOPLEVEL)<br />

圱 圸 "lambda 是 匿 名 函 式 x 為 其 參 數 "<br />

window.connect("destroy", lambda x: gtk.main_quit())<br />

圲 地 window.set_title 視 窗 抬 頭 (’’)<br />

window.set_keep_above(True)<br />

圲 圲<br />

vbox1 = gtk.VBox(False, 2)<br />

圲 圴<br />

hbox1 = gtk.HBox(homogeneous=True,spacing=5)<br />

hbox2 = gtk.HBox(homogeneous=True,spacing=5)<br />

圲 圶<br />

hbox3 = gtk.HBox(homogeneous=True,spacing=5)<br />

yes = gtk.Button("yes")<br />

圲 圸<br />

no = gtk.Button("no")<br />

close = gtk.Button(None,gtk.STOCK_CLOSE)<br />

圳 地<br />

close.connect("clicked", lambda x: gtk.main_quit())<br />

yes.connect("clicked", self.callback, ’yes’)<br />

De-Yu Wang CSIE CYUT 267


13.3. SIGNALS, EVENTS AND FUNCTIONS CHAPTER 13. PYGTK<br />

圳 圲<br />

no.connect("clicked", self.callback, ’no’)<br />

hbox1.add(yes)<br />

圳 圴<br />

hbox1.add(no)<br />

hbox2.add(close)<br />

圳 圶 vbox1.pack_start(hbox1, True, True, 0)<br />

vbox1.pack_start(hbox2, True, True, 0)<br />

圳 圸 vbox1.pack_start(hbox3, True, True, 0)<br />

window.add(vbox1)<br />

圴 地<br />

window.show_all()<br />

圴 圲<br />

myPy()<br />

圴 圴 gtk.main()<br />

✡✝<br />

✆<br />

2. Example2<br />

✞<br />

#!/usr/bin/python<br />

圲 # coding: utf-8<br />

圴<br />

圶<br />

圸<br />

圱 地<br />

#import pygtk<br />

import gtk<br />

import subprocess<br />

icondir="/usr/share/icons/gnome/16x16"<br />

yes_icon = icondir+"/stock/generic/stock_calc-accept.png"<br />

no_icon = icondir+"/stock/generic/stock_calc-cancel.png"<br />

圱 圲 def img_label_box(parent, img_file, label):<br />

box = gtk.HBox(False, 0)<br />

圱 圴 box.set_border_width(2)<br />

image = gtk.Image()<br />

圱 圶 image.set_from_file(img_file)<br />

label = gtk.Label(label)<br />

圱 圸 box.pack_start(image, False, False, 5)<br />

box.pack_start(label, False, False, 5)<br />

圲 地 image.show()<br />

label.show()<br />

圲 圲 return box<br />

圲 圴<br />

圲 圶<br />

圲 圸<br />

圳 地<br />

圳 圲<br />

class myPy:<br />

def callback(self, widget, data):<br />

if data == "yes":<br />

subprocess.Popen("gnome-terminal",shell=True)<br />

elif data == "no":<br />

print "no"<br />

else:<br />

print "yes|no"<br />

def __init__(self):<br />

De-Yu Wang CSIE CYUT 268


13.4. LABEL AND ENTRY CHAPTER 13. PYGTK<br />

圳 圴<br />

圳 圶<br />

圳 圸<br />

window = gtk.Window(gtk.WINDOW_TOPLEVEL)<br />

"lambda 是 匿 名 函 式 x 為 其 參 數 "<br />

window.connect("destroy", lambda x: gtk.main_quit())<br />

window.set_title 視 窗 抬 頭 (’’)<br />

window.set_keep_above(True)<br />

圴 地 vbox1 = gtk.VBox(False, 2)<br />

hbox1 = gtk.HBox(homogeneous=True,spacing=5)<br />

圴 圲<br />

hbox2 = gtk.HBox(homogeneous=True,spacing=5)<br />

hbox3 = gtk.HBox(homogeneous=True,spacing=5)<br />

圴 圴<br />

yes = gtk.Button()<br />

no = gtk.Button()<br />

圴 圶<br />

close = gtk.Button(None,gtk.STOCK_CLOSE)<br />

close.set_use_stock(True)<br />

圴 圸<br />

close.connect("clicked", lambda x: gtk.main_quit())<br />

yes.connect("clicked", self.callback, ’yes’)<br />

圵 地<br />

no.connect("clicked", self.callback, ’no’)<br />

box_yes = img_label_box(window, yes_icon, "YES")<br />

圵 圲<br />

box_no = img_label_box(window, no_icon, "NO")<br />

yes.add(box_yes)<br />

圵 圴<br />

no.add(box_no)<br />

hbox1.add(yes)<br />

圵 圶<br />

hbox1.add(no)<br />

hbox2.add(close)<br />

圵 圸 vbox1.pack_start(hbox1, True, True, 0)<br />

vbox1.pack_start(hbox2, True, True, 0)<br />

圶 地 vbox1.pack_start(hbox3, True, True, 0)<br />

window.add(vbox1)<br />

圶 圲<br />

window.show_all()<br />

圶 圴<br />

myPy()<br />

圶 圶 gtk.main()<br />

✡✝<br />

✆<br />

3. 類 別 相 關 聯 結<br />

(a) gtk.Button class<br />

13.4 Label and Entry<br />

1. Example1: Label<br />

✞<br />

#!/usr/bin/python<br />

圲 # coding: utf-8<br />

圴<br />

圶<br />

#import pygtk<br />

import gtk<br />

import subprocess<br />

De-Yu Wang CSIE CYUT 269


13.4. LABEL AND ENTRY CHAPTER 13. PYGTK<br />

圸<br />

圱 地<br />

icondir="/usr/share/icons/gnome/16x16"<br />

yes_icon = icondir+"/stock/generic/stock_calc-accept.png"<br />

no_icon = icondir+"/stock/generic/stock_calc-cancel.png"<br />

圱 圲 def img_label_box(parent, img_file, label):<br />

box = gtk.HBox(False, 0)<br />

圱 圴 box.set_border_width(2)<br />

image = gtk.Image()<br />

圱 圶 image.set_from_file(img_file)<br />

label = gtk.Label(label)<br />

圱 圸 box.pack_start(image, False, False, 5)<br />

box.pack_start(label, False, False, 5)<br />

圲 地 image.show()<br />

label.show()<br />

圲 圲 return box<br />

圲 圴<br />

圲 圶<br />

圲 圸<br />

圳 地<br />

圳 圲<br />

圳 圴<br />

圳 圶<br />

圳 圸<br />

class myPy:<br />

def callback(self, widget, data):<br />

if data == "yes":<br />

subprocess.Popen("gnome-terminal",shell=True)<br />

elif data == "no":<br />

self.label.set_text("no")<br />

else:<br />

print "yes|no"<br />

def __init__(self):<br />

window = gtk.Window(gtk.WINDOW_TOPLEVEL)<br />

"lambda 是 匿 名 函 式 x 為 其 參 數 "<br />

window.connect("destroy", lambda x: gtk.main_quit())<br />

window.set_title 視 窗 抬 頭 (’’)<br />

window.set_keep_above(True)<br />

圴 地 vbox1 = gtk.VBox(False, 2)<br />

hbox1 = gtk.HBox(homogeneous=True,spacing=5)<br />

圴 圲<br />

hbox2 = gtk.HBox(homogeneous=True,spacing=5)<br />

hbox3 = gtk.HBox(homogeneous=True,spacing=5)<br />

圴 圴<br />

yes = gtk.Button()<br />

no = gtk.Button()<br />

圴 圶<br />

close = gtk.Button(None,gtk.STOCK_CLOSE)<br />

close.set_use_stock(True)<br />

圴 圸<br />

close.connect("clicked", lambda x: gtk.main_quit())<br />

yes.connect("clicked", self.callback, ’yes’)<br />

圵 地<br />

no.connect("clicked", self.callback, ’no’)<br />

box_yes = img_label_box(window, yes_icon, "YES")<br />

圵 圲<br />

box_no = img_label_box(window, no_icon, "NO")<br />

yes.add(box_yes)<br />

圵 圴<br />

no.add(box_no)<br />

self.label=gtk.Label("Yes|No")<br />

圵 圶<br />

hbox1.add(yes)<br />

hbox1.add(no)<br />

De-Yu Wang CSIE CYUT 270


13.4. LABEL AND ENTRY CHAPTER 13. PYGTK<br />

圵 圸<br />

hbox2.add(close)<br />

hbox3.add(self.label)<br />

圶 地 vbox1.pack_start(hbox1, True, True, 0)<br />

vbox1.pack_start(hbox2, True, True, 0)<br />

圶 圲 vbox1.pack_start(hbox3, True, True, 0)<br />

window.add(vbox1)<br />

圶 圴<br />

window.show_all()<br />

圶 圶<br />

myPy()<br />

圶 圸 gtk.main()<br />

✡✝<br />

✆<br />

2. Example2: Entry<br />

✞<br />

#!/usr/bin/python<br />

圲 # coding: utf-8<br />

圴<br />

圶<br />

圸<br />

圱 地<br />

#import pygtk<br />

import gtk<br />

import subprocess<br />

icondir="/usr/share/icons/gnome/16x16"<br />

yes_icon = icondir+"/stock/generic/stock_calc-accept.png"<br />

no_icon = icondir+"/stock/generic/stock_calc-cancel.png"<br />

圱 圲 def img_label_box(parent, img_file, label):<br />

box = gtk.HBox(False, 0)<br />

圱 圴 box.set_border_width(2)<br />

image = gtk.Image()<br />

圱 圶 image.set_from_file(img_file)<br />

label = gtk.Label(label)<br />

圱 圸 box.pack_start(image, False, False, 5)<br />

box.pack_start(label, False, False, 5)<br />

圲 地 image.show()<br />

label.show()<br />

圲 圲 return box<br />

圲 圴<br />

圲 圶<br />

圲 圸<br />

圳 地<br />

圳 圲<br />

圳 圴<br />

class myPy:<br />

def callback(self, widget, data):<br />

if data == "yes":<br />

subprocess.Popen("gnome-terminal",shell=True)<br />

elif data == "no":<br />

self.label.set_text(data)<br />

else:<br />

self.label.set_text("Only yes|no")<br />

def entryChange(self,widget):<br />

if self.entry.get_text() == "yes":<br />

subprocess.Popen("gnome-terminal",shell=True)<br />

De-Yu Wang CSIE CYUT 271


13.4. LABEL AND ENTRY CHAPTER 13. PYGTK<br />

圳 圶<br />

圳 圸<br />

圴 地<br />

self.label.set_text("yes")<br />

elif self.entry.get_text() == "no":<br />

self.label.set_text("no")<br />

else:<br />

self.label.set_text("Only yes|no")<br />

圴 圲 def __init__(self):<br />

window = gtk.Window(gtk.WINDOW_TOPLEVEL)<br />

圴 圴 "lambda 是 匿 名 函 式 x 為 其 參 數 "<br />

window.connect("destroy", lambda x: gtk.main_quit())<br />

圴 圶 window.set_title 視 窗 抬 頭 (’’)<br />

window.set_keep_above(True)<br />

圴 圸<br />

vbox1 = gtk.VBox(False, 2)<br />

圵 地<br />

hbox1 = gtk.HBox(homogeneous=True,spacing=5)<br />

hbox2 = gtk.HBox(homogeneous=True,spacing=5)<br />

圵 圲<br />

hbox3 = gtk.HBox(homogeneous=True,spacing=5)<br />

yes = gtk.Button()<br />

圵 圴<br />

no = gtk.Button()<br />

close = gtk.Button(None,gtk.STOCK_CLOSE)<br />

圵 圶<br />

close.set_use_stock(True)<br />

self.label=gtk.Label("Yes|No")<br />

圵 圸<br />

self.entry=gtk.Entry()<br />

close.connect("clicked", lambda x: gtk.main_quit())<br />

圶 地<br />

yes.connect("clicked", self.callback, ’yes’)<br />

no.connect("clicked", self.callback, ’no’)<br />

圶 圲<br />

self.entry.connect("changed", self.entryChange)<br />

box_yes = img_label_box(window, yes_icon, "YES")<br />

圶 圴<br />

box_no = img_label_box(window, no_icon, "NO")<br />

yes.add(box_yes)<br />

圶 圶<br />

no.add(box_no)<br />

hbox1.add(yes)<br />

圶 圸<br />

hbox1.add(no)<br />

圷 地<br />

hbox2.add(close)<br />

hbox3.add(self.label)<br />

hbox3.add(self.entry)<br />

圷 圲 vbox1.pack_start(hbox1, True, True, 0)<br />

vbox1.pack_start(hbox2, True, True, 0)<br />

圷 圴 vbox1.pack_start(hbox3, True, True, 0)<br />

window.add(vbox1)<br />

圷 圶<br />

window.show_all()<br />

圷 圸<br />

if __name__ == "__main__":<br />

圸 地 print __name__<br />

myPy()<br />

圸 圲 gtk.main()<br />

else:<br />

圸 圴 print __name__<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 272


13.4. LABEL AND ENTRY CHAPTER 13. PYGTK<br />

3. 類 別 相 關 聯 結<br />

(a) gtk.Label class<br />

(b) gtk.Entry class<br />

De-Yu Wang CSIE CYUT 273


13.4. LABEL AND ENTRY CHAPTER 13. PYGTK<br />

De-Yu Wang CSIE CYUT 274


CHAPTER 14.<br />

GLADE<br />

Chapter 14<br />

Glade<br />

14.1 簡 介<br />

1. 什 麼 是 glade <br />

(a) Glade 是 Rapid application development (RAD) 工 具 , 提 供 使 用 者<br />

容 易 的 GTK+ 工 具 箱 及 GNOME 桌 面 環 境 。<br />

(b) Glade 設 計 好 的 使 用 者 界 面 存 成 XML 檔 , 供 程 式 使 用 。<br />

(c) Glade 的 XML 檔 可 供 無 數 的 程 式 語 言 使 用 , 包 括 C, C++, C#, Vala,<br />

Java, Perl, Python 等 。<br />

(d) Glade 是 GNU GPL License 授 權 的 自 由 軟 體 。<br />

2. glade3 安 裝<br />

✞<br />

圱 [root@dywHome2 ~]# [root@deyu ~]# yum install glade3<br />

✡✝<br />

✆<br />

圱<br />

3. 執 行 glade designer<br />

✞<br />

圖 形 界 面<br />

圳<br />

Applications->Programming->Glade Interface Designer 文 字 界 面<br />

圵<br />

[dywang@deyu glade]$ glade-3<br />

✡✝<br />

✆<br />

4. Glade Interface Designer Demo<br />

5. 撰 寫 python file example1.py<br />

✞<br />

#!/usr/bin/python<br />

圲 # coding: utf-8<br />

De-Yu Wang CSIE CYUT 275


14.1. 簡 介 CHAPTER 14. GLADE<br />

圴<br />

圶<br />

import gtk<br />

import gtk.glade<br />

import subprocess<br />

import sys<br />

圸 class Example1:<br />

def __init__(self):<br />

圱 地<br />

self.gladefile = "example1.glade"<br />

self.wTree = gtk.glade.XML(self.gladefile)<br />

圱 圲 dic = {<br />

"on_window_example1_destroy" :self.quit,<br />

圱 圴<br />

"on_button1_clicked" : self.ok,<br />

"on_button2_clicked" : self.quit,<br />

圱 圶<br />

"on_entry1_changed" : self.entrychanged<br />

}<br />

圱 圸<br />

self.wTree.signal_autoconnect(dic)<br />

self.window = self.wTree.get_widget("window1")<br />

圲 地<br />

self.window.set_keep_above(True)<br />

self.window.show()<br />

圲 圲<br />

def entrychanged(self,widget):<br />

圲 圴<br />

if self.wTree.get_widget("entry1").get_text() == "show":<br />

subprocess.Popen("gnome-terminal",shell=True)<br />

圲 圶<br />

self.wTree.get_widget("label1").set_text("Show<br />

terminal")<br />

else:<br />

圲 圸<br />

self.wTree.get_widget("label1").set_text("Only show")<br />

圳 地<br />

圳 圲<br />

圳 圴<br />

圳 圶<br />

def ok(self,widget):<br />

subprocess.Popen("gnome-terminal",shell=True)<br />

self.wTree.get_widget("label1").set_text("Open terminal")<br />

def quit(self,widget):<br />

sys.exit(0)<br />

圳 圸 if __name__ == "__main__":<br />

Example1()<br />

圴 地 gtk.main()<br />

✡✝<br />

✆<br />

6. 執 行 python<br />

✞<br />

[dywang@deyu glade]$ python example1.py<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 276


14.2. CALCULATOR EXAMPLE CHAPTER 14. GLADE<br />

14.2 Calculator Example<br />

1. 下 載 計 算 機 範 例 檔<br />

calculator.glade<br />

calculatorglade.py<br />

2. 下 載 計 算 機 範 例 檔 ( 增 加 開 根 號 )<br />

calculator1.glade<br />

calculator1.py<br />

3. 以 glade-3 開 啟 calculator.glade<br />

✞<br />

圱 1. table1 Rows: 5 -> 6<br />

2. insert ok button in table1 (0,5)<br />

圳 3. rename ok button Label and Name to Sqrt<br />

4. set Sqrt button clicked Signals to on_Sqrt_clicked<br />

圵 5. vim calculatorglade.py<br />

圷 # coding: utf-8<br />

import sys<br />

圹 import math # 匯 入 數 學 模 組<br />

try:<br />

圱 圱 import pygtk<br />

pygtk.require(’2.0’)<br />

圱 圳 except:<br />

pass<br />

圱 圵 .... omission ....<br />

圱 圷 class Calculator:<br />

.... omission ....<br />

圱 圹<br />

"on_Add_clicked" : self.displayAdd,<br />

"on_Sqrt_clicked" : self.displaySqrt, # 定 義 按 鈕 接 受 函<br />

數 sqrt<br />

圲 圱 .... omission ....<br />

if operator == ’Sqrt’:<br />

圲 圳<br />

self.firstOperand = self.wTree.get_widget("<br />

displayText").get_text()<br />

result = math.sqrt(float(self.firstOperand))<br />

圲 圵<br />

self.wTree.get_widget("displayText").set_text(str(<br />

result))<br />

.... omission ....<br />

圲 圷<br />

def displaySqrt(self,widget): # 定 義 函 數 displaySqrt<br />

圲 圹<br />

self.compute("Sqrt")<br />

✡✝<br />

✆<br />

4. 執 行<br />

✞<br />

圱 [dywang@deyu glade]$ python calculatorglade.py<br />

De-Yu Wang CSIE CYUT 277


14.2. CALCULATOR EXAMPLE CHAPTER 14. GLADE<br />

✡✝<br />

✆<br />

5. 相 關 聯 結<br />

(a) GTK+ and Glade3 GUI Programming Tutorial<br />

(b) 用 Libglade 快 速 開 發 GTK+ 視 窗 程 式<br />

(c) Calculator Program using Python and Glade<br />

(d) Python 教 學<br />

De-Yu Wang CSIE CYUT 278


CHAPTER 15.<br />

*TARBALL 套 件 發 行<br />

Chapter 15<br />

*Tarball 套 件 發 行<br />

15.1 套 件 發 行<br />

• 程 式 發 行 時 要 面 對 :<br />

1. 使 用 者 發 現 臭 蟲 ;<br />

2. 作 者 想 要 提 升 功 能 或 更 新 。<br />

• 解 決 方 法 :<br />

1. 若 發 行 只 提 供 二 進 位 的 程 式 時 , 通 常 只 要 再 補 上 新 版 的 二 進 位 檔 案 即<br />

可 。<br />

2. 供 應 商 直 接 發 表 新 版 的 程 式 。<br />

3. 以 原 始 碼 方 式 發 行 軟 體 , 可 以 讓 使 用 者 檢 查 程 式 的 進 行 , 並 且 再 利 用 部<br />

分 原 始 碼 。<br />

4. patch 命 令 , 讓 您 可 以 只 散 佈 兩 個 版 本 之 間 的 差 異 部 分 。<br />

• 軟 體 的 發 行 方 法 :<br />

1. 將 所 有 檔 案 元 件 包 裝 成 一 個 單 獨 的 檔 案 套 件 ( package )。<br />

2. 使 用 標 準 工 具 管 理 套 件 的 版 本 編 號 。<br />

3. 在 套 件 的 檔 案 名 稱 中 , 加 入 版 本 編 號 , 這 樣 使 用 者 就 可 知 道 他 們 使 用 的<br />

版 本 。<br />

4. 在 套 件 中 使 用 子 目 錄 , 確 保 往 後 解 開 套 件 時 , 檔 案 都 能 放 在 個 別 的 目<br />

錄 。<br />

• 安 裝 與 升 級 套 件<br />

1. 安 裝 與 升 級 之 可 能 原 因 :<br />

(a) 需 要 新 的 功 能 , 但 舊 有 主 機 的 舊 版 套 件 並 沒 有 ;<br />

(b) 舊 版 本 的 套 件 上 面 可 能 有 安 全 上 的 顧 慮 ;<br />

(c) 舊 版 的 套 件 執 行 效 能 不 彰 , 或 者 執 行 的 能 力 不 能 讓 管 理 者 滿 足 。<br />

De-Yu Wang CSIE CYUT 279


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

練 習 題<br />

2. 使 用 之 套 件 的 格 式 :<br />

(a) 原 始 碼 打 包 壓 縮 成 tarball 套 件 ;<br />

(b) 編 譯 好 的 二 進 位 執 行 檔 RPM 套 件 ;<br />

(c) 含 原 始 碼 的 RPM,SRPM 套 件 。<br />

1. 請 列 舉 兩 項 , 軟 體 發 行 後 需 要 修 改 的 原 因 。<br />

Sol. 1. 使 用 者 發 現 臭 蟲 ;2. 作 者 想 要 提 升 功 能 或 更 新 。<br />

2. 軟 體 發 行 後 , 若 要 除 錯 或 更 新 , 比 較 簡 單 的 方 法 為 何 <br />

Sol. 以 原 始 碼 方 式 發 行 軟 體 , 再 以 patch 命 令 , 發 佈 兩 個 版 本 之 間 差 異<br />

部 分 。<br />

3. 軟 體 發 行 時 , 將 所 有 檔 案 元 件 包 裝 成 一 個 單 獨 的 檔 案 , 稱 之 為 何 <br />

Sol. 套 件 ( package )。<br />

4. 軟 體 發 行 後 , 升 級 之 可 能 原 因 為 何 <br />

Sol. 1. 需 要 新 的 功 能 , 但 舊 版 套 件 沒 有 ;2. 舊 版 套 件 可 能 有 安 全 的 顧<br />

慮 ;3. 舊 版 套 件 執 行 效 能 不 彰 。<br />

5. 軟 體 發 行 , 安 裝 及 升 級 的 方 式 為 何 <br />

Sol. 1. 原 始 碼 tarball;2. 編 譯 好 的 RPM 套 件 ;3. 原 始 碼 RPM 之 SRPM<br />

套 件 。<br />

15.2 Tarballs 簡 介<br />

• 何 謂 Tarball 套 件 <br />

1. Tarball: 壓 縮 過 的 TAR(tape archive) 檔 案 。<br />

2. <strong>Linux</strong> 程 式 和 原 始 碼 通 常 是 以 一 個 tarball 檔 案 的 方 式 散 佈 。<br />

3. 程 式 tarball 名 稱 通 常 有 版 本 資 訊 , 副 檔 名 為 .tar.gz 或 .tgz。<br />

• Tarball 套 件 安 裝 的 基 本 步 驟<br />

1. 下 載 Tarball;<br />

2. 將 Tarball 解 打 包 壓 縮 會 在 目 前 目 錄 下 產 生 套 件 目 錄 , 目 錄 下 通 常 會<br />

有 :<br />

(a) 原 始 程 式 碼 檔 案 ;<br />

(b) 偵 測 程 式 檔 案 ( 可 能 是 configure 或 config 等 檔 名 );<br />

(c) 本 套 件 的 簡 易 說 明 與 安 裝 說 明 ( INSTALL 或 README )。<br />

3. 根 據 INSTALL/README 的 內 容 安 裝 好 相 依 的 套 件 ;<br />

4. 以 configure 或 config 自 動 偵 測 作 業 環 境 , 並 建 立 Makefile 檔<br />

案 ;<br />

De-Yu Wang CSIE CYUT 280


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

5. 以 指 令 make 配 合 該 目 錄 下 的 Makefile, 進 行 make 動 作 ;<br />

6. 以 指 令 make 並 以 Makefile 中 的 install 目 標 項 目 , 安 裝 到 正 確 的<br />

路 徑 。<br />

• 使 用 原 始 碼 管 理 套 件 所 需 要 的 基 礎 套 件<br />

1. gcc 或 cc 等 C 語 言 編 譯 器 ( compiler ):<br />

2. make 及 autoconfig 等 套 件 。<br />

(a) 不 同 的 系 統 可 能 具 有 的 基 礎 套 件 環 境 並 不 相 同 , 必 須 偵 測 使 用 者 的<br />

作 業 環 境 , 以 建 立 makefile 檔 案 。<br />

(b) 自 行 偵 測 程 式 必 須 藉 由 autoconfig 相 關 的 套 件 輔 助 。<br />

3. 需 要 kernel 提 供 的 library 以 及 相 關 的 include 檔 案 :<br />

• Tarball 的 安 裝 可 跨 平 台<br />

1. 因 為 C 語 言 的 程 式 碼 在 各 個 平 台 上 面 是 可 以 共 通 的 ;<br />

2. 需 要 的 編 譯 器 可 能 並 不 相 同 。 例 如 <strong>Linux</strong> 上 編 譯 器 用 gcc 而 Windows<br />

上 則 用 相 關 的 C 編 譯 器 。<br />

• 多 用 途 指 令 tar<br />

1. tar 指 令<br />

✞<br />

圱 [root@linux ~]# tar [-cxtzjvfpPN] 檔 案 與 目 錄 .... 選 項 :<br />

圳 -c : 建 立 一 個 打 包 檔 案 (create);<br />

-x : 解 開 一 個 打 包 檔 案 ;<br />

圵 -t : 查 看 tarfile 內 的 檔 案 ;(c/x/t 不 可 同 時 存 在 !)<br />

-z : 同 時 用 gzip 壓 縮 ;<br />

圷 -j : 同 時 用 bzip2 壓 縮 ;<br />

-v : 壓 縮 的 過 程 中 顯 示 檔 案 ;<br />

圹 -f : 使 用 檔 名 , 在 f 之 後 要 立 即 接 檔 名 !<br />

-p : 保 留 檔 案 的 原 來 屬 性 ( 屬 性 不 會 依 據 使 用 者 而 變 )<br />

圱 圱 -P : 保 留 絕 對 路 徑 ;<br />

-N : 比 後 面 接 的 日 期 (yyyy/mm/dd) 還 要 新 的 才 會 被 打 包 ;<br />

圱 圳 --exclude : 排 除 FILE FILE 。<br />

✡✝<br />

✆<br />

2. 將 檔 案 txt 打 包 為 txt.tar<br />

✞<br />

圱 [root@dywOffice tmp]# tar -cvf txt.tar txt<br />

✡✝<br />

✆<br />

3. 將 整 個 /etc 目 錄 下 的 檔 案 全 部 打 包 成 為 /tmp/etc.tar<br />

De-Yu Wang CSIE CYUT 281


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

✞<br />

圱 [root@dywOffice tmp]# tar -cvf /tmp/etc.tar /etc


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

✞<br />

圱 [root@dywOffice tmp]# tar -zcvf home.tar.gz /home --exclude<br />

✡✝<br />

/home/csie/tmp<br />

✆<br />

• Tarballs 檔 案 處 理 步 驟 :<br />

1. 打 包 檔 案<br />

✞<br />

圱 $ tar -cvf myapp-1.0.tar main.c 2.c 3.c *.h myapp.1 Makefile5<br />

main.c<br />

圳 2.c<br />

3.c<br />

圵 a.h<br />

b.h<br />

圷 c.h<br />

myapp.1<br />

圹 Makefile5<br />

$<br />

✡✝<br />

✆<br />

2. 顯 示 tar 檔 案<br />

✞<br />

$ ls -l *.tar<br />

圲 -rw-r--r-- 1 neil users 10240 2003-02-15 11:31 myapp-1.0.<br />

tar<br />

$<br />

✡✝<br />

✆<br />

3. 再 利 用 gzip 壓 縮 檔 案 , 檔 案 大 幅 減 小 。<br />

✞<br />

圱 $ gzip myapp-1.0.tar<br />

$ ls -l *.gz<br />

圳 -rw-r--r-- 1 neil users 1668 2003-02-15 11:31 myapp-1.0.<br />

tar.gz<br />

$<br />

✡✝<br />

✆<br />

4. Windows 對 於 正 確 的 副 檔 名 非 常 在 意 , 而 <strong>Linux</strong>/UNIX 則 不 同 。 若 要 在<br />

windows 執 行 可 更 改 附 檔 名 :<br />

✞<br />

$ mv myapp-1.0.tar.gz myapp_v1.tgz<br />

圲 $ mv myapp_v1.tgz myapp-1.0.tar.gz<br />

✡✝<br />

✆<br />

5. 取 回 檔 案 , 要 先 解 壓 縮 , 隨 後 在 解 開 tar 檔 案 。<br />

De-Yu Wang CSIE CYUT 283


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

✞<br />

$ gzip -d myapp-1.0.tar.gz<br />

圲 $ tar -xvf myapp-1.0.tar<br />

main.c<br />

圴 2.c<br />

3.c<br />

圶 a.h<br />

b.h<br />

圸 c.h<br />

myapp.1<br />

圱 地 Makefile5<br />

$<br />

✡✝<br />

✆<br />

• GNU 版 的 tar 可 以 更 簡 化 , 可 以 一 個 步 驟 產 生 壓 縮 檔 。<br />

1. 打 包 並 壓 縮 檔 案<br />

✞<br />

圱 $ tar -zcvf myapp_v1.tgz main.c 2.c 3.c *.h myapp.1 Makefile5<br />

main.c<br />

圳 2.c<br />

3.c<br />

圵 a.h<br />

b.h<br />

圷 c.h<br />

myapp.1<br />

圹 Makefile5<br />

$<br />

✡✝<br />

✆<br />

2. 也 可 以 直 接 解 壓 縮 :<br />

✞<br />

$ tar -zxvf myapp_v1.tgz<br />

圲 main.c<br />

2.c<br />

圴 3.c<br />

a.h<br />

圶 b.h<br />

c.h<br />

圸 myapp.1<br />

Makefile5<br />

圱 地 $<br />

✡✝<br />

✆<br />

• 也 可 利 用 修 改 makefile, 增 加 一 個 新 的 目 標 項 目 dist, 建 立 tarball 收<br />

集 檔 案 。<br />

1. 修 改 makefile。<br />

De-Yu Wang CSIE CYUT 284


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

✞<br />

all: myapp<br />

圲 # Which compiler<br />

CC = gcc<br />

圴 # Where are include files kept<br />

INCLUDE = .<br />

圶 # Options for development<br />

CFLAGS = -g -Wall -ansi<br />

圸 # Options for release<br />

# CFLAGS = -O -Wall -ansi<br />

圱 地 # Local Libraries<br />

MYLIB = mylib.a<br />

圱 圲 myapp: main.o $(MYLIB)<br />

$(CC) -o myapp main.o $(MYLIB)<br />

圱 圴 $(MYLIB): $(MYLIB)(2.o) $(MYLIB)(3.o)<br />

main.o: main.c a.h<br />

圱 圶 2.o: 2.c a.h b.h<br />

3.o: 3.c b.h c.h<br />

圱 圸 clean:<br />

-rm main.o 2.o 3.o $(MYLIB)<br />

圲 地 dist: myapp-1.0.tar.gz<br />

myapp-1.0.tar.gz: myapp myapp.1<br />

圲 圲 -rm -rf myapp-1.0<br />

mkdir myapp-1.0<br />

圲 圴 cp *.c *.h *.1 Makefile myapp-1.0<br />

tar -zcvf $@ myapp-1.0<br />

✡✝<br />

✆<br />

2. 執 行 以 下 命 令 , 產 生 tarball 檔 案 :<br />

✞<br />

圱 $ make dist<br />

✡✝<br />

✆<br />

3. 查 看 myapp-1.0.0.tar.gz。<br />

✞<br />

圱 $ ls myapp-1.0.tar.gz<br />

myapp-1.0.tar.gz<br />

✡✝<br />

✆<br />

• 一 般 tarball 軟 體 安 裝 之 指 令 下 達 方 式 :<br />

✞<br />

$ tar -zxvf tarballfile.tar.gz<br />

圲 $ ./configure<br />

$ make clean<br />

圴 $ make<br />

$ make install<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 285


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

• Tarball 套 件 安 裝 建 議 事 項 :<br />

1. Tarball 在 /usr/local/src 解 壓 縮 ;<br />

2. <strong>Linux</strong> distribution 釋 出 安 裝 的 套 件 大 多 在 /usr , 而 使 用 者 自 行 安<br />

裝 的 套 件 則 建 議 放 置 在 /usr/local;<br />

3. man 預 設 會 去 搜 尋 /usr/local/man 裡 的 說 明 文 件 ;<br />

4. 自 行 安 裝 套 件 在 /usr/local 較 易 管 理 , 例 如 : 解 除 安 裝 。<br />

• <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑<br />

1. 以 自 由 軟 體 多 媒 體 播 放 軟 體 kplayer 為 例 , 安 裝 路 徑 如 下 :<br />

✞<br />

圱 /usr/bin


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

2. 實 際 安 裝 時 得 視 該 軟 體 的 Makefile 裡 的 install 資 訊 才 能 知 道 安 裝<br />

情 況 。<br />

• 套 件 相 依 性 :<br />

練 習 題<br />

1. 套 件 相 依 性 :<strong>Linux</strong> 軟 體 套 件 , 經 常 無 法 單 獨 安 裝 , 往 往 需 要 其 他 相 關<br />

套 件 存 在 , 才 能 正 常 工 作 。<br />

2. 套 件 相 依 有 順 序 : 例 如 :kplayer 必 須 先 安 裝 套 件 mplayer, 而<br />

mplayer 必 須 先 安 裝 套 件 kdelibs-common。<br />

3. 依 套 件 相 依 性 , 移 除 順 序 為 kdelibs-common, mplayer, kplayer。<br />

4. kplyaer 相 依 套 件 不 只 kdelibs-common 與 mplayer 兩 套 件 , 須 視 實<br />

際 安 裝 訊 息 而 定 。<br />

1. 何 謂 Tarball 套 件 <br />

Sol. 壓 縮 過 的 TAR(tape archive) 檔 案 。<br />

2. 程 式 tarball 名 稱 通 常 有 版 本 資 訊 , 副 檔 名 為 何 <br />

Sol. .tar.gz 或 .tgz。<br />

3. Tarball 套 件 解 壓 縮 後 , 通 常 會 有 那 些 檔 案 <br />

Sol. 1. 原 始 程 式 碼 檔 案 ;2. 偵 測 程 式 檔 案 configure 或 config;3. 套 件<br />

簡 易 說 明 README 與 ( 或 ) 安 裝 說 明 INSTALL。<br />

4. Tarball 套 件 解 壓 縮 後 , 通 常 會 有 那 個 偵 測 程 式 偵 測 作 業 環 境 , 建 立<br />

Makefile 檔 案 <br />

Sol. configure 或 config。<br />

5. Tarball 套 件 解 壓 縮 後 , 通 常 要 先 查 閱 那 兩 個 檔 案 , 以 瞭 解 套 件 如 何 安 裝 <br />

Sol. 套 件 簡 易 說 明 README 與 安 裝 說 明 INSTALL。<br />

6. <strong>Linux</strong> 上 編 譯 C 語 言 的 程 式 碼 的 主 要 工 具 為 何 <br />

Sol. gcc<br />

7. <strong>Linux</strong> 上 編 譯 C++ 語 言 的 程 式 碼 的 主 要 工 具 為 何 <br />

Sol. g++<br />

8. Tarball 套 件 在 <strong>Linux</strong> 上 安 裝 時 , 基 本 上 需 要 那 些 基 礎 套 件 <br />

Sol. tar, gcc, make 及 autoconfig 等 套 件 。<br />

9. 程 式 make 時 , 需 要 那 個 檔 案 提 供 , 要 產 生 之 目 標 檔 案 及 其 法 則 <br />

Sol. makefile 或 Makefile。<br />

10. 偵 測 使 用 者 的 作 業 環 境 , 以 建 立 makefile 檔 案 之 套 件 為 何 <br />

Sol. autoconfig<br />

11. Tarball 套 件 可 以 在 Windows 上 安 裝 嗎 <br />

Sol. 可 以 , 使 用 Windows 下 相 關 的 C 編 譯 器 。<br />

De-Yu Wang CSIE CYUT 287


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

12. 如 何 以 指 令 tar 將 檔 案 txt 打 包 為 txt.tar<br />

Sol. tar -cvf txt.tar txt<br />

13. 如 何 以 指 令 tar 將 整 個 /etc 目 錄 下 的 檔 案 全 部 打 包 成 為 /tmp/etc.tar<br />

Sol. tar -cvf /tmp/etc.tar /etc<br />

14. 如 何 以 指 令 tar 將 整 個 /etc 目 錄 下 的 檔 案 全 部 打 包 , 且 以 gzip 壓 縮 成<br />

為 /tmp/etc.tar.gz<br />

Sol. tar -zcvf /tmp/etc.tar.gz /etc<br />

15. 如 何 以 指 令 tar 將 整 個 /home 目 錄 下 的 檔 案 全 部 打 包 , 且 以 gzip 壓 縮 成<br />

為 /tmp/home.tar.gz<br />

Sol. tar -zcvf /tmp/home.tar.gz /home<br />

16. 如 何 以 指 令 tar 查 閱 tar 打 包 壓 縮 檔 /tmp/etc.tar.gz 內 有 那 些 檔 案 <br />

Sol. tar -ztvf /tmp/etc.tar.gz<br />

17. 如 何 以 指 令 tar 將 /etc/ 內 的 所 有 檔 案 備 份 為 /tmp/etc.tar.gz 下 , 並<br />

且 保 存 其 權 限 <br />

Sol. tar -zcvpf /tmp/etc.tar.gz /etc<br />

18. 如 何 以 指 令 tar 將 /tmp/home.tar.gz 檔 案 解 壓 縮 在 根 目 錄 /<br />

Sol. tar -zxvf /home/etc.tar.gz /<br />

19. 如 何 以 指 令 tar 將 /tmp/etc.tar.gz 檔 案 解 壓 縮 在 目 前 目 錄 <br />

Sol. tar -zxvf /tmp/etc.tar.gz<br />

20. 如 何 以 指 令 tar 將 備 份 /home 成 myhome.tar.gz, 但 不 要 /home/test<br />

Sol. tar --exclude /home/test -zcvf myhome.tar.gz /home/*<br />

21. 如 何 以 指 令 tar 打 包 檔 案 main.c 2.c 3.c *.h 成 myapp-1.0.tar<br />

Sol. tar -cvf myapp-1.0.tar main.c 2.c 3.c *.h<br />

22. 如 何 將 打 包 檔 案 myapp-1.0.tar, 再 利 用 gzip 壓 縮 檔 案 <br />

Sol. gzip myapp-1.0.tar<br />

23. 打 包 檔 案 myapp-1.0.tar, 再 利 用 gzip 壓 縮 後 之 檔 名 為 何 <br />

Sol. myapp-1.0.tar.gz<br />

24. 如 何 將 打 包 且 壓 縮 檔 案 myapp-1.0.tar.gz, 利 用 gzip 解 壓 縮 <br />

Sol. gzip -d myapp-1.0.tar.gz<br />

25. 如 何 將 打 包 檔 案 myapp-1.0.tar, 利 用 tar 解 打 包 <br />

Sol. tar -xvf myapp-1.0.tar<br />

26. 如 何 以 指 令 tar 打 包 並 壓 縮 檔 案 main.c 2.c 3.c *.h 成<br />

myapp-1.0.tar.gz<br />

Sol. tar -zcvf myapp-1.0.tar main.c 2.c 3.c *.h<br />

De-Yu Wang CSIE CYUT 288


15.2. TARBALLS 簡 介 CHAPTER 15. *TARBALL 套 件 發 行<br />

27. 如 何 以 指 令 tar 將 myapp-1.0.tar.gz 打 包 壓 縮 <br />

Sol. tar -zxvf myapp-1.0.tar.gz<br />

28. makefile 新 增 一 個 的 目 標 項 目 dist, 建 立 tarball, 其 中 一 行 dist:<br />

myapp-1.0.tar.gz 代 表 意 義 為 何 <br />

Sol. 目 標 項 目 為 dist, 其 相 依 項 目 為 myapp-1.0.tar.gz<br />

29. makefile 新 增 一 個 的 目 標 項 目 dist, 建 立 tarball, 其 中 一 行<br />

myapp-1.0.tar.gz: myapp myapp.1 代 表 意 義 為 何 <br />

Sol. 目 標 項 目 為 myapp-1.0.tar.gz, 其 相 依 項 目 為 myapp 與 myapp.1<br />

30. makefile 新 增 一 個 的 目 標 項 目 dist, 建 立 tarball, 其 中 一 行<br />

tar -zcvf $@ myapp-1.0 代 表 意 義 為 何 <br />

Sol. 將 myapp-1.0 打 包 壓 縮 , 檔 名 為 目 前 之 目 標 項 目 。<br />

31. 一 般 tarball 軟 體 安 裝 時 , 請 說 明 執 行 ./configure 之 目 的 為 何 <br />

Sol. ./ 表 示 在 目 前 目 錄 下 執 行 configure, 自 動 偵 測 作 業 環 境 , 並 產 生<br />

makefile。<br />

32. 一 般 tarball 軟 體 安 裝 時 , 請 說 明 執 行 make clean 之 目 的 為 何 <br />

Sol. 執 行 目 標 項 目 clean, 清 除 目 標 檔 。<br />

33. 一 般 tarball 軟 體 安 裝 時 , 請 說 明 執 行 make 之 目 的 為 何 <br />

Sol. 編 譯 程 式 , 產 生 二 進 位 之 執 行 檔 。<br />

34. 一 般 tarball 軟 體 安 裝 時 , 請 說 明 執 行 make install 之 目 的 為 何 <br />

Sol. 執 行 目 標 項 目 install, 將 編 譯 好 之 可 執 行 檔 及 相 關 檔 案 , 複 製 到 指<br />

定 的 目 錄 。<br />

35. 一 般 <strong>Linux</strong> distribution 釋 出 安 裝 的 套 件 大 多 在 那 個 目 錄 <br />

Sol. /usr<br />

36. 一 般 <strong>Linux</strong> 建 議 使 用 者 自 行 安 裝 的 套 件 放 置 在 那 個 目 錄 <br />

Sol. /usr/local<br />

37. <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑 /usr/bin 放 置 什 麼 檔 案 <br />

Sol. 執 行 檔<br />

38. <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑 /usr/lib 放 置 什 麼 檔 案 <br />

Sol. 函 式 庫<br />

39. <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑 /usr/share/applnk 放 置 什 麼 檔<br />

案 <br />

Sol. 程 式 選 單 連 結 檔<br />

40. <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑 /usr/share/apps/ 放 置 什 麼 檔<br />

案 <br />

Sol. 程 式 內 容<br />

De-Yu Wang CSIE CYUT 289


15.3. KPLAYER TARBALL 實 例 CHAPTER 15. *TARBALL 套 件 發 行<br />

41. <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑 /usr/share/doc/ 放 置 什 麼 檔<br />

案 <br />

Sol. 程 式 文 件<br />

42. <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑 /usr/share/icons/ 放 置 什 麼 檔<br />

案 <br />

Sol. 程 式 圖 標<br />

43. <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑 /usr/share/locale/ 放 置 什 麼<br />

檔 案 <br />

Sol. 程 式 支 援 之 語 系<br />

44. <strong>Linux</strong> distribution 預 設 安 裝 套 件 的 路 徑 /usr/share/services/ 放 置 什<br />

麼 檔 案 <br />

Sol. 程 式 支 援 之 服 務<br />

15.3 KPlayer Tarball 實 例<br />

• 安 裝 前 置 作 業<br />

1. 自 由 軟 體 多 媒 體 播 放 軟 體 Kplayer 官 方 網 站 下 載 原 始 碼<br />

2. 在 目 前 目 錄 ( 一 般 為 /usr/src ), 解 開 原 始 碼 :<br />

✞<br />

[root@dywHome2 src]# tar -jxvf kplayer-0.5.3.tar.bz2<br />

圲 kplayer-0.5.3/<br />

kplayer-0.5.3/README<br />

圴 kplayer-0.5.3/AUTHORS<br />

kplayer-0.5.3/COPYING<br />

圶 kplayer-0.5.3/ChangeLog<br />

kplayer-0.5.3/INSTALL<br />

圸 kplayer-0.5.3/Makefile.am<br />

kplayer-0.5.3/Makefile.in 以 下 省 略<br />

圱 地 --------<br />

✡✝<br />

✆<br />

3. 顯 示 解 開 原 始 碼 之 目 錄 :<br />

✞<br />

[root@dywHome2 src]# ls -ld kplayer*<br />

圲 drwxrwxrwx 8 1002 1002 1024 Jan 9 2005 kplayer-0.5.3/<br />

-rw-r--r-- 1 root root 3156593 Apr 3 08:50 kplayer-0.5.3.tar<br />

.bz2<br />

✡✝<br />

✆<br />

4. 閱 讀 README 與 INSTALL:<br />

De-Yu Wang CSIE CYUT 290


15.3. KPLAYER TARBALL 實 例 CHAPTER 15. *TARBALL 套 件 發 行<br />

圱<br />

圳<br />

✞<br />

[root@dywHome2 kplayer-0.5.3]# cat INSTALL<br />

# 截 取 INSTALL 中 之 重 要 安 裝 訊 息<br />

Extract the tarball<br />

圵<br />

圷<br />

圹<br />

圱 圱<br />

圱 圳<br />

圱 圵<br />

圱 圷<br />

圱 圹<br />

圲 圱<br />

圲 圳<br />

圲 圵<br />

✡✝<br />

tar -xjf kplayer-0.5.3.tar.bz2<br />

cd kplayer-0.5.3<br />

Create configure script<br />

make -f Makefile.dist<br />

Configure<br />

./configure --prefix=‘kde-config --prefix‘<br />

Compile<br />

make<br />

Install<br />

Run<br />

su -c ’make install’<br />

kplayer<br />

✆<br />

• 依 照 上 述 INSTALL 之 重 要 安 裝 訊 息 , 逐 步 安 裝 :<br />

1. Extract the tarball, 已 完 成 。<br />

2. Create configure script<br />

✞<br />

[root@dywHome2 kplayer-0.5.3]# make -f Makefile.dist<br />

圲 This Makefile is only for the CVS repository<br />

This will be deleted before making the distribution<br />

圴<br />

*** Creating acinclude.m4<br />

圶 *** Creating list of subdirectories<br />

*** Creating configure.files<br />

圸 *** Creating configure.in<br />

*** Creating aclocal.m4<br />

圱 地 *** Creating configure<br />

*** Creating config.h template<br />

圱 圲 *** Creating Makefile templates<br />

*** Postprocessing Makefile templates<br />

圱 圴 *** Creating date/time stamp<br />

*** Finished<br />

圱 圶 Don’t forget to run ./configure<br />

De-Yu Wang CSIE CYUT 291


15.3. KPLAYER TARBALL 實 例 CHAPTER 15. *TARBALL 套 件 發 行<br />

✡✝<br />

If you haven’t done so in a while, run ./configure --help<br />

✆<br />

3. Configure<br />

(a) 假 設 相 依 套 件 已 安 裝 ;<br />

(b) ./configure: 表 示 執 行 目 前 目 錄 下 之 自 動 偵 測 作 業 環 境 執 行 檔<br />

configure;<br />

(c) --prefix=PATH: 指 定 安 裝 目 錄 為 PATH。<br />

例 如 :--prefix=/usr/local/kplayer;<br />

(d) ‘kde-config --prefix‘: 會 先 執 行 , 以 找 到 套 件 安 裝 目 錄 , 在 本<br />

系 統 為 /usr;<br />

(e) 若 系 統 環 境 檢 查 一 切 正 常 , 則 出 現 訊 息 Good - your configure<br />

finished. Start make now。<br />

✞<br />

圱 [root@dywHome2 kplayer-0.5.3]# ./configure --prefix=‘kdeconfig<br />

--prefix‘<br />

[root@dywHome2 kplayer-0.5.3]# ./configure --prefix=/usr/<br />

local/kplayer<br />

圳 checking build system type... i686-pc-linux-gnu<br />

checking host system type... i686-pc-linux-gnu 中 間 省 略<br />

圵 --------<br />

configure: creating ./config.status<br />

圷 fast creating Makefile<br />

fast creating admin/Makefile<br />

圹 fast creating doc/Makefile<br />

fast creating doc/da/Makefile<br />

圱 圱 fast creating doc/en/Makefile<br />

fast creating doc/pt/Makefile<br />

圱 圳 fast creating doc/sv/Makefile<br />

fast creating icons/Makefile<br />

圱 圵 fast creating kplayer/Makefile<br />

fast creating po/Makefile<br />

圱 圷 config.pl: fast created 10 file(s).<br />

config.status: creating config.h<br />

圱 圹 config.status: config.h is unchanged<br />

config.status: executing depfiles commands<br />

圲 圱<br />

Good - your configure finished. Start make now<br />

✡✝<br />

✆<br />

4. Compile<br />

✞<br />

[root@dywHome2 kplayer-0.5.3]# make 以 上 省 略<br />

圲 --------<br />

make[2]: Entering directory ‘/usr/src/kplayer-0.5.3’<br />

圴 make[2]: Leaving directory ‘/usr/src/kplayer-0.5.3’<br />

make[1]: Leaving directory ‘/usr/src/kplayer-0.5.3’<br />

De-Yu Wang CSIE CYUT 292


15.3. KPLAYER TARBALL 實 例 CHAPTER 15. *TARBALL 套 件 發 行<br />

✡✝<br />

✆<br />

5. Install<br />

✞<br />

圱 [root@dywHome2 kplayer-0.5.3]# make install 以 上 省 略<br />

--------<br />

圳 make[2]: Leaving directory ‘/usr/src/kplayer-0.5.3’<br />

make[1]: Leaving directory ‘/usr/src/kplayer-0.5.3’<br />

✡✝<br />

✆<br />

6. 查 看 安 裝 目 錄 /usr/local/kplayer/<br />

✞<br />

[root@dywHome2 src]# ll /usr/local/kplayer/<br />

圲 total 3<br />

drwxr-xr-x 2 root root 1024 Apr 3 10:09 bin/<br />

圴 drwxr-xr-x 3 root root 1024 Apr 3 10:09 lib/<br />

drwxr-xr-x 8 root root 1024 Apr<br />

✡✝<br />

3 10:09 share/<br />

✆<br />

• 進 入 目 錄 kplayer-0.5.3 修 改 原 始 碼 :<br />

✞<br />

圱 [root@dywHome2 src]# cd kplayer-0.5.3<br />

✡✝<br />

✆<br />

• 將 kplayer-0.5.3 整 個 目 錄 , 打 包 壓 縮 成 tarball。<br />

1. 直 接 以 tar 指 令 打 包 壓 縮<br />

✞<br />

圱 [root@dywHome2 kplayer-0.5.3]# cd..<br />

[root@dywHome2 src]# tar -zcvf kplayer-0.5.3.systray.tar.gz<br />

./kplayer-0.5.3<br />

圳 ./kplayer-0.5.3/<br />

./kplayer-0.5.3/README<br />

圵 ./kplayer-0.5.3/AUTHORS<br />

./kplayer-0.5.3/COPYING<br />

圷 ./kplayer-0.5.3/ChangeLog<br />

./kplayer-0.5.3/INSTALL 中 間 省 略<br />

圹 --------<br />

./kplayer-0.5.3/Makefile<br />

圱 圱 ./kplayer-0.5.3/libtool<br />

./kplayer-0.5.3/config.status<br />

圱 圳 ./kplayer-0.5.3/config.h<br />

✡✝<br />

✆<br />

2. 利 用 Makefile 產 生 tarball<br />

De-Yu Wang CSIE CYUT 293


15.3. KPLAYER TARBALL 實 例 CHAPTER 15. *TARBALL 套 件 發 行<br />

(a) 修 改 Makefile 中 版 本 序 號 VERSION:0.5.3 後 面 加 入 .systray<br />

✞<br />

圱 [root@dywHome2 kplayer-0.5.3.systray]# vi Makefile<br />

VERSION = 0.5.3.systray<br />

圳 ## 所 有 目 錄 kplayer-0.5.3 皆 改 成 kplayer-0.5.3.systray<br />

## 在 vi 環 境 下 指<br />

令 :1,$s/kplayer-0.5.3/kplayer-0.5.3.systray/g<br />

圵 install_sh = /usr/src/rpm/SOURCES/kplayer-0.5.3.systray/<br />

admin/install-sh<br />

✡✝<br />

✆<br />

(b) 執 行 make dist-gzip, 產 生 tarball<br />

kplayer-0.5.3.systray.tar.gz<br />

✞<br />

圱 [root@dywHome2 kplayer-0.5.3.systray]# make dist-gzip<br />

{ test ! -d kplayer-0.5.3.systray || { find kplayer<br />

-0.5.3.systray<br />

圳 -type d ! -perm -200 -exec chmod u+w {} ’;’<br />

&& rm -fr kplayer-0.5.3.systray; }; }<br />

圵 mkdir kplayer-0.5.3.systray 以 下 省 略<br />

--------<br />

✡✝<br />

✆<br />

• 直 接 以 tarball 將 軟 體 釋 出<br />

1. 將 tarball kplayer-0.5.3.systray.tar.gz 移 到 上 一 層 目 錄<br />

/usr/src/rpm/SOURCES。<br />

✞<br />

[root@dywHome2 kplayer-0.5.3.systray]# mv kplayer-0.5.3.<br />

systray.tar.gz ../<br />

✡✝<br />

✆<br />

2. 查 看 tarball kplayer-0.5.3.systray.tar.gz。<br />

✞<br />

圱 [root@dywHome2 kplayer-0.5.3.systray]# cd..<br />

[root@dywHome2 SOURCES]# ll<br />

圳 total 6818<br />

drwxr-xr-x 9 root root 1024 Apr 5 15:17 kplayer-0.5.3.<br />

systray/<br />

圵 -rw-r--r-- 1 root root 3793524 Apr 5 15:15 kplayer-0.5.3.<br />

systray.tar.gz<br />

-rw-r--r-- 1 root users 3156593 Jul 3 2006 kplayer-0.5.3.<br />

✡✝<br />

tar.bz2<br />

✆<br />

3. 釋 出 kplayer-0.5.3.systray.tar.gz<br />

De-Yu Wang CSIE CYUT 294


15.3. KPLAYER TARBALL 實 例 CHAPTER 15. *TARBALL 套 件 發 行<br />

練 習 題<br />

1. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 則 其 執 行 檔 放 置 在 那 個 目<br />

錄 <br />

Sol. /usr/local/kplayer/bin<br />

2. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 則 其 函 式 庫 放 置 在 那 個 目<br />

錄 <br />

Sol. /usr/local/kplayer/lib<br />

3. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 則 其 程 式 選 單 連 結 檔 放 置<br />

在 那 個 目 錄 <br />

Sol. /usr/local/kplayer/share/applnk<br />

4. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 則 其 程 式 內 容 放 置 在 那 個<br />

目 錄 <br />

Sol. /usr/local/kplayer/share/apps<br />

5. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 則 其 程 式 文 件 放 置 在 那 個<br />

目 錄 <br />

Sol. /usr/local/kplayer/share/doc<br />

6. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 則 其 程 式 圖 標 放 置 在 那 個<br />

目 錄 <br />

Sol. /usr/local/kplayer/share/icons<br />

7. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 則 其 程 式 支 援 語 系 之 檔 案<br />

放 置 在 那 個 目 錄 <br />

Sol. /usr/local/kplayer/share/locale<br />

8. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 則 其 程 式 支 援 服 務 之 檔 案<br />

放 置 在 那 個 目 錄 <br />

Sol. /usr/local/kplayer/share/services<br />

9. 若 將 套 件 kplayer 安 裝 在 /usr/local/kplayer, 如 何 以 一 個 指 令 將 其 完 全<br />

移 除 <br />

Sol. rm -rf /usr/local/kplayer<br />

10. 請 說 明 <strong>Linux</strong> 套 件 相 依 性 。<br />

Sol. <strong>Linux</strong> 軟 體 套 件 , 經 常 無 法 單 獨 安 裝 , 往 往 需 要 其 他 相 關 套 件 存 在 ,<br />

才 能 正 常 工 作 。<br />

11. 套 件 kplayer 安 裝 前 , 需 要 先 安 裝 套 件 mplayer, 則 移 除 套 件 mplayer<br />

後 ,kplayer 能 否 執 行 <br />

Sol. 無 法 執 行 。<br />

12. 套 件 kplayer 安 裝 前 , 必 須 先 裝 套 件 mplayer, 而 mplayer 必 須 先 安 裝 套<br />

件 kdelibs-common, 解 除 安 裝 之 順 序 為 何 <br />

Sol. 移 除 順 序 為 kdelibs-common, mplayer, kplayer。<br />

De-Yu Wang CSIE CYUT 295


15.3. KPLAYER TARBALL 實 例 CHAPTER 15. *TARBALL 套 件 發 行<br />

13. Tarball 套 件 kplayer-0.5.3.tar.bz2 下 載 後 要 如 何 解 打 包 壓 縮 <br />

Sol. tar -jxvf kplayer-0.5.3.tar.bz2<br />

14. Tarball 套 件 kplayer 解 打 包 壓 縮 後 , 請 說 明 INSTALL 中 重 要 訊 息<br />

Create configure script<br />

make -f Makefile.dist。<br />

Sol. 產 生 作 業 環 境 偵 測 腳 本 , 需 執 行 make -f Makefile.dist。<br />

15. Tarball 套 件 kplayer 解 打 包 壓 縮 後 , 請 說 明 INSTALL 中 重 要 訊 息<br />

./configure --prefix=‘kde-config --prefix‘。<br />

Sol. 先 執 行 kde-config --prefix 產 生 kde 配 置 目 錄 , 一 般 為 /usr;<br />

在 目 前 目 錄 下 以 選 項 --prefix=/usr 執 行 作 業 環 境 偵 測 configure。<br />

16. 安 裝 tarball 套 件 kplayer, 執 行 make -f Makefile.dist 最 後 出 現<br />

Don’t forget to run ./configure, 代 表 意 義 為 何 <br />

Sol. 表 示 作 業 環 境 偵 測 腳 本 產 生 成 功 , 不 要 忘 了 執 行 ./configure。<br />

17. 安 裝 tarball 套 件 kplayer, 執 行 ./configure, 代 表 意 義 為 何 <br />

Sol. 表 示 執 行 目 前 目 錄 下 之 自 動 偵 測 作 業 環 境 執 行 檔 configure。<br />

18. 安 裝 tarball 套 件 kplayer, 執 行 ./configure --prefix=PATH, 其 中 選<br />

項 --prefix=PATH 代 表 意 義 為 何 <br />

Sol. 指 定 安 裝 目 錄 為 PATH。<br />

19. 安 裝 tarball 套 件 kplayer, 執 行 ./configure --prefix=‘kde-config<br />

--prefix‘, 其 中 選 項 ‘kde-config --prefix‘ 代 表 意 義 為 何 <br />

Sol. ‘‘ 括 號 , 表 示 先 執 行 kde-config --prefix, 產 生 kde 配 置 目 錄 。<br />

20. 安 裝 tarball 套 件 kplayer, 執 行 ./configure --prefix=‘kde-config<br />

--prefix‘, 最 後 出 現 Good - your configure finished. Start make<br />

now 代 表 意 義 為 何 <br />

Sol. 表 示 自 動 偵 測 作 業 環 境 產 生 makefile 成 功 , 可 以 繼 續 執 行 make。<br />

De-Yu Wang CSIE CYUT 296


CHAPTER 16.<br />

*RPM 與 SRPM 套 件 發 行<br />

Chapter 16<br />

*RPM 與 SRPM 套 件 發 行<br />

16.1 RPM 與 SRPM 套 件<br />

• 何 謂 RPM<br />

1. RPM 全 名 是 『 RedHat Package Manager 』 簡 稱 為 RPM。<br />

2. 由 Red Hat 公 司 發 展 出 來 , 由 於 RPM 使 用 方 便 , 所 以 成 了 目 前 最 熱 門<br />

的 套 件 管 理 程 式 。<br />

3. RPM 是 以 資 料 庫 記 錄 的 方 式 來 將 所 需 要 的 套 件 安 裝 到 <strong>Linux</strong> 主 機 的 一<br />

套 管 理 程 式 。<br />

4. RPM 將 要 安 裝 的 套 件 先 編 譯 過 , 並 且 打 包 好 , 安 裝 時 RPM 會 先 依 照 套<br />

件 裡 的 紀 錄 資 料 查 詢 相 依 屬 性 套 件 是 否 滿 足 , 若 滿 足 則 予 以 安 裝 , 若 不<br />

滿 足 則 不 予 安 裝 。<br />

• RPM 優 點 :<br />

1. 免 編 譯 : 已 編 譯 ;<br />

2. 避 免 安 裝 錯 誤 : 安 裝 前 先 檢 查 系 統 的 硬 碟 容 量 、 作 業 系 統 版 本 等 ;<br />

3. 瞭 解 套 件 : 提 供 套 件 版 本 資 訊 、 相 依 屬 性 套 件 名 稱 、 套 件 用 途 說 明 、 套<br />

件 所 含 檔 案 等 資 訊 ;<br />

4. 安 裝 、 移 除 、 更 新 升 級 及 驗 證 套 件 方 便 : 資 料 庫 記 錄 參 數 , 且 一 個 指 令<br />

即 可 完 成 。<br />

5. 容 易 傳 送 : 打 包 成 一 個 檔 案 。<br />

• RPM 缺 點 :<br />

1. 安 裝 的 環 境 必 須 與 打 包 時 的 環 境 需 求 一 致 或 相 當 ;<br />

2. 相 依 套 件 必 須 滿 足 ;<br />

3. 反 安 裝 時 , 下 層 套 件 不 可 先 移 除 , 否 則 可 能 造 成 整 個 系 統 的 問 題 。<br />

• RPM 套 件 的 屬 性 相 依<br />

De-Yu Wang CSIE CYUT 297


16.1. RPM 與 SRPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

1. RPM 打 包 套 件 檔 案 時 , 會 同 時 加 入 套 件 的 訊 息 。 例 如 :<br />

(a) 版 本 、<br />

(b) 打 包 套 件 者 、<br />

(c) 相 依 屬 性 的 套 件 、<br />

(d) 套 件 的 功 能 說 明 、<br />

(e) 套 件 的 所 有 檔 案 與 目 錄 紀 錄 。<br />

2. 在 <strong>Linux</strong> 系 統 上 亦 建 立 一 個 RPM 套 件 資 料 庫 。<br />

3. 當 要 安 裝 某 個 以 RPM 型 態 提 供 的 套 件 時 , 如 果 資 料 庫 顯 示 其 相 依 套 件<br />

不 存 在 , 則 會 顯 示 錯 誤 訊 息 。<br />

4. 屬 性 相 依 的 克 服 方 式<br />

(a) 手 動 下 載 並 安 裝 好 所 有 相 依 套 件 。<br />

(b) 利 用 urpmi 安 裝 rpm 套 件 : 自 行 尋 找 未 安 裝 的 相 依 套 件 加 以 安<br />

裝 。<br />

• 何 謂 SRPM<br />

1. SRPM 是 Source RPM, 也 就 是 RPM 檔 案 裡 含 有 原 始 碼 ( Source Code<br />

)。<br />

2. SRPM 除 含 tarball 原 始 碼 外 , 亦 包 含 rpm 規 格 檔 .spec, 提 供 重 建<br />

rpm 套 件 所 有 資 訊 。 例 如 : 所 須 相 依 性 套 件 。<br />

3. SRPM 可 經 由 修 改 規 格 檔 , 以 重 建 符 合 自 己 系 統 之 rpm 套 件 。<br />

• SRPM 安 裝 與 利 用 :<br />

1. 先 將 該 套 件 以 RPM 管 理 的 方 式 安 裝 ;<br />

2. 安 裝 完 成 後 , 會 有 原 始 碼 tarball 及 rpm 規 格 檔 .spec;<br />

3. 修 改 、 重 新 編 譯 原 始 碼 , 再 打 包 成 tarball;<br />

4. 修 改 rpm 規 格 檔 , 以 適 合 自 己 的 <strong>Linux</strong> 環 境 ;<br />

5. 重 建 RPM 套 件 ;<br />

6. 以 RPM 管 理 方 式 , 將 重 建 之 RPM 套 件 安 裝 至 系 統 ;<br />

• RPM 與 SRPM 的 格 式 :<br />

✞<br />

name-version-release.architecture.rpm


16.1. RPM 與 SRPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

2. 釋 出 版 本 次 數 :5mdv2007.0。<br />

(a) 不 同 的 distirbution 會 有 不 同 的 環 境 與 函 式 庫 , 釋 出 版 本 次 數 後<br />

可 能 會 再 加 上 distirbution 的 簡 寫 。<br />

(b) mdv2007.0 表 示 <strong>Linux</strong> distribution Mandriva 2007.0。<br />

(c) 安 裝 RPM 套 件 , 最 好 選 擇 相 同 環 境 之 檔 案 , 即 distirbution 的<br />

簡 寫 與 自 己 的 系 統 環 境 相 同 。<br />

3. 操 作 硬 體 平 台 之 選 擇 :<br />

(a) 平 台 名 稱 說 明 :<br />

平 台 名 稱 適 合 平 台 說 明<br />

i386 幾 乎 適 用 於 所 有 的 x86 平 台 。<br />

i 是 Intel 相 容 的 CPU,386 是 CPU 的 等 級 。<br />

i586 586 等 級 的 電 腦 , 包 括 pentum 第 一 代 MMX CPU,<br />

AMD 的 K5, K6 系 列 等 CPU。<br />

i686 pentum II 以 後 的 Intel 系 列 CPU,<br />

及 K7 以 後 等 級 的 CPU。<br />

noarch 沒 有 任 何 硬 體 等 級 上 的 限 制 。<br />

athlon AMD Athlon 晶 片 。<br />

(b) i386 可 安 裝 在 586 或 686 的 機 器 ;<br />

(c) i686 是 針 對 686 等 級 的 CPU 進 行 最 佳 化 編 譯 , 所 以 不 一 定 可 以<br />

使 用 於 386 或 586 的 硬 體 。<br />

(d) 在 686 的 機 器 上 使 用 i686 的 檔 案 會 比 使 用 i386 的 檔 案 , 效 能<br />

可 能 比 較 好 。<br />

(e) 目 前 <strong>Linux</strong> distribution Mandriva 2007.0 釋 出 之 rpm, 平 台 名<br />

稱 為 i586。<br />

• RPM 檔 案 系 統<br />

1. Mandriva 2007 以 /usr/src/rpm/ 為 工 作 目 錄<br />

2. /usr/src/rpm 以 下 五 個 目 錄 :<br />

rpm 子 目 錄 說 明<br />

BUILD 編 譯 過 程 中 , 暫 存 資 料 放 置 目 錄 。<br />

RPMS 編 譯 打 包 成 功 後 , 完 成 的 rpm 檔 案 放 置 目 錄 。<br />

SOURCES 放 置 套 件 的 原 始 碼 , 即 tarball 檔 。<br />

SPECS 放 置 套 件 的 規 格 檔 spec 檔 案 。<br />

SRPMS 編 譯 打 包 成 功 後 , 完 成 的 srpm 檔 案 放 置 目 錄 。<br />

3. /usr/src/rpm/RPMS 目 錄 通 常 有 一 些 架 構 的 子 目 錄 , 如 下 :<br />

✞<br />

$ ls RPMS<br />

圲 athlon<br />

i386<br />

圴 i486<br />

i586<br />

De-Yu Wang CSIE CYUT 299


16.1. RPM 與 SRPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

圶<br />

i686<br />

noarch<br />

✡✝<br />

✆<br />

練 習 題<br />

1. RPM 全 名 為 何 <br />

Sol. RedHat Package Manager<br />

2. 何 謂 RPM<br />

Sol. 以 資 料 庫 記 錄 的 方 式 來 將 所 需 要 的 套 件 安 裝 到 <strong>Linux</strong> 主 機 的 一 套 管<br />

理 程 式 。<br />

3. RPM 套 件 是 否 經 過 編 譯 <br />

Sol. 是 。<br />

4. RPM 套 件 安 裝 前 是 否 會 檢 查 相 依 屬 性 套 件 <br />

Sol. 會 。<br />

5. RPM 套 件 安 裝 時 將 套 件 的 資 訊 寫 入 資 料 庫 之 目 的 為 何 <br />

Sol. 便 於 查 詢 、 驗 證 、 升 級 更 新 及 反 安 裝 。<br />

6. 請 列 舉 RPM 套 件 之 優 點 。<br />

Sol. 1. 免 編 譯 ;2. 避 免 安 裝 錯 誤 :3. 可 瞭 解 套 件 ;4. 更 新 升 級 、 移 除 、 查<br />

詢 與 驗 證 方 便 ;5. 容 易 傳 送 。<br />

7. 請 列 舉 RPM 套 件 之 缺 點 。<br />

Sol. 1. 安 裝 的 環 境 要 一 致 ;2. 相 依 套 件 要 滿 足 ;3. 下 層 套 件 不 可 先 移 除 。<br />

8. RPM 打 包 套 件 檔 案 時 , 會 同 時 加 入 套 件 的 訊 息 。 請 列 舉 三 項 。<br />

Sol. 1. 版 本 、2. 打 包 套 件 者 、3. 相 依 屬 性 的 套 件 、4. 套 件 的 功 能 說<br />

明 、5. 套 件 的 所 有 檔 案 與 目 錄 紀 錄 。<br />

9. 如 何 克 服 RPM 安 裝 套 件 屬 性 相 依 的 問 題 <br />

Sol. 1. 手 動 下 載 並 安 裝 好 所 有 相 依 套 件 。2. 利 用 urpmi 安 裝 rpm 套 件 。<br />

10. 何 謂 SRPM<br />

Sol. SRPM 是 Source RPM, 也 就 是 RPM 檔 案 裡 含 有 原 始 碼 。<br />

11. 請 說 明 SRPM 與 tarball 之 差 異 <br />

Sol. SRPM 除 含 tarball 原 始 碼 外 , 亦 包 含 rpm 規 格 檔 .spec, 提 供 重<br />

建 rpm 套 件 所 有 資 訊 。 例 如 : 所 須 相 依 性 套 件 。<br />

12. 請 說 明 SRPM 之 優 點 <br />

Sol. SRPM 可 經 由 修 改 規 格 檔 , 以 重 建 符 合 自 己 系 統 之 rpm 套 件 。<br />

De-Yu Wang CSIE CYUT 300


16.1. RPM 與 SRPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

13. 下 載 SRPM 並 以 RPM 管 理 的 方 式 安 裝 後 , 會 有 那 些 檔 案 <br />

Sol. tarball 及 rpm 規 格 檔 .spec。<br />

14. 修 改 rpm 規 格 檔 .spec 的 主 要 目 的 為 何 <br />

Sol. 以 重 建 符 合 自 己 系 統 之 rpm 套 件 。<br />

15. 請 寫 出 RPM 檔 名 格 式 。<br />

Sol. name-version-release.architecture.rpm<br />

16. 請 寫 出 SRPM 檔 名 格 式 。<br />

Sol. name-version-release.src.rpm<br />

17. 檔 案 kplayer-0.5.3-5mdv2007.0.i586.rpm 之 套 件 名 稱 為 何 <br />

Sol. kplayer<br />

18. 檔 案 kplayer-0.5.3-5mdv2007.0.i586.rpm 之 套 件 版 本 資 訊 為 何 <br />

Sol. 0.5.3<br />

19. 檔 案 kplayer-0.5.3-5mdv2007.0.i586.rpm 之 套 件 釋 出 的 次 數 為 何 <br />

Sol. 5mdv2007.0<br />

20. 檔 案 kplayer-0.5.3-5mdv2007.0.i586.rpm 之 套 件 適 合 的 硬 體 平 台 為 何 <br />

Sol. i586<br />

21. 檔 案 kplayer-0.5.3-5mdv2007.0.i586.rpm 中 mdv2007.0 代 表 意 義 為 何 <br />

Sol. mdv2007.0 表 示 打 包 之 環 境 為 Mandriva 2007.0。<br />

22. 將 檔 案 kplayer-0.5.3-5mdv2007.0.i586.rpm 安 裝 在 Fedora 7 是 否 恰<br />

當 為 什 麼 <br />

Sol. 不 恰 當 , 因 打 包 環 境 為 Mandriva 2007.0, 不 見 得 適 合 合 Fedora<br />

7。<br />

23. 檔 案 kplayer-0.5.3-5mdv2007.0.i586.rpm 中 i586 代 表 意 義 為 何 <br />

Sol. 適 合 安 裝 於 Intel 相 容 的 CPU 等 級 586 的 電 腦 。<br />

24. 檔 案 kplayer-0.5.3-5mdv2007.0.noarch.rpm 中 noarch 代 表 意 義 為 何 <br />

Sol. 安 裝 上 沒 有 任 何 硬 體 等 級 上 的 限 制 。<br />

25. 檔 案 kplayer-0.5.3-5mdv2007.0.athlon.rpm 中 athlon 代 表 意 義 為 何 <br />

Sol. 適 合 安 裝 於 AMD Athlon 晶 片 的 電 腦 。<br />

26. 檔 案 kplayer-0.5.3-5mdv2007.0.i386.rpm 是 否 可 安 裝 在 586 等 級 的 電<br />

腦 <br />

Sol. 可 以 。<br />

27. 檔 案 kplayer-0.5.3-5mdv2007.0.i586.rpm 是 否 可 安 裝 在 386 等 級 的 電<br />

腦 <br />

Sol. 不 可 以 。<br />

De-Yu Wang CSIE CYUT 301


16.2. 建 立 RPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

28. RPM 檔 案 系 統 工 作 目 錄 /usr/src/rpm/ 下 之 子 目 錄 BUILD 主 要 用 途 為 何 <br />

Sol. 編 譯 過 程 中 , 暫 存 資 料 放 置 目 錄 。<br />

29. RPM 檔 案 系 統 工 作 目 錄 /usr/src/rpm/ 下 之 子 目 錄 RPMS 主 要 用 途 為 何 <br />

Sol. 編 譯 打 包 成 功 後 , 完 成 的 rpm 檔 案 放 置 目 錄 。<br />

30. RPM 檔 案 系 統 工 作 目 錄 /usr/src/rpm/ 下 之 子 目 錄 SOURCES 主 要 用 途 為<br />

何 <br />

Sol. 放 置 套 件 的 原 始 碼 , 即 tarball 檔 。<br />

31. RPM 檔 案 系 統 工 作 目 錄 /usr/src/rpm/ 下 之 子 目 錄 SPECS 主 要 用 途 為 何 <br />

Sol. 放 置 套 件 的 規 格 檔 spec 檔 案 。<br />

32. RPM 檔 案 系 統 工 作 目 錄 /usr/src/rpm/ 下 之 子 目 錄 SRPMS 主 要 用 途 為 何 <br />

Sol. 編 譯 打 包 成 功 後 , 完 成 的 srpm 檔 案 放 置 目 錄 。<br />

33. 以 i586 硬 體 重 建 RPM 檔 案 , 產 生 之 rpm 套 件 放 在 那 個 目 錄 <br />

Sol. /usr/src/rpm/RPMS/i586<br />

16.2 建 立 RPM 套 件<br />

• 步 驗 :<br />

1. 收 集 要 包 裝 的 軟 體 。<br />

2. 產 生 spec 檔 案 , 這 個 檔 案 說 明 如 何 建 立 套 件 。<br />

3. 以 rpmbuild 命 令 建 立 套 件 。<br />

• 聚 集 (gather) 軟 體<br />

1. 收 集 應 用 程 式 原 始 碼 、 建 立 的 檔 案 ( 例 如 makefile)、 線 上 的 使 用 手<br />

冊 文 件 。<br />

2. 收 集 軟 體 最 簡 單 的 方 法 , 就 是 將 這 些 檔 案 以 tarball 產 生 方 法 , 裝 成<br />

一 個 tarball。<br />

3. tarball 的 檔 案 名 稱 , 必 須 有 應 用 程 式 名 稱 和 版 本 編 號 , 例 如<br />

myapp-1.0.tar.gz。<br />

4. 將 myapp-1.0.0.tar.gz 複 製 到 RPM 的 SOURCES 目 錄 。<br />

✞<br />

圱 $ cp myapp-1.0.tar.gz /usr/src/rpm/SOURCES<br />

✡✝<br />

✆<br />

• 建 立 程 式 myapp 的 RPM spec 檔 案 , 檔 案 名 稱 定 為 myapp.spec。<br />

1. 註 解 : 以 # 為 行 首 的 資 料 。 在 spec 檔 中 加 入 註 解 , 例 如 :<br />

De-Yu Wang CSIE CYUT 302


16.2. 建 立 RPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

✞<br />

圱 # spec file for package myapp (Version 1.0)<br />

✡✝<br />

✆<br />

2. 標 籤 ( tags ): 資 料 定 義 。 一 般 格 式 如 下 :<br />

✞<br />

圱 :<br />

✡✝<br />

✆<br />

(a) 導 文 ( preamble ): 設 定 套 件 名 稱 、 版 本 編 號 和 其 它 資 訊 。 例 如 :<br />

✞<br />

圱 Vendor: Wrox Press # 發 展 的 廠 商<br />

Distribution: Any #<br />

圳 Name: myapp # 套 件 的 名 稱<br />

Version: 1.0 # 套 件 的 版 本 資 訊<br />

圵 Release: 1 # 版 本 打 包 的 次 數 說 明<br />

Packager: neil@provider.com # 套 件 打 包 者<br />

圷 License: Copyright 2003 by Wrox Press # 套 件 的 授<br />

權 模 式<br />

Group: Applications/Media # 套 件 的 發 展 團 體 名 稱<br />

圹 Provides: goodness # 系 統 提 供 的 功 能<br />

Requires: mysql >= 3.23 # 套 件 之 相 依 套 件<br />

圱 圱 Buildroot: %{_tmppath}/%{name}-%{version}-root<br />

Source: %{name}-%{version}.tar.gz # 套 件 的 來 源<br />

圱 圳 Summary:<br />

✡✝<br />

Trivial application # 主 要 的 套 件 說 明<br />

✆<br />

(b) %description 標 籤 : 提 供 相 關 說 明 , 不 同 於 上 述 格 式 , 其 以 % 開<br />

頭 , 且 可 展 開 成 多 行 。 例 如 :<br />

✞<br />

圱 %description<br />

MyApp Trivial Application<br />

圳 A trivial application used to demonstrate development<br />

tools.<br />

This version pretends it requires MySQL at or above 3.23.<br />

圵 Authors: Neil Matthew and Richard Stones<br />

✡✝<br />

✆<br />

(c) 套 件 名 稱 與 版 本 巨 集 ( marco ), 例 如 :<br />

✞<br />

圱 Source: %{name}-%{version}.tar.gz<br />

圳<br />

# %{name} 與 %{version} 為 RPM 的 巨 集 , 分 別 表 示 套 件 名 稱 及 版<br />

本 ;<br />

# 在 本 例 中 rpmbuild 命 令 會 將 %{name} 展 開 成 為 ,<br />

而 myapp %{version} 展 開 為 ; 1.0<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 303


16.2. 建 立 RPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

(d) Buildroot 設 定 安 裝 目 錄 。<br />

✞<br />

Buildroot: %{_tmppath}/%{name}-%{version}-root<br />

圲 # %{_tmppath} 巨 集 內 容 可 以 rpm --showrc 查 詢 。<br />

✡✝<br />

✆<br />

3. RPM 工 作 腳 本 ( scripts )<br />

(a) %prep: build 前 的 準 備 ( prepare ) 動 作 , 主 要 是 執 行 套 件 解<br />

打 包 壓 縮 。 由 於 準 備 動 作 幾 乎 是 公 式 化 的 動 作 , 故 已 寫 成 巨 集<br />

%setup。 例 如 :<br />

✞<br />

%prep<br />

圲 %setup -q # 選 項 -q 代 表 設 定 為 安 靜 模 式 。<br />

✡✝<br />

✆<br />

(b) %build: 建 立 用 應 用 程 式 。 例 如 :<br />

✞<br />

%build<br />

圲 make<br />

✡✝<br />

✆<br />

(c) %install: 安 裝 應 用 程 式 、 使 用 手 冊 和 支 援 的 檔 案 。 例 如 :<br />

✞<br />

%install<br />

圲 mkdir -p $RPM_BUILD_ROOT%{_bindir}<br />

mkdir -p $RPM_BUILD_ROOT%{_mandir}<br />

圴 install -m755 myapp $RPM_BUILD_ROOT%{_bindir}/myapp<br />

install -m755 myapp.1 $RPM_BUILD_ROOT%{_mandir}/myapp.1<br />

圶 # %RPM_BUILD_ROOT 環 境 變 數 紀 錄 Buildroot 的 位 置 。<br />

# %{bindir} 和 %{_mandir} 巨 集 , 分 別 展 開 為 二 進 位 執 行 檔 案 目<br />

錄 和 使 用 手 冊 目 錄 。<br />

✡✝<br />

✆<br />

(d) %clean: 清 除 rpmbuild 命 令 產 生 的 檔 案 。 例 如 :<br />

✞<br />

圱 %clean<br />

rm -rf $RPM_BUILD_ROOT<br />

✡✝<br />

✆<br />

4. %files: 列 出 套 件 包 含 的 檔 案 。 例 如 :<br />

✞<br />

%files<br />

圲 %{_bindir}/myapp<br />

%{_mandir}/myapp.1<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 304


16.2. 建 立 RPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

5. %post: 套 件 安 裝 後 執 行 的 腳 本 。 例 如 :<br />

✞<br />

圱 %post<br />

mail root -s "myapp installed - please register" = 3.23<br />

圱 圴 Buildroot: %{_tmppath}/%{name}-%{version}-root<br />

source:<br />

%{name}-%{version}.tar.gz<br />

圱 圶 Summary: Trivial application<br />

%description<br />

圱 圸 MyApp Trivial Application<br />

A trivial application used to demonstrate development tools.<br />

圲 地 This version pretends it requires MySQL at or above 3.23.<br />

Authors: Neil Matthew and Richard Stones<br />

圲 圲 %prep<br />

%setup -q<br />

圲 圴 %build<br />

make<br />

圲 圶 %install<br />

mkdir -p $RPM_BUILD_ROOT%{_bindir}<br />

圲 圸 mkdir -p $RPM_BUILD_ROOT%{_mandir}<br />

install -m755 myapp $RPM_BUILD_ROOT%{_bindir}/myapp<br />

圳 地 install -m755 myapp.1 $RPM_BUILD_ROOT%{_mandir}/myapp.1<br />

%clean<br />

圳 圲 rm -rf $RPM_BUILD_ROOT<br />

%post<br />

圳 圴 mail root -s "myapp installed - please register"


16.2. 建 立 RPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

1. 語 法 :rpmbuild -bBuildStage spec_file<br />

選 項 bBuildStage 意 義<br />

-ba 建 立 所 有 , 包 含 二 進 位 和 原 始 碼 RPM。<br />

-bb 建 立 一 個 二 進 位 RPM。<br />

-bc 建 立 ( 編 譯 ) 程 式 , 但 是 不 會 建 立 整 個 RPM。<br />

-bp 準 備 建 立 一 個 二 進 位 RPM。<br />

-bi 產 生 一 個 二 進 位 RPM, 並 且 安 裝 它 。<br />

-bl 檢 查 RPM 的 檔 案 列 表 。<br />

-bs 只 建 立 一 個 原 始 碼 RPM。<br />

2. 建 立 套 件 輸 出 結 果 :<br />

✞<br />

圱 $ rpmbuild -ba myapp.spec<br />

Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.71108<br />

圳 + umask 022<br />

+ cd /usr/src/redhat/BUILD<br />

圵 + LANG=C<br />

+ export LANG<br />

圷 + cd /usr/src/redhat/BUILD<br />

+ rm -rf myapp-1.0<br />

圹 + /usr/bin/gzip -dc /usr/src/redhat/SOURCES/myapp-1.0.tar.gz<br />

+ tar -xf -<br />

圱 圱 + STATUS=0<br />

+ ’[’ 0 -ne 0 ’]’<br />

圱 圳 + cd myapp-1.0<br />

++ /usr/bin/id -u<br />

圱 圵 + ’[’ 0 = 0 ’]’<br />

+ /bin/chown -Rhf root .<br />

圱 圷 ++ /usr/bin/id -u<br />

+ ’[’ 0 = 0 ’]’<br />

圱 圹 + /bin/chgrp -Rhf root .<br />

+ /bin/chmod -Rf a+rX,g-w,o-w .<br />

圲 圱 + exit 0<br />

Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.43788<br />

圲 圳 + umask 022<br />

+ cd /usr/src/redhat/BUILD<br />

圲 圵 + cd myapp-1.0<br />

圲 圷<br />

+ LANG=C<br />

+ export LANG<br />

+ make<br />

圲 圹 gcc -g -Wall -ansi -c -o main.o main.c<br />

gcc -g -Wall -ansi -c -o 2.o 2.c<br />

圳 圱 ar rv mylib.a 2.o<br />

a - 2.o<br />

圳 圳 gcc -g -Wall -ansi -c -o 3.o 3.c<br />

ar rv mylib.a 3.o<br />

圳 圵 a - 3.o<br />

gcc -o myapp main.o mylib.a<br />

圳 圷 + exit 0<br />

Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.90688<br />

De-Yu Wang CSIE CYUT 306


16.2. 建 立 RPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

圳 圹 + umask 022<br />

+ cd /usr/src/redhat/BUILD<br />

圴 圱 + cd myapp-1.0<br />

+ LANG=C<br />

圴 圳 + export LANG<br />

+ mkdir -p /var/tmp/myapp-1.0-root/usr/bin<br />

圴 圵 + mkdir -p /var/tmp/myapp-1.0-root/usr/share/man<br />

+ install -m755 myapp /var/tmp/myapp-1.0-root/usr/bin/myapp<br />

圴 圷 + install -m755 myapp.1 /var/tmp/myapp-1.0-root/usr/share/man<br />

/myapp.1<br />

+ /usr/lib/rpm/find-debuginfo.sh /usr/src/redhat/BUILD/myapp<br />

-1.0<br />

圴 圹 extracting debug info from /var/tmp/myapp-1.0-root/usr/bin/<br />

myapp<br />

1 block<br />

圵 圱 + /usr/lib/rpm/redhat/brp-compress<br />

+ /usr/lib/rpm/redhat/brp-strip /usr/bin/strip<br />

圵 圳 + /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip<br />

+ /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip<br />

圵 圵 /usr/bin/objdump<br />

Processing files: myapp-1.0-1<br />

圵 圷 Provides: goodness<br />

Requires(interp): /bin/sh<br />

圵 圹 Requires(rpmlib): rpmlib(CompressedFileNames)


16.2. 建 立 RPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

2. 在 SRPMS 目 錄 的 原 始 碼 RPM 檔 :<br />

✞<br />

圱 myapp-1.0-1.src.rpm<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 請 說 明 建 立 RPM 套 件 三 步 驟 。<br />

Sol. 1. 收 集 要 包 裝 的 軟 體 。2. 產 生 spec 規 格 檔 案 。3. 以 rpmbuild 命 令<br />

建 立 套 件 。<br />

2. 建 立 RPM 套 件 要 先 收 集 程 式 相 關 檔 案 , 但 一 般 而 言 , 軟 體 開 發 所 產 生 之 檔 案<br />

不 只 一 個 , 最 簡 單 的 方 法 為 何 <br />

Sol. 將 所 有 相 關 檔 案 打 包 壓 縮 成 一 個 tarball。<br />

3. 建 立 RPM 套 件 要 先 收 集 程 式 相 關 檔 案 , 並 將 其 複 製 到 RPM 檔 案 系 統 下 那 個<br />

目 錄 <br />

Sol. SOURCES<br />

4. RPM 規 格 檔 案 , 一 般 附 檔 名 為 何 <br />

Sol. .spec<br />

5. 如 何 在 RPM 規 格 檔 案 中 加 入 註 解 <br />

Sol. 行 首 以 # 開 頭 。<br />

6. RPM 規 格 檔 案 中 標 籤 定 義 Vendor: Wrox Press, 意 義 為 何 <br />

Sol. 發 展 的 廠 商 Wrox Press<br />

7. RPM 規 格 檔 案 中 標 籤 定 義 Distribution: Any, 意 義 為 何 <br />

Sol. 適 用 任 何 的 <strong>Linux</strong> distribution<br />

8. RPM 規 格 檔 案 中 標 籤 定 義 Name: myapp, 意 義 為 何 <br />

Sol. 套 件 的 名 稱 myapp<br />

9. RPM 規 格 檔 案 中 標 籤 定 義 Version: 1.0, 意 義 為 何 <br />

Sol. 套 件 的 版 本 為 1.0<br />

10. RPM 規 格 檔 案 中 標 籤 定 義 Release: 1, 意 義 為 何 <br />

Sol. 版 本 打 包 的 次 數 1<br />

11. RPM 規 格 檔 案 中 標 籤 定 義 Packager: dywang@cyut.edu.tw, 意 義 為 何 <br />

Sol. 套 件 打 包 者 為 dywang@cyut.edu.tw<br />

12. RPM 規 格 檔 案 中 標 籤 定 義 License: GPL , 意 義 為 何 <br />

Sol. 套 件 的 授 權 模 式 GPL<br />

13. RPM 規 格 檔 案 中 標 籤 定 義 Group: Applications/Media, 意 義 為 何 <br />

Sol. 套 件 的 發 展 團 體 名 為 Applications/Media<br />

De-Yu Wang CSIE CYUT 308


16.2. 建 立 RPM 套 件 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

14. RPM 規 格 檔 案 中 標 籤 定 義 Provides: goodness, 意 義 為 何 <br />

Sol. 系 統 提 供 的 功 能 有 goodness<br />

15. RPM 規 格 檔 案 中 標 籤 定 義 Requires: mysql >= 3.23, 意 義 為 何 <br />

Sol. 套 件 之 相 依 套 件 mysql 且 版 本 需 >= 3.23<br />

16. RPM 規 格 檔 案 中 標 籤 定 義 Buildroot: %{_tmppath}/%{name}-%{version}-root,<br />

意 義 為 何 <br />

Sol. 建 立 rpm 套 件 的 暫 存 工 作 目 錄 為<br />

%{_tmppath}/%{name}-%{version}-root<br />

17. RPM 規 格 檔 案 中 標 籤 定 義 Source: %{name}-%{version}.tar.gz, 意 義 為<br />

何 <br />

Sol. 套 件 的 來 源 %{name}-%{version}.tar.gz<br />

18. RPM 規 格 檔 案 中 標 籤 定 義 Summary: Trivial application, 意 義 為 何 <br />

Sol. 主 要 的 套 件 說 明 Trivial application<br />

19. RPM 規 格 檔 案 中 標 籤 %description, 與 其 他 資 料 定 義 標 籤 , 主 要 不 同 為<br />

何 <br />

Sol. 以 % 開 頭 , 且 可 展 開 成 多 行 , 可 提 供 套 件 相 關 說 明 。<br />

20. RPM 規 格 檔 案 中 標 籤 定 義 Source: %{name}-%{version}.tar.gz, 其 中<br />

%{name}-%{version} 意 義 為 何 <br />

Sol. %{name} 與 %{version} 為 RPM 的 巨 集 ;rpmbuild 命 令 會 將 其 展 開<br />

為 套 件 名 稱 及 版 本 。<br />

21. RPM 規 格 檔 案 中 標 籤 定 義 Buildroot: %{_tmppath}/%{name}-%{version}-root,<br />

其 中 %{_tmppath} 意 義 為 何 <br />

Sol. %{_tmppath} 為 RPM 的 巨 集 ;rpmbuild 命 令 會 將 其 展 開 為 : 建 立<br />

rpm 套 件 的 暫 存 工 作 目 錄 。<br />

22. RPM 規 格 檔 案 中 工 作 腳 本 %prep, 主 要 工 作 內 容 為 何 <br />

Sol. 建 立 rpm 套 件 前 的 準 備 動 作 , 主 要 是 執 行 套 件 解 打 包 壓 縮 。<br />

23. RPM 規 格 檔 案 中 工 作 腳 本 %prep, 通 常 是 執 行 那 個 巨 集 為 什 麼 <br />

Sol. 由 於 準 備 動 作 幾 乎 是 公 式 化 的 動 作 , 故 已 寫 成 巨 集 %setup。<br />

24. RPM 規 格 檔 案 中 工 作 腳 本 %setup -q, 其 中 選 項 -q 代 表 意 義 為 何 <br />

Sol. 安 靜 模 式 。<br />

25. RPM 規 格 檔 案 中 工 作 腳 本 %build, 主 要 工 作 內 容 為 何 <br />

Sol. 建 立 用 應 用 程 式 , 通 常 是 執 行 make 。<br />

26. RPM 規 格 檔 案 之 工 作 腳 本 中 %RPM_BUILD_ROOT, 代 表 意 義 為 何 <br />

Sol. %RPM_BUILD_ROOT 為 環 境 變 數 , 紀 錄 Buildroot 的 位 置 。<br />

27. RPM 規 格 檔 案 之 工 作 腳 本 中 %{_bindir}, 代 表 意 義 為 何 <br />

Sol. %{_bindir} 為 RPM 的 巨 集 ;rpmbuild 命 令 會 將 其 展 開 為 二 進 位 執<br />

行 檔 案 目 錄 。<br />

De-Yu Wang CSIE CYUT 309


16.3. KPLAYER RPM 實 例 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

28. RPM 規 格 檔 案 之 工 作 腳 本 中 %{_mandir}, 代 表 意 義 為 何 <br />

Sol. %{_mandir} 為 RPM 的 巨 集 ;rpmbuild 命 令 會 將 其 展 開 為 使 用 手 冊<br />

目 錄 。<br />

29. RPM 規 格 檔 案 中 工 作 腳 本 %clean, 主 要 工 作 內 容 為 何 <br />

Sol. 清 除 rpmbuild 命 令 產 生 的 檔 案 。<br />

30. RPM 規 格 檔 案 中 工 作 腳 本 %file, 主 要 工 作 內 容 為 何 <br />

Sol. 列 出 套 件 包 含 的 檔 案 。<br />

31. RPM 規 格 檔 案 中 工 作 腳 本 %post, 主 要 工 作 內 容 為 何 <br />

Sol. 套 件 安 裝 後 需 執 行 的 動 作 。<br />

32. 建 立 RPM 套 件 指 令 為 何 <br />

Sol. rpmbuild<br />

33. 若 RPM 規 格 檔 為 myapp.spec, 如 何 同 時 建 立 RPM 與 SRPM 套 件 <br />

Sol. rpmbuild -ba myapp.spec<br />

34. 若 RPM 規 格 檔 為 myapp.spec, 如 何 只 建 立 RPM 套 件 <br />

Sol. rpmbuild -bb myapp.spec<br />

35. 若 RPM 規 格 檔 為 myapp.spec, 如 何 建 立 RPM 並 安 裝 它 <br />

Sol. rpmbuild -bi myapp.spec<br />

36. 若 RPM 規 格 檔 為 myapp.spec, 如 何 只 建 立 SRPM 套 件 <br />

Sol. rpmbuild -bs myapp.spec<br />

16.3 KPlayer RPM 實 例<br />

• 安 裝 rpm 原 始 碼<br />

1. 下 載 Mandriva 2007.0 kplayer rpm 原 始 碼 至 目 錄<br />

/usr/src/rpm/SRPMS<br />

✞<br />

圱 [root@dywHome2 SRPMS]# wget ftp://ftp.isu.edu.tw/<strong>Linux</strong>/<br />

Mandriva/<br />

devel/2007.0/SRPMS/contrib/release/kplayer-0.5.3-5mdv2007.0.<br />

src.rpm<br />

✡✝<br />

✆<br />

2. 使 用 urpmi 在 /usr/src/rpm/SRPMS, 安 裝 rpm 原 始 碼 :<br />

✞<br />

[root@dywHome2 SRPMS]# cd ..<br />

圲 [root@dywHome2 rpm]# urpmi SRPMS/kplayer-0.5.3-5mdv2007.0.src<br />

.rpm<br />

To satisfy dependencies, the following package is going to be<br />

installed:<br />

De-Yu Wang CSIE CYUT 310


16.3. KPLAYER RPM 實 例 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

圴<br />

圶<br />

libnas2-devel-1.8-1.1mdv2007.0.i586<br />

Proceed with the installation of the 1 packages (0 MB) (Y/n)<br />

y<br />

ftp://ftp.isu.edu.tw/<strong>Linux</strong>/Mandriva/official/2007.0/i586/<br />

media/main<br />

圸<br />

/updates/libnas2-devel-1.8-1.1mdv2007.0.i586.rpm<br />

installing libnas2-devel-1.8-1.1mdv2007.0.i586.rpm from /var/<br />

cache/urpmi/rpms<br />

圱 地 Preparing... #<br />

###########################################<br />

1/1: libnas2-devel #<br />

###########################################<br />

✡✝<br />

✆<br />

3. 查 看 rpm 原 始 碼 之 目 錄 :<br />

✞<br />

圱 [root@dywHome2 rpm]# ls BUILD/ RPMS/ SOURCES/ SPECS/ SRPMS/<br />

BUILD/:<br />

圳<br />

RPMS/:<br />

圵 athlon/ i386/ i486/ i586/ i686/ noarch/<br />

圷<br />

圹<br />

圱 圱<br />

SOURCES/:<br />

kplayer-0.5.3.tar.bz2<br />

SPECS/:<br />

kplayer.spec<br />

圱 圳<br />

SRPMS/:<br />

kplayer-0.5.3-5mdv2007.0.src.rpm<br />

✡✝<br />

✆<br />

• 程 式 修 改 與 重 新 打 包 壓 縮 :<br />

1. tarball 解 打 包 壓 縮 在 目 錄 kplayer-0.5.3。<br />

2. 修 改 目 錄 名 稱 :<br />

圲<br />

✞<br />

[root@dywHome2 SOURCES]# mv kplayer-0.5.3 kplayer-0.5.3.<br />

systray<br />

[root@dywHome2 SOURCES]# ll<br />

total 3097<br />

圴 drwxr-xr-x 9 root root 1024 Apr 5 15:17 kplayer-0.5.3.<br />

systray/<br />

-rw-r--r-- 1 root users 3156593 Jul 3 2006 kplayer-0.5.3.<br />

✡✝<br />

tar.bz2<br />

✆<br />

De-Yu Wang CSIE CYUT 311


16.3. KPLAYER RPM 實 例 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

3. 修 改 程 式 : 不 詳 述 。<br />

4. Makefile 修 改 : 與 tarball 相 同 。<br />

5. 版 本 序 號 0.5.3 後 , 加 入 .systray, 故 打 包 壓 縮 之 tarball 名 稱<br />

為 : kplayer-0.5.3.systray.tar.gz。<br />

✞<br />

圱 [root@dywHome2 SOURCES]# ll<br />

total 6820<br />

圳 drwxr-xr-x 9 root root 1024 Apr 5 17:27 kplayer-0.5.3.<br />

systray/<br />

-rw-r--r-- 1 root root 3795740 Apr 5 17:27 kplayer-0.5.3.<br />

systray.tar.gz<br />

圵 -rw-r--r-- 1 root users 3156593 Jul 3 2006 kplayer-0.5.3.<br />

tar.bz2<br />

[root@dywHome2 SOURCES]# cd ../SPECS/<br />

✡✝<br />

✆<br />

• 建 立 rpm 檔 案 :<br />

1. 修 改 kplayer.spec: 版 本 序 號 0.5.3 後 , 加 入 .systray<br />

✞<br />

[root@dywHome2 rpm]# vi SPECS/kplayer.spec<br />

圲 %define version 0.5.3.systray<br />

✡✝<br />

✆<br />

2. 產 生 kplayer-0.5.3.systray-5mdv2007.0.i586.rpm<br />

✞<br />

[root@dywHome2 SPECS]# rpmbuild -bb kplayer.spec 以 上 省 略<br />

圲 --------<br />

Wrote: /usr/src/rpm/RPMS/i586/kplayer-0.5.3.systray-5mdv2007<br />

.0.i586.rpm<br />

圴 Wrote: /usr/src/rpm/RPMS/i586/kplayer-debug-0.5.3.systray-5<br />

mdv2007.0.i586.rpm<br />

Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.6408<br />

圶 + umask 022<br />

圸<br />

+ cd /usr/src/rpm/BUILD<br />

+ cd kplayer-0.5.3.systray<br />

+ rm -rf /var/tmp/kplayer-0.5.3.systray-buildroot<br />

圱 地 + exit 0<br />

✡✝<br />

✆<br />

3. 查 看 rpm 檔 案<br />

✞<br />

[root@dywHome2 SPECS]# ll ../RPMS/i586/<br />

圲 total 6377<br />

-rw-r--r-- 1 root root 3122228 Apr 5 17:29<br />

圴 kplayer-0.5.3.systray-5mdv2007.0.i586.rpm<br />

De-Yu Wang CSIE CYUT 312


16.3. KPLAYER RPM 實 例 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

-rw-r--r-- 1 root root 3378549 Apr 5 17:29<br />

圶 kplayer-debug-0.5.3.systray-5mdv2007.0.i586.rpm<br />

✡✝<br />

✆<br />

• 建 立 二 進 位 和 原 始 碼 RPM 檔 案 :<br />

1. 產 生 kplayer-0.5.3.systray-5mdv2007.0.i586.src.rpm<br />

✞<br />

[root@dywHome2 SPECS]# rpmbuild -ba kplayer.spec 以 上 省 略<br />

圲 --------<br />

Wrote: /usr/src/rpm/SRPMS/kplayer-0.5.3.systray-5mdv2007.0.<br />

src.rpm<br />

圴 Wrote: /usr/src/rpm/RPMS/i586/kplayer-0.5.3.systray-5mdv2007<br />

.0.i586.rpm<br />

Wrote: /usr/src/rpm/RPMS/i586/kplayer-debug-0.5.3.systray-5<br />

mdv2007.0.i586.rpm<br />

圶 Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.26586<br />

+ umask 022<br />

圸 + cd /usr/src/rpm/BUILD<br />

+ cd kplayer-0.5.3.systray<br />

圱 地 + rm -rf /var/tmp/kplayer-0.5.3.systray-buildroot<br />

+ exit 0<br />

✡✝<br />

✆<br />

2. 查 看 二 進 位 和 原 始 碼 RPM 檔 案<br />

✞<br />

圱 [root@dywHome2 SPECS]# ll ../SRPMS/ ../RPMS/i586/<br />

../RPMS/i586/:<br />

圳 total 6377<br />

-rw-r--r-- 1 root root 3122404 Apr 5 17:46<br />

圵 kplayer-0.5.3.systray-5mdv2007.0.i586.rpm<br />

-rw-r--r-- 1 root root 3378599 Apr 5 17:46<br />

圷 kplayer-debug-0.5.3.systray-5mdv2007.0.i586.rpm<br />

圹 ../SRPMS/:<br />

total 6845<br />

圱 圱 -rw-r--r-- 1 root root 3168326 Apr 5 10:35<br />

kplayer-0.5.3-5mdv2007.0.src.rpm<br />

圱 圳 -rw-r--r-- 1 root root 3808850 Apr 5 17:46<br />

kplayer-0.5.3.systray-5mdv2007.0.src.rpm<br />

✡✝<br />

✆<br />

• 將 rpm 及 原 始 碼 rpm 釋 出<br />

1. 釋 出 kplayer-0.5.3.systray-5mdv2007.0.i586.rpm<br />

2. 釋 出 kplayer-0.5.3.systray-5mdv2007.0.src.rpm<br />

De-Yu Wang CSIE CYUT 313


16.3. KPLAYER RPM 實 例 CHAPTER 16. *RPM 與 SRPM 套 件 發 行<br />

De-Yu Wang CSIE CYUT 314


CHAPTER 17.<br />

* 套 件 修 補 、 檢 驗 與 管 理<br />

Chapter 17<br />

* 套 件 修 補 、 檢 驗 與 管 理<br />

17.1 patch 程 式<br />

• 為 什 麼 patch<br />

1. 檔 案 ( 版 本 ) 之 間 的 差 異 , 可 以 指 令 diff 儲 存 在 一 個 patch 檔 案 。<br />

2. 若 舊 版 本 需 要 修 改 , 只 要 將 patch 檔 案 釋 出 。<br />

3. 使 用 者 可 以 指 令 patch, 配 合 patch 檔 案 中 記 錄 之 新 舊 版 差 異 , 將 舊<br />

版 程 式 更 新 。<br />

4. 使 用 者 若 發 現 並 修 正 一 個 程 式 的 臭 蟲 , 簡 單 、 正 確 的 方 式 是 , 寄 一 個<br />

patch 檔 案 給 作 者 , 而 不 要 只 是 說 明 修 正 的 地 方 。<br />

• diff 指 令 : 比 對 兩 個 檔 案 之 間 的 差 異 , 一 般 是 用 在 ASCII 純 文 字 檔 的 比 對<br />

上 。<br />

1. diff 指 令 用 法 :<br />

✞<br />

[root@linux ~]# diff [-bBiqn] from-file to-file 選 項 :<br />

圲<br />

from-file : 檔 名 , 作 為 原 始 比 對 檔 案 的 檔 名 ;<br />

圴 to-file : 檔 名 , 作 為 目 的 比 對 檔 案 的 檔 名 ;<br />

# from-file 或 to-file 可 以 - 取 代 , - 代 表<br />

『Standard 』。input<br />

圶<br />

-b : 忽 略 一 行 當 中 , 多 個 空 白 的 差 異 例 如<br />

圸 ( "about me" 與 "about me" 視 為 相 同 )<br />

-B : 忽 略 空 白 行 的 差 異 。<br />

圱 地 -i : 忽 略 大 小 寫 的 不 同 。<br />

-q : 只 列 出 檔 案 是 否 有 差 異 。<br />

圱 圲 -n : 以 RCS 格 式 輸 出 檔 案 之 差 異 。<br />

-c (-C NUM) : 兩 個 檔 案 皆 加 入 差 異 部 分 前 後 NUM 行 , 以 增 加 輸 出 之 可<br />

讀 性 。 預 設 NUM。=3<br />

圱 圴 -u (-U NUM) : 加 入 差 異 部 分 前 後 NUM 行 , 以 增 加 輸 出 之 可 讀 性 。 預<br />

✡✝ 設 NUM。=3<br />

✆<br />

De-Yu Wang CSIE CYUT 315


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

2. 預 處 理 : 將 /etc/passwd 第 四 行 刪 除 , 第 六 行 取 代 為 『no six<br />

line』, 新 的 檔 案 放 到 /tmp/test。<br />

✞<br />

[root@linux ~]# mkdir -p /tmp/test<br />

圲 [root@linux ~]# cat /etc/passwd | \<br />

> sed -e ’4d’ -e ’6c no six line’ > /tmp/test/passwd<br />

圴 # sed 後 面 若 要 接 超 過 兩 個 以 上 的 動 作 時 , 每 個 動 作 前 面 得 加 -e 。<br />

✡✝<br />

✆<br />

3. 比 對 /tmp/test/passwd 與 /etc/passwd 的 差 異 。<br />

✞<br />

[root@dywHome2 ~]# diff /etc/passwd /tmp/test/passwd<br />

圲 4d3<br />

< adm:x:3:4:adm:/var/adm:/bin/sh<br />

圴 6c5<br />

< sync:x:5:0:sync:/sbin:/bin/sync<br />

圶 ---<br />

> no six line<br />

✡✝<br />

✆<br />

4. 只 列 出 檔 案 是 否 有 差 異 。<br />

✞<br />

圱 [root@dywHome2 ~]# diff -q /etc/passwd /tmp/test/passwd<br />

Files /etc/passwd and /tmp/test/passwd differ<br />

✡✝<br />

✆<br />

5. 以 RCS 格 式 輸 出 檔 案 之 差 異 。<br />

✞<br />

[root@dywHome2 ~]# diff -n /etc/passwd /tmp/test/passwd<br />

圲 d4 1<br />

d6 1<br />

圴 a6 1<br />

no six line<br />

✡✝<br />

✆<br />

6. 加 入 差 異 部 分 前 後 3 行 , 以 增 加 輸 出 之 可 讀 性 。<br />

✞<br />

圱 [root@dywHome2 tmp]# diff -u old/ new/ > test.patch<br />

[root@dywHome2 tmp]# cat test.patch<br />

圳 diff -u old/passwd new/passwd<br />

--- old/passwd 2008-04-16 13:14:50.000000000 -0400<br />

圵 +++ new/passwd 2008-04-16 11:15:12.000000000 -0400<br />

@@ -1,9 +1,8 @@<br />

圷 root:x:0:0:root:/root:/bin/bash<br />

bin:x:1:1:bin:/bin:/bin/sh<br />

圹 daemon:x:2:2:daemon:/sbin:/bin/sh<br />

-adm:x:3:4:adm:/var/adm:/bin/sh<br />

De-Yu Wang CSIE CYUT 316


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

圱 圱 lp:x:4:7:lp:/var/spool/lpd:/bin/sh<br />

-sync:x:5:0:sync:/sbin:/bin/sync<br />

圱 圳 +no six line<br />

shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown<br />

圱 圵 halt:x:7:0:halt:/sbin:/sbin/halt<br />

mail:x:8:12:mail:/var/spool/mail:/bin/sh<br />

✡✝<br />

✆<br />

7. 比 對 /etc 與 /tmp/test 的 差 異 。<br />

✞<br />

[root@linux ~]# diff /etc /tmp/test 前 面 省 略<br />

圲 ......().....<br />

Only in /etc: paper.config<br />

圴 diff /etc/passwd /tmp/test/passwd<br />

4d3<br />

圶 < adm:x:3:4:adm:/var/adm:/sbin/nologin<br />

6c5<br />

圸 < sync:x:5:0:sync:/sbin:/bin/sync<br />

圱 地<br />

---<br />

> no six line<br />

Only in /etc: passwd- 後 面 省 略<br />

圱 圲 ......().....<br />

✡✝<br />

✆<br />

• cmp: 主 要 利 用 『 位 元 』 單 位 去 比 對 (diff 主 要 是 以 『 行 』 為 單 位 比 對 ,cmp<br />

則 是 以 『 位 元 』 為 單 位 去 比 對 )。<br />

1. cmp 指 令 用 法 :<br />

✞<br />

[root@linux ~]# cmp [-bcsi] file1 file2 選 項 :<br />

圲<br />

-b : 列 出 第 一 個 的 不 同 點 之 字 元 。<br />

圴 -c : 同 上 。<br />

-i SKIP1:SKIP2 : file1 與 file2 分 別 忽 略 前 SKIP1 與 SKIP2 位<br />

元 。<br />

圶 -s : 安 靜 模 式 , 不 顯 示 任 何 訊 息 。<br />

✡✝<br />

✆<br />

2. 用 cmp 比 較 /etc/passwd 與 /tmp/test/passwd<br />

✞<br />

[root@dywHome2 ~]# cmp /etc/passwd /tmp/test/passwd<br />

圲 /etc/passwd /tmp/test/passwd differ: byte 94, line 4<br />

# 不 同 點 在 第 四 行 , 而 且 位 元 數 是 在 第 94 個 位 元 。<br />

✡✝<br />

✆<br />

3. 列 出 第 一 個 的 不 同 點 之 字 元<br />

De-Yu Wang CSIE CYUT 317


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

✞<br />

圱 [root@dywHome2 ~]# cmp -c /etc/passwd /tmp/test/passwd<br />

/etc/passwd /tmp/test/passwd differ: byte 94, line 4 is 141 a<br />

154 l<br />

圳 # 不 同 點 在 檔 案 /etc/passwd 的 第 一 個 字 元 為 , 在 檔<br />

案 a /tmp/test/passwd 的 第 一 個 字 元 為 。 l<br />

# 字 元 a 之 八 進 位 碼 為 , 字 元 141 l 之 八 進 位 碼 為 。 154<br />

✡✝<br />

✆<br />

4. 以 printf 驗 證 ASCII 之 字 元<br />

✞<br />

[root@dywHome2 ~]# printf ’\x61\t\x6c\n’<br />

圲 a l<br />

# \xNN : NN 為 十 六 進 位<br />

✡✝<br />

✆<br />

• patch: 檔 案 補 丁 。 需 與 diff 配 合 使 用 。<br />

1. patch 指 令 用 法<br />

✞<br />

圱 [root@linux ~]# patch [OPTION]... [ORIGFILE [PATCHFILE]] 選<br />

項 :<br />

圳 -pNUM : 取 消 NUM 層 目 錄 。 例 如 : 假 設 檔 名<br />

/u/howard/src/blurfl/blurfl.c<br />

圵 -p0 : 代 表 u/howard/src/blurfl/blurfl.c<br />

-p4 : 代 表 blurfl/blurfl.c<br />

圷 -l : 忽 略 空 白 之 差 異 。<br />

-i PATCHFILE : 從 PATCHFILE 讀 取 補 丁 。<br />

圹 -o FILE : 輸 出 補 丁 到 檔 案 。 FILE<br />

-r FILE : 輸 出 錯 誤 到 檔 案 。 FILE<br />

✡✝<br />

✆<br />

2. 預 處 理 : 建 立 兩 個 不 同 版 本 的 檔 案 /tmp/test/passwd 與<br />

/etc/passwd。<br />

✞<br />

[root@dywHome2 ~]# mkdir /tmp/old; cp /etc/passwd /tmp/old<br />

圲 [root@dywHome2 ~]# mkdir /tmp/new; cp /tmp/test/passwd /tmp/<br />

new<br />

✡✝<br />

✆<br />

3. 建 立 補 丁 檔 案 /tmp/test.patch 記 錄 新 舊 檔 案 之 間 的 差 異 。<br />

✞<br />

[root@dywHome2 ~]# cd /tmp ; diff old/ new/ > test.patch<br />

圲 # diff 製 作 檔 案 時 , 舊 的 檔 案 必 須 是 在 前 面 , 亦 即<br />

是 diff oldfile 。newfile<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 318


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

4. 將 舊 的 內 容 (/tmp/old/passwd) 更 新 到 新 版 (/tmp/new/passwd) 的<br />

內 容<br />

✞<br />

[root@dywHome2 tmp]# cd /tmp/old<br />

圲 [root@dywHome2 old]# patch passwd -i /tmp/test.patch<br />

patching file passwd<br />

圴 # 選 項 -i 亦 可 省 略<br />

✡✝<br />

✆<br />

5. 更 新 內 容 , 並 指 定 存 於 passwd1<br />

✞<br />

[root@dywHome2 old]# patch passwd /tmp/test.patch -o passwd1<br />

圲 patching file passwd<br />

✡✝<br />

✆<br />

6. 內 容 已 更 新 , 若 再 做 一 次 補 丁 , 系 統 會 詢 問 是 否 執 行 <br />

(a) 預 設 回 答 n(o): 系 統 會 將 錯 誤 訊 息 存 在 passwd.rej<br />

✞<br />

[root@dywHome2 old]# patch passwd -i /tmp/test.patch<br />

圲 patching file passwd<br />

Reversed (or previously applied) patch detected! Assume<br />

-R [n] n<br />

圴 Apply anyway [n] n<br />

Skipping patch.<br />

圶 2 out of 2 hunks ignored -- saving rejects to file passwd<br />

.rej<br />

✡✝<br />

✆<br />

(b) 回 答 y(es): 系 統 會 將 更 新 後 的 內 容 存 在 passwd.orig<br />

✞<br />

[root@dywHome2 old]# patch passwd -i /tmp/test.patch<br />

圲 patching file passwd<br />

Reversed (or previously applied) patch detected! Assume<br />

-R [n] y<br />

✡✝<br />

✆<br />

(c) 查 詢 檔 案<br />

✞<br />

圱 [root@dywHome2 old]# ll passwd*<br />

-rw-r--r-- 1 root root 1207 Apr 16 13:14 passwd<br />

圳 -rw------- 1 root root 1156 Apr 16 13:10 passwd1<br />

-rw-r--r-- 1 root root 1156 Apr 16 13:11 passwd.orig<br />

圵 -rw-r--r-- 1 root root 149 Apr 16 13:12 passwd.rej<br />

✡✝<br />

✆<br />

7. 使 用 選 項 -pNUM 更 新 舊 版 資 料<br />

De-Yu Wang CSIE CYUT 319


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

(a) 變 換 目 錄 至 /tmp<br />

✞<br />

圱 [root@dywHome2 old]# cd ..<br />

✡✝<br />

✆<br />

(b) 以 選 項 -u 建 立 目 錄 old/ 與 new/ 下 檔 案 之 差 異 檔 , 再 回 到 目<br />

錄 /tmp/old。<br />

✞<br />

圱 [root@dywHome2 tmp]# diff -u old/ new/ > /tmp/test.patch<br />

[root@dywHome2 tmp]# cd old<br />

✡✝<br />

(c) test.patch 儲 存 diff -u old/passwd new/passwd, 故 必 須 一 層<br />

目 錄 , 即 -p1。<br />

✞<br />

[root@dywHome2 old]# patch -p1


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

2. 產 生 第 二 版 的 檔 案 file2.c:<br />

✞<br />

圱 This is file two<br />

line 2<br />

圳 line 3<br />

line 4<br />

圵 line 5<br />

line 6<br />

圷 a new line 8<br />

✡✝<br />

✆<br />

3. 利 用 diff 命 令 產 生 差 異 :<br />

✞<br />

圱 $ diff file1.c file2.c > diffs<br />

diffs 檔 案 如 下 :<br />

圳 1c1<br />

< This is file one|<br />

圵<br />

> This is file two<br />

圷 4c4,5<br />

< there is no line 4, this is line 5|<br />

圹<br />

> line 4<br />

圱 圱 > line 5<br />

5a7<br />

圱 圳 > a new line 8<br />

✡✝<br />

✆<br />

4. 假 設 有 file1.c 和 diffs 檔 案 。 可 以 利 用 patch 命 令 更 新<br />

file1.c, 使 其 與 file2.c 一 樣 。<br />

✞<br />

圱 $ patch file1.c diffs<br />

Hmm... Looks like a normal diff to me...<br />

圳 Patching file file1.c using Plan A...<br />

Hunk #1 succeeded at 1.<br />

圵 Hunk #2 succeeded at 4.<br />

Hunk #3 succeeded at 7.<br />

圷 done<br />

$<br />

✡✝<br />

✆<br />

5. 若 希 望 回 覆 file1.c , 只 要 再 使 用 patch, 加 上 -R( 反 向 patch) 選<br />

項 ,file1.c 就 會 回 到 原 本 的 狀 況 。。<br />

✞<br />

$ patch -R file1.c diffs<br />

圲 Hmm... Looks like a normal diff to me...<br />

Patching file file1.c using Plan A...<br />

圴 Hunk #1 succeeded at 1.<br />

De-Yu Wang CSIE CYUT 321


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

Hunk #2 succeeded at 4.<br />

圶 Hunk #3 succeeded at 6.<br />

done<br />

圸 $<br />

✡✝<br />

✆<br />

• 例 題 : 完 成 下 列 工 作 。<br />

練 習 題<br />

1. 以 vi 在 printf.txt 最 後 加 入 一 行 csie - - -, 並 另 存 為<br />

printf.new;<br />

2. 以 diff 比 較 printf.txt 及 printf.new, 並 建 立 其 patch<br />

file,printf.patch;<br />

3. 以 cmp 比 較 printf.txt 及 printf.new;<br />

4. 利 用 patch file,printf.patch 將 printf.txt 更 新 為<br />

printf.new。<br />

1. 使 用 開 放 原 始 碼 之 套 件 時 , 若 發 現 並 修 正 一 個 程 式 的 臭 蟲 , 要 如 何 以 一 個 簡<br />

單 、 正 確 的 方 式 通 知 者 <br />

Sol. 寄 一 個 patch 檔 案 給 作 者 , 而 不 要 只 是 說 明 修 正 的 地 方 。<br />

2. 請 以 指 令 cat 及 sed 配 合 管 線 處 理 , 將 /etc/passwd 第 四 行 刪 除 , 第 六<br />

行 取 代 為 『no six line』, 新 的 檔 案 存 為 /tmp/passwd。<br />

Sol. cat /etc/passwd | sed -e ’4d’ -e ’6c no six line’ ><br />

/tmp/passwd<br />

3. 如 何 以 指 令 diff 比 對 兩 個 檔 案 file1 與 file2 之 差 異 <br />

Sol. diff file1 file2<br />

4. 以 diff 比 對 file1 與 file2, 出 現 訊 息 4d3, 代 表 意 義 為 何 <br />

Sol. file1 第 四 行 被 刪 除<br />

5. 以 diff 比 對 file1 與 file2, 出 現 訊 息 6c5, 代 表 意 義 為 何 <br />

Sol. file1 第 六 行 被 取 代 成 file2 的 第 五 行<br />

6. 如 何 以 指 令 diff 比 對 兩 個 檔 案 file1 與 file2, 且 只 列 出 檔 案 是 否 有 差<br />

異 <br />

Sol. diff -q file1 file2<br />

7. 如 何 以 指 令 diff 比 對 兩 個 檔 案 file1 與 file2, 且 忽 略 一 行 當 中 , 多 個<br />

空 白 的 差 異 <br />

Sol. diff -b file1 file2<br />

8. 如 何 以 指 令 diff 比 對 兩 個 檔 案 file1 與 file2, 且 忽 略 空 白 行 的 差 異 <br />

Sol. diff -B file1 file2<br />

De-Yu Wang CSIE CYUT 322


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

9. 如 何 以 指 令 diff 比 對 兩 個 檔 案 file1 與 file2, 且 忽 略 大 小 寫 的 不 同 <br />

Sol. diff -i file1 file2<br />

10. 如 何 以 指 令 diff 比 對 兩 個 檔 案 file1 與 file2, 且 以 RCS 格 式 輸 出 檔 案<br />

之 差 異 <br />

Sol. diff -n file1 file2<br />

11. 如 何 以 diff 比 對 兩 目 錄 /tmp/old 與 /tmp/new, 並 將 新 舊 檔 案 之 間 的 差<br />

異 記 錄 在 test.patch<br />

Sol. diff /tmp/old /tmp/new > test.patch<br />

12. 如 何 以 diff 比 對 兩 目 錄 /tmp/old 與 /tmp/new, 並 將 新 舊 檔 案 之 間 的 差<br />

異 記 錄 在 test.patch, 且 加 入 差 異 部 分 前 後 3 行 , 以 增 加 輸 出 之 可 讀 性 <br />

Sol. diff -u /tmp/old /tmp/new > test.patch<br />

13. 若 有 一 檔 案 test.patch 記 錄 兩 目 錄 /tmp/old 與 /tmp/new 之 間 的 差 異 ,<br />

如 何 將 舊 的 內 容 /tmp/old 更 新 到 新 版 /tmp/new 的 內 容 <br />

Sol. patch -p1 < /tmp/test.patch<br />

14. 如 何 以 『 位 元 』 為 單 位 比 對 兩 檔 案 file1 與 file2<br />

Sol. cmp file1 file2<br />

15. 以 指 令 cmp 比 對 兩 檔 案 file1 與 file2, 最 後 出 現 differ: byte 94,<br />

line 4, 代 表 意 義 為 何 <br />

Sol. 不 同 點 在 第 四 行 , 而 且 位 元 數 是 在 第 94 個 位 元 。<br />

16. 如 何 以 指 令 cmp 比 對 兩 檔 案 file1 與 file2, 且 列 出 第 一 個 的 不 同 點 之 字<br />

元 <br />

Sol. cmp -c file1 file2<br />

17. 以 指 令 cmp 比 對 兩 檔 案 file1 與 file2, 最 後 出 現 differ: byte 94,<br />

line 4 is 141 a 154 l, 其 中 a 與 l 代 表 意 義 為 何 <br />

Sol. 不 同 點 在 檔 案 file1 的 第 一 個 字 元 為 a, 在 檔 案 file2 的 第 一 個 字<br />

元 為 l。<br />

18. 以 指 令 cmp 比 對 兩 檔 案 file1 與 file2, 最 後 出 現 differ: byte 94,<br />

line 4 is 141 a 154 l, 其 中 141 代 表 意 義 為 何 <br />

Sol. 字 元 a 之 八 進 位 碼 為 141。<br />

19. 以 指 令 cmp 比 對 兩 檔 案 file1 與 file2, 最 後 出 現 differ: byte 94,<br />

line 4 is 141 a 154 l, 其 中 154 代 表 意 義 為 何 <br />

Sol. 字 元 l 之 八 進 位 碼 為 154。<br />

20. 指 定 格 式 方 式 輸 出 printf ’\x61\t\x6c\n’, 其 中 \x61 代 表 意 義 為 何 <br />

Sol. 表 示 輸 出 十 六 進 位 61 ( 即 八 進 位 141) 之 ASCII 字 元 , 螢 幕 輸 輸 出<br />

應 為 a。<br />

De-Yu Wang CSIE CYUT 323


17.1. PATCH 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

21. 指 定 格 式 方 式 輸 出 printf ’\x61\t\x6c\n’, 其 中 \x6c 代 表 意 義 為 何 <br />

Sol. 表 示 輸 出 十 六 進 位 6c ( 即 八 進 位 154) 之 ASCII 字 元 , 螢 幕 輸 輸 出<br />

應 為 l。<br />

22. 如 何 以 指 令 patch, 配 合 passwd 之 補 丁 檔 案 /tmp/test.patch, 將<br />

passwd 更 新 <br />

Sol. patch passwd -i /tmp/test.patch<br />

23. 若 以 指 令 patch 進 行 檔 案 更 新 , 出 現 patching file passwd, 代 表 意 義 為<br />

何 <br />

Sol. 表 示 更 新 檔 案 passwd 完 成 。<br />

24. 如 何 以 指 令 patch, 配 合 passwd 之 補 丁 檔 案 /tmp/test.patch, 將<br />

passwd 更 新 , 且 將 更 新 內 容 另 存 於 passwd1<br />

Sol. patch passwd /tmp/test.patch -o passwd1<br />

25. 若 以 指 令 patch 進 行 檔 案 file1 更 新 發 生 錯 誤 , 系 統 會 將 錯 誤 訊 息 存 在 那<br />

個 檔 案 <br />

Sol. file1.rej<br />

26. 若 補 丁 檔 案 在 /tmp/test.patch, 如 何 以 指 令 patch 進 行 檔 案 file1 更<br />

新 , 並 指 定 錯 誤 輸 出 檔 案 為 error.rej<br />

Sol. patch file1 /tmp/test.patch -r error.rej<br />

27. 若 已 以 指 令 patch 進 行 檔 案 passwd 更 新 , 現 再 次 進 行 patch, 會 出 現 什<br />

麼 訊 息 <br />

Sol. 詢 問 是 否 進 行 。<br />

28. 若 已 以 指 令 patch 進 行 檔 案 passwd 更 新 , 現 再 次 進 行 patch 會 詢 問 是 否<br />

進 行 , 如 果 回 應 確 定 執 行 , 會 產 生 什 麼 結 果 <br />

Sol. 系 統 會 將 更 新 後 的 內 容 另 存 在 passwd.orig<br />

29. 若 已 以 指 令 patch 進 行 檔 案 passwd 更 新 , 現 再 次 進 行 patch 會 詢 問 是 否<br />

進 行 , 如 果 回 應 不 繼 續 執 行 , 會 產 生 什 麼 結 果 <br />

Sol. 系 統 會 將 錯 誤 訊 息 存 在 passwd.rej<br />

30. 在 目 錄 /tmp 下 , 執 行 diff -u old/ new/ > /tmp/test.patch, 再 進 入 目<br />

錄 /tmp/old, 如 何 以 patch 進 行 目 前 目 錄 /tmp/old 下 所 有 檔 案 之 更 新 <br />

Sol. patch -p1


17.2. 檢 驗 軟 體 正 確 性 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

33. 若 補 丁 檔 中 記 錄 之 檔 案 為 /u/howard/src/blurfl/blurfl.cdiff, 則 執 行<br />

patch -p2


17.2. 檢 驗 軟 體 正 確 性 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

✞<br />

圱 [root@dywHome2 SOURCES]# cat kplayer.md5<br />

b907112f049c3c46664b4eab042f545e kplayer-0.5.3.systray.tar.<br />

gz<br />

✡✝<br />

✆<br />

5. 編 輯 readme 檔 :<br />

✞<br />

[root@dywHome2 SOURCES]# vi readme<br />

圲 [root@dywHome2 SOURCES]# cat readme<br />

kplayer-0.5.3.systray.tar.gz kplyaer source codes tarball<br />

圴 kplayer.md5 md5sum file<br />

✡✝<br />

✆<br />

6. 計 算 readme 的 檔 案 指 紋 , 並 累 加 至 指 紋 檔 kplayer.md5:<br />

✞<br />

[root@dywHome2 SOURCES]# md5sum readme >> kplayer.md5<br />

✡✝<br />

✆<br />

7. 再 查 看 指 紋 檔 kplayer.md5 內 容 :<br />

✞<br />

圱 [root@dywHome2 SOURCES]# cat kplayer.md5<br />

b907112f049c3c46664b4eab042f545e kplayer-0.5.3.systray.tar.<br />

gz<br />

圳 761adab1a7b0bc9fb2b60542137ee335 readme<br />

✡✝<br />

✆<br />

• 指 紋 驗 證 機 制 MD5: 判 斷 檔 案 有 沒 有 被 更 動 過 。<br />

1. md5sum 驗 證 選 項 :<br />

✞<br />

圱 [root@linux ~]# md5sum [-bct] filename 選 項 :<br />

圳 -b : 使 用 binary 的 讀 檔 方 式 , 預 設 為 Windows/DOS 檔 案 型 態 的 讀 取<br />

方 式 ;<br />

-c : 檢 驗 md5sum 檔 案 指 紋 ;<br />

圵 -t : 以 文 字 型 態 來 讀 取 md5sum 的 檔 案 指 紋 。<br />

✡✝<br />

✆<br />

2. 讀 取 readme 之 檔 案 指 紋 :<br />

✞<br />

圱 [root@dywHome2 SOURCES]# md5sum readme<br />

761adab1a7b0bc9fb2b60542137ee335 readme<br />

圳 [root@dywHome2 SOURCES]# md5sum -b readme<br />

761adab1a7b0bc9fb2b60542137ee335 *readme<br />

圵 [root@dywHome2 SOURCES]# md5sum -t readme<br />

De-Yu Wang CSIE CYUT 326


17.2. 檢 驗 軟 體 正 確 性 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

761adab1a7b0bc9fb2b60542137ee335<br />

✡✝<br />

readme<br />

✆<br />

3. 檢 驗 kplayer.md5 檔 案 指 紋 :<br />

✞<br />

[root@dywHome2 SOURCES]# md5sum -c kplayer.md5<br />

圲 kplayer-0.5.3.systray.tar.gz: OK<br />

readme: OK<br />

✡✝<br />

✆<br />

4. 修 改 readme:<br />

✞<br />

圱 [root@dywHome2 SOURCES]# vi readme<br />

[root@dywHome2 SOURCES]# cat readme<br />

圳 kplayer-0.5.3.systray.tar.gz kplyaer: source codes tarball<br />

kplayer.md5: md5sum file<br />

✡✝<br />

✆<br />

5. 再 讀 取 readme 之 檔 案 指 紋 , 已 經 不 同 於 kplayer.md5 所 存 內 容 :<br />

✞<br />

[root@dywHome2 SOURCES]# md5sum -t readme<br />

圲 5a4d99c2a9b759dca679c2c1001cf8d4 readme<br />

✡✝<br />

✆<br />

6. 再 檢 驗 kplayer.md5 檔 案 指 紋 :<br />

✞<br />

[root@dywHome2 SOURCES]# md5sum -c kplayer.md5<br />

圲 kplayer-0.5.3.systray.tar.gz: OK<br />

readme: FAILED<br />

圴 md5sum: WARNING: 1 of 2 computed checksums did NOT match<br />

✡✝<br />

✆<br />

• 以 Mandriva 2007.0 更 新 目 錄 之 MD5SUM 為 例 :<br />

1. 下 載 檔 案 指 紋 碼 :<br />

✞<br />

[root@dywHome2 rpm]# wget ftp://ftp.isu.edu.tw/<strong>Linux</strong>/Mandriva<br />

圲 /official/2007.0/i586/media/main/updates/media_info/MD5SUM<br />

--20:57:43-- ftp://ftp.isu.edu.tw/<strong>Linux</strong>/Mandriva<br />

圴 /official/2007.0/i586/media/main/updates/media_info/MD5SUM<br />

=> ‘MD5SUM’<br />

圶 Resolving ftp.isu.edu.tw... 140.127.177.15, 140.127.177.17<br />

Connecting to ftp.isu.edu.tw|140.127.177.15|:21... connected.<br />

圸 Logging in as anonymous ... Logged in!<br />

==> SYST ... done. ==> PWD ... done.<br />

De-Yu Wang CSIE CYUT 327


17.2. 檢 驗 軟 體 正 確 性 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

圱 地 ==> TYPE I ... done. ==> CWD /<strong>Linux</strong>/Mandriva/official<br />

/2007.0/i586/media/main/updates/media_info ... done.<br />

==> PASV ... done. ==> RETR MD5SUM ... done.<br />

圱 圲 Length: 98 (unauthoritative)<br />

圱 圴 100%[===============================================>] 98<br />

--.--K/s<br />

圱 圶 20:57:49 (51.26 KB/s) - ‘MD5SUM’ saved [98]<br />

✡✝<br />

✆<br />

2. 查 看 MD5SUM 內 容 :<br />

✞<br />

[root@dywHome2 rpm]# cat MD5SUM<br />

圲 374fca8ea858a7079c3717acca208e47 hdlist.cz<br />

38b6616b9514707ff8dc344eadd5468f<br />

✡✝<br />

synthesis.hdlist.cz<br />

✆<br />

3. 下 載 檔 案 :<br />

✞<br />

圱 [root@dywHome2 rpm]# wget ftp://ftp.isu.edu.tw/<strong>Linux</strong>/Mandriva<br />

/official/2007.0/i586/media/main/updates/media_info/hdlist.cz<br />

圳 --20:58:30-- ftp://ftp.isu.edu.tw/<strong>Linux</strong>/Mandriva<br />

/official/2007.0/i586/media/main/updates/media_info/hdlist.cz<br />

圵<br />

=> ‘hdlist.cz’<br />

Resolving ftp.isu.edu.tw... 140.127.177.15, 140.127.177.17<br />

圷 Connecting to ftp.isu.edu.tw|140.127.177.15|:21... connected.<br />

Logging in as anonymous ... Logged in!<br />

圹 ==> SYST ... done. ==> PWD ... done.<br />

==> TYPE I ... done. ==> CWD /<strong>Linux</strong>/Mandriva/official<br />

/2007.0/i586/media/main/updates/media_info ... done.<br />

圱 圱 ==> PASV ... done. ==> RETR hdlist.cz ... done.<br />

Length: 21,737,096 (21M) (unauthoritative)<br />

圱 圳<br />

100%[===============================================>]<br />

21,737,096 102.50K/s ETA 00:00<br />

圱 圵<br />

21:02:04 (99.67 KB/s) - ‘hdlist.cz’ saved [21737096]<br />

圱 圷<br />

[root@dywHome2 rpm]# wget ftp://ftp.isu.edu.tw/<strong>Linux</strong>/Mandriva<br />

圱 圹 /official/2007.0/i586/media/main/updates/media_info/synthesis<br />

.hdlist.cz<br />

--21:02:21-- ftp://ftp.isu.edu.tw/<strong>Linux</strong>/Mandriva<br />

圲 圱 /official/2007.0/i586/media/main/updates/media_info/synthesis<br />

.hdlist.cz<br />

=> ‘synthesis.hdlist.cz’<br />

圲 圳 Resolving ftp.isu.edu.tw... 140.127.177.17, 140.127.177.15<br />

Connecting to ftp.isu.edu.tw|140.127.177.17|:21... connected.<br />

圲 圵 Logging in as anonymous ... Logged in!<br />

De-Yu Wang CSIE CYUT 328


17.2. 檢 驗 軟 體 正 確 性 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

==> SYST ... done. ==> PWD ... done.<br />

圲 圷 ==> TYPE I ... done. ==> CWD /<strong>Linux</strong>/Mandriva/official<br />

/2007.0/i586/media/main/updates/media_info ... done.<br />

==> PASV ... done. ==> RETR synthesis.hdlist.cz ... done.<br />

圲 圹 Length: 156,870 (153K) (unauthoritative)<br />

圳 圱 100%[===============================================>]<br />

156,870 99.67K/s<br />

圳 圳 21:02:24 (99.44 KB/s) - ‘synthesis.hdlist.cz’ saved [156870]<br />

✡✝<br />

✆<br />

4. 讀 取 hdlist.cz 的 md5sum 檢 查 碼 :<br />

✞<br />

圱 [root@dywHome2 rpm]# cat MD5SUM<br />

374fca8ea858a7079c3717acca208e47 hdlist.cz<br />

圳 38b6616b9514707ff8dc344eadd5468f synthesis.hdlist.cz<br />

[root@dywHome2 rpm]# md5sum -b hdlist.cz<br />

圵 374fca8ea858a7079c3717acca208e47 *hdlist.cz<br />

[root@dywHome2 rpm]# md5sum -t hdlist.cz<br />

圷 374fca8ea858a7079c3717acca208e47<br />

✡✝<br />

hdlist.cz<br />

✆<br />

5. 檢 驗 md5sum 檔 案 指 紋 :<br />

✞<br />

圱 [root@dywHome2 rpm]# md5sum -c MD5SUM<br />

hdlist.cz: OK<br />

圳 synthesis.hdlist.cz: OK<br />

✡✝<br />

✆<br />

練 習 題<br />

1. 如 何 計 算 檔 案 file1 的 md5 指 紋 <br />

Sol. md5sum file1<br />

2. 如 何 計 算 檔 案 file1 的 md5 指 紋 , 並 存 成 file1.md5<br />

Sol. md5sum file1 >file1.md5<br />

3. 如 何 計 算 檔 案 file2 的 md5 指 紋 , 並 累 加 至 file1.md5<br />

Sol. md5sum file2 >>file1.md5<br />

4. 如 何 讀 取 檔 案 file1 的 md5 指 紋 <br />

Sol. md5sum file1<br />

5. 如 何 使 用 二 進 位 讀 檔 方 式 讀 取 檔 案 file1 的 md5 指 紋 <br />

Sol. md5sum -b file1<br />

De-Yu Wang CSIE CYUT 329


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

6. 如 何 使 用 文 字 型 態 讀 取 檔 案 file1 的 md5 指 紋 <br />

Sol. md5sum -t file1<br />

7. 如 何 檢 驗 檔 案 指 紋 檔 file.md5 中 檔 案 的 md5 指 紋 <br />

Sol. md5sum -c file.md5<br />

8. 檢 驗 檔 案 指 紋 檔 file.md5 中 檔 案 的 md5 指 紋 , 出 現 checksums did NOT<br />

match 訊 息 , 代 表 意 義 為 何 <br />

Sol. md5sum 檢 驗 , 發 現 檔 案 md5 指 紋 不 符 , 表 示 檔 案 被 更 動 過 。<br />

17.3 RPM 套 件 管 理 程 式<br />

• rpm 指 令<br />

1. 基 本 功 能 : 套 件 安 裝 、 升 級 、 更 新 、 移 除 、 查 詢 及 數 位 簽 章 驗 證 及 檢<br />

查 。<br />

✞<br />

圱 INSTALLING, UPGRADING, AND REMOVING PACKAGES:<br />

rpm {-i|--install} [install-options] PACKAGE_FILE ...<br />

圳 rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...<br />

rpm {-F|--freshen} [install-options] PACKAGE_FILE ...<br />

圵 rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts]<br />

[--notriggers] [--repackage] [--test] PACKAGE_NAME ...<br />

圷 QUERYING AND VERIFYING PACKAGES:<br />

rpm {-q|--query} [select-options] [query-options]<br />

圹 rpm {-V|--verify} [select-options] [verify-options]<br />

rpm --import PUBKEY ...<br />

圱 圱 rpm {-K|--checksig} [--nosignature] [--nodigest]<br />

PACKAGE_FILE ...<br />

✡✝<br />

✆<br />

2. 一 般 選 項 : 適 用 於 所 有 模 式<br />

✞<br />

-, --help : 列 出 輔 助 訊 息<br />

圲 --version : 列 出 rpm 版 本<br />

--quiet : 僅 列 出 錯 誤 訊 息<br />

圴 -v : 察 看 更 細 部 的 安 裝 資 訊<br />

-vv : 列 出 大 量 除 錯 訊 息<br />

圶 --pipe CMD : 將 rpm 的 輸 出 以 管 線 處 理 送 到 命 令 CMD<br />

✡✝<br />

✆<br />

• RPM 套 件 安 裝<br />

1. 安 裝 選 項 以 -i 開 頭<br />

✞<br />

rpm {-i|--install} [install-options] PACKAGE_FILE ...<br />

圲 install-:options<br />

De-Yu Wang CSIE CYUT 330


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

-h : 以 安 裝 資 訊 列 顯 示 安 裝 進 度<br />

圴 --: 不 要 去 檢 查 nodeps rpm 套 件 的 相 依 性 。<br />

--: 不 要 檢 查 nomd5 rpm 套 件 的 MD5 資 訊 。<br />

圶 --: 不 想 讓 該 套 件 自 行 啟 用 或 者 自 行 執 行 某 些 系 統 指 令 。noscripts<br />

圸<br />

--: 直 接 覆 蓋 已 存 在 的 檔 案 。replacefiles<br />

--: 重 新 安 裝 某 個 已 經 安 裝 過 的 套 件 。replacepkgs<br />

--:force--replacefiles 與 --replacepkgs 。<br />

圱 地 --: 測 試 套 件 是 否 可 以 被 安 裝 到 使 用 者 的 test <strong>Linux</strong> 環 境 當 中 。<br />

--prefix : 安 裝 到 新 目 錄 NEWPATH NEWPATH<br />

✡✝<br />

✆<br />

2. 安 裝 rp-pppoe-3.1-5.i386.rpm<br />

✞<br />

圱 [root@linux ~]# rpm -ivh rp-pppoe-3.1-5.i386.rpm<br />

Preparing... #######################################<br />

[100%]<br />

圳 1:rp-pppoe #######################################<br />

✡✝<br />

[100%]<br />

✆<br />

3. 一 次 安 裝 兩 個 以 上 的 套 件 :<br />

✞<br />

圱 [root@linux ~]# rpm -ivh a.i386.rpm b.i386.rpm *.rpm<br />

# 後 面 直 接 接 上 許 多 的 套 件 檔 案 。<br />

✡✝<br />

✆<br />

4. 直 接 由 網 路 http://ftp.isu.edu.tw 安 裝 套 件 logrotate:<br />

✞<br />

[root@dywHome2 ~]# rpm -ivh http://ftp.isu.edu.tw/pub/<strong>Linux</strong>/<br />

Mandriva\<br />

圲 >/official/2007.0/i586/media/main/release/logrotate-3.7.3-4<br />

mdk.i586.rpm<br />

✡✝<br />

✆<br />

5. 測 試 FlashPlayer 是 否 可 以 被 安 裝 在 目 前 作 業 環 境 :<br />

✞<br />

[root@dywHome2 ~]# rpm -ivh FlashPlayer-9.0.21.78-1.mdv2007<br />

.0.mde.i586.rpm --test<br />

圲 Preparing... #<br />

########################################## [100%]<br />

✡✝<br />

✆<br />

• RPM 套 件 升 級 與 更 新<br />

1. 升 級 選 項 以 -U 開 頭 , 更 新 選 項 以 -F 開 頭 :<br />

De-Yu Wang CSIE CYUT 331


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

✞<br />

rpm {-U|--upgrade} [install-options] PACKAGE_FILE ...<br />

圲 rpm {-F|--freshen} [install-options] PACKAGE_FILE ...<br />

install-:options 與 安 裝 相 同<br />

✡✝<br />

✆<br />

2. 升 級 更 新 與 安 裝 之 差 異 :<br />

(a) 升 級 後 所 有 舊 版 套 件 皆 被 移 除 ;<br />

(b) 若 舊 版 未 安 裝 , 則 無 法 更 新 , 即 套 件 不 會 被 安 裝 。<br />

3. 目 前 系 統 未 安 裝 套 件 baghira 情 況 下 , 以 選 項 -U 安 裝 :<br />

✞<br />

[root@dywOffice rpm]# rpm -Uvh baghira-0.7-2.2006mcnl.i586.<br />

rpm<br />

圲 Preparing... #<br />

########################################## [100%]<br />

1:baghira #<br />

########################################## [100%]<br />

✡✝<br />

✆<br />

4. 目 前 系 統 未 安 裝 套 件 baghira 情 況 下 , 以 選 項 -F 安 裝 舊 版 :<br />

✞<br />

圱 [root@dywOffice rpm]# rpm -Fvh baghira-0.7-2.2006mcnl.i586.<br />

rpm<br />

[root@dywOffice rpm]# rpm -Fvh baghira-0.7-0arn.20060mdk.i586<br />

.rpm<br />

✡✝<br />

✆<br />

5. 目 前 系 統 已 安 裝 套 件 baghira 情 況 下 , 以 選 項 -F 升 級 :<br />

✞<br />

[root@dywOffice rpm]# rpm -Fvh baghira-0.7-7arn.cvs20051211<br />

.20060mdk.i586.rpm<br />

圲 Preparing... #<br />

########################################## [100%]<br />

1:baghira #<br />

########################################## [100%]<br />

✡✝<br />

✆<br />

• RPM 套 件 移 除<br />

1. 移 除 選 項 :<br />

✞<br />

圱 rpm {-e|--erase} [--allmatches] [--nodeps] [--test]<br />

PACKAGE_NAME ...<br />

圳 --: 不 要 去 檢 查 nodeps rpm 套 件 的 相 依 性 。<br />

De-Yu Wang CSIE CYUT 332


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

--: 只 是 測 試 , 不 是 真 的 移 除 套 件 。 常 與 一 般 選 項 test -vv 一 起 使 用 來<br />

除 錯<br />

✡✝<br />

✆<br />

2. 測 試 是 否 可 移 除 mplayer:<br />

✞<br />

[root@dywHome2 rpm]# rpm -e mplayer --test<br />

圲 error: Failed dependencies:<br />

mplayer is needed by (installed) kplayer-0.5.3-5<br />

mdv2007.0.i586<br />

✡✝<br />

✆<br />

3. 測 試 不 要 檢 查 rpm 套 件 的 相 依 性 下 , 是 否 可 移 除 mplayer:<br />

✞<br />

圱 [root@dywHome2 rpm]# rpm -e mplayer --test --nodeps<br />

✡✝<br />

✆<br />

4. 移 除 套 件 baghira:<br />

✞<br />

圱 [root@dywHome2 rpm]# rpm -e baghira<br />

✡✝<br />

✆<br />

• RPM 查 詢 : 選 項 以 -q 開 頭 。<br />

1. 查 詢 已 安 裝 套 件 資 訊 的 選 項 :<br />

✞<br />

圱 [root@linux ~]# rpm -qa<br />

[root@linux ~]# rpm -q[licdR] 已 安 裝 的 套 件 名 稱<br />

圳 [root@linux ~]# rpm -qf 存 在 於 系 統 上 面 的 某 個 檔 案<br />

圵 -q : 僅 查 詢 , 後 面 接 的 套 件 名 稱 是 否 有 安 裝 ;<br />

-qa : 列 出 所 有 已 經 安 裝 在 本 機 <strong>Linux</strong> 系 統 上 面 的 套 件 名 稱 ;<br />

圷 -qi : 列 出 該 套 件 的 詳 細 資 訊 (information), 包 含 開 發 商 、 版 本 與 說<br />

明 等 ;<br />

-ql : 列 出 該 套 件 所 有 的 檔 案 與 目 錄 所 在 完 整 檔 名 (list);<br />

圹 -qc : 列 出 該 套 件 的 所 有 設 定 檔 僅 找 出 在 ( /etc/ 底 下 的 檔 名 )<br />

-qd : 列 出 該 套 件 的 所 有 說 明 檔 僅 找 出 與 ( man 有 關 的 檔 案 )<br />

圱 圱 -qR : 列 出 與 該 套 件 有 關 的 相 依 套 件 所 含 的 檔 案 (Required )<br />

-qf : 由 後 面 接 的 檔 案 名 稱 , 找 出 該 檔 案 屬 於 哪 一 個 已 安 裝 的 套 件 ;<br />

✡✝<br />

✆<br />

2. 查 詢 未 安 裝 套 件 資 訊 的 選 項 :<br />

✞<br />

[root@linux ~]# rpm -qp[licdR] 未 安 裝 的 某 個 檔 案 名 稱<br />

圲 -qp[icdlR: 後 面 接 的 所 有 參 數 以 上 面 的 說 明 一 致 。]<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 333


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

3. 找 出 是 否 有 安 裝 套 件 logrotate<br />

✞<br />

[root@linux ~]# rpm -q logrotate # 不 必 加 上 版 本 。<br />

圲 logrotate-3.7.1-10<br />

[root@linux ~]# rpm -q logrotating<br />

圴 package logrotating is not installed<br />

✡✝<br />

✆<br />

4. 列 出 套 件 logrotate 的 所 有 目 錄 與 檔 案 :<br />

✞<br />

[root@linux ~]# rpm -ql logrotate<br />

圲 /etc/cron.daily/logrotate<br />

/etc/logrotate.conf 以 下 省 略<br />

圴 ............<br />

✡✝<br />

✆<br />

5. 列 出 套 件 logrotate 的 相 關 說 明 資 料 :<br />

✞<br />

[root@linux ~]# rpm -qi logrotate<br />

圲 Name : logrotate Relocations: (not relocatable)<br />

Version : 3.7.1 Vendor: Red Hat, Inc.<br />

圴 Release : 10 Build Date: Fri Apr 1 03:54:42<br />

2005<br />

Install Date: Sat Jun 25 08:28:26 2005 Build Host: tweety.<br />

build.redhat.com<br />

圶 Group : 系 統 環 境 基<br />

礎 / Source RPM: logrotate-3.7.1-10.src.rpm<br />

Size : 47825 License: GPL<br />

圸 Signature : DSA/SHA1, Sat May 21 01:34:11 2005, Key ID<br />

b44269d04f2a6fd2<br />

Packager : Red Hat, Inc. <br />

圱 地 Summary : 循 環 、 壓 縮 、 移 除 以 及 郵 寄 系 統 紀 錄 檔 案 。<br />

Description :<br />

圱 圲 The logrotate utility is designed to simplify the<br />

administration of<br />

log files on a system which generates a lot of log files.<br />

Logrotate<br />

圱 圴 allows for the automatic rotation, compression, removal, and<br />

mailing of<br />

log files. Logrotate can be set to handle a log file daily,<br />

weekly,<br />

圱 圶 monthly, or when the log file gets to a certain size.<br />

Normally,<br />

logrotate runs as a daily cron job.<br />

✡✝<br />

✆<br />

6. 查 詢 mplayer 的 設 定 檔<br />

De-Yu Wang CSIE CYUT 334


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

✞<br />

圱 [root@dywHome2 ~]# rpm -qc mplayer<br />

/etc/mplayer/codecs.conf<br />

圳 /etc/mplayer/input.conf<br />

/etc/mplayer/menu.conf<br />

圵 /etc/mplayer/mplayer.conf<br />

✡✝<br />

✆<br />

7. 查 詢 mplayer 的 說 明 檔<br />

✞<br />

圱 [root@dywHome2 ~]# rpm -qd mplayer<br />

/usr/share/doc/mplayer-1.0/AUTHORS<br />

圳 /usr/share/doc/mplayer-1.0/ChangeLog<br />

/usr/share/doc/mplayer-1.0/Copyright<br />

圵 /usr/share/doc/mplayer-1.0/HTML/cs/advaudio.html<br />

/usr/share/doc/mplayer-1.0/HTML/cs/aspect.html<br />

圷 /usr/share/doc/mplayer-1.0/HTML/cs/audio-codecs.html<br />

/usr/share/doc/mplayer-1.0/HTML/cs/audio-formats.html 以 下 省 略<br />

圹 --------<br />

✡✝<br />

✆<br />

8. 查 詢 logrotate 相 依 套 件<br />

✞<br />

圱 [root@linux ~]# rpm -qR logrotate<br />

/bin/sh<br />

圳 config(logrotate) = 3.7.1-10<br />

libc.so.6 以 下 省 略<br />

圵 --------<br />

✡✝<br />

✆<br />

9. 查 詢 /bin/sh 是 由 那 個 套 件 提 供 <br />

✞<br />

圱 [root@linux ~]# rpm -qf /bin/sh<br />

bash-3.0-31<br />

圳 # 參 數 後 面 接 的 是 『 檔 案 』, 不 是 接 套 件 。<br />

✡✝<br />

✆<br />

10. 查 詢 套 件 kplayer ( 未 安 裝 ) 之 相 依 套 件 <br />

✞<br />

圱 [root@dywHome2 rpm]# rpm -qpR kplayer-0.5.3-5mdv2007.0.i586.<br />

rpm<br />

mplayer<br />

圳 kdelibs-common<br />

/bin/sh<br />

圵 /bin/sh<br />

rpmlib(PayloadFilesHavePrefix)


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

libDCOP.so.4<br />

圹 libICE.so.6 以 下 省 略<br />

--------<br />

✡✝<br />

✆<br />

11. 查 詢 套 件 logrotate 設 定 檔<br />

✞<br />

[root@dywHome2 ~]# rpm -qc logrotate<br />

圲 /etc/logrotate.conf<br />

/etc/logrotate.d/syslog<br />

✡✝<br />

✆<br />

12. 若 查 出 logrotate 的 設 定 檔 案 已 被 改 過 , 而 要 從 網 路 直 接 重 新 安 裝 ,<br />

該 如 何 作 <br />

✞<br />

圱 [root@dywHome2 ~]# rpm -ivh http://ftp.isu.edu.tw/pub/<strong>Linux</strong>/<br />

Mandriva\<br />

>/official/2007.0/i586/media/main/release/logrotate-3.7.3-4<br />

mdk.i586.rpm\<br />

圳 > --replacepkgs<br />

✡✝<br />

✆<br />

13. 如 果 誤 刪 /etc/crontab, 如 何 查 詢 它 屬 於 那 個 套 件 , 以 重 新 安 裝 <br />

✞<br />

圱 # 雖 然 檔 案 /etc/crontab 已 不 存 在 , 但 /var/lib/rpm 資 料 庫 中 有 記<br />

錄 :<br />

[root@dywHome2 ~]# rpm -qf /etc/crontab<br />

圳 crontabs-1.10-6mdk<br />

✡✝<br />

✆<br />

14. 查 詢 系 統 中 含 player 字 串 的 套 件 <br />

✞<br />

圱 [root@dywHome2 rpm]# rpm -qa | grep player<br />

mplayer-1.0-1.pre8.13.2mdv2007.0<br />

圳 kplayer-0.5.3-5mdv2007.0<br />

✡✝<br />

✆<br />

15. 如 何 知 道 系 統 中 以 c 開 頭 的 套 件 有 幾 個 <br />

✞<br />

圱 [root@dywHome2 rpm]# rpm -qa | grep ^c | wc -l<br />

15<br />

✡✝<br />

✆<br />

• RPM 驗 證<br />

De-Yu Wang CSIE CYUT 336


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

1. 驗 證 使 用 時 機 :<br />

(a) 當 資 料 不 小 心 遺 失 ;<br />

(b) 誤 殺 了 某 個 套 件 的 檔 案 ;<br />

(c) 不 知 道 修 改 到 某 一 個 套 件 的 檔 案 內 容 。<br />

2. 驗 證 方 法 :<br />

(a) rpm 套 件 安 裝 相 關 訊 息 存 在 /var/lib/rpm 資 料 庫 ;<br />

(b) 比 對 目 前 <strong>Linux</strong> 系 統 環 境 與 /var/lib/rpm 資 料 庫 。<br />

3. rpm 驗 證 : 選 項 以 -V 開 頭 。<br />

✞<br />

[root@linux ~]# rpm -Va<br />

圲 [root@linux ~]# rpm -V 已 安 裝 的 套 件 名 稱<br />

[root@linux ~]# rpm -Vp 某 rpm 套 件 名 稱<br />

圴 [root@linux ~]# rpm -Vf 在 系 統 上 面 的 某 個 檔 案 選 項 :<br />

圶 -V : 後 接 套 件 名 稱 , 若 該 套 件 所 含 的 檔 案 被 更 動 過 , 才 會 列 出 來 ;<br />

-Va : 列 出 目 前 系 統 上 面 所 有 可 能 被 更 動 過 的 檔 案 ;<br />

圸 -Vp : 後 接 套 件 名 稱 , 列 出 該 套 件 內 可 能 被 更 動 過 的 檔 案 ;<br />

-Vf : 列 出 某 個 檔 案 是 否 被 更 動 過 。<br />

✡✝<br />

✆<br />

4. 列 出 <strong>Linux</strong> 內 的 套 件 logrotate 是 否 被 更 動 過 <br />

✞<br />

圱 [root@dywHome2 rpm]# rpm -V logrotate<br />

.M...... d /usr/share/man/man8/logrotate.8.bz2<br />

✡✝<br />

✆<br />

5. 查 詢 /etc/crontab 是 否 被 更 動 過 <br />

✞<br />

[root@dywHome2 rpm]# rpm -Vf /etc/crontab<br />

圲 .......T c /etc/crontab<br />

✡✝<br />

✆<br />

6. 查 詢 kplayer-0.5.3-5mdv2007.0.i586.rpm 內 被 更 動 過 的 檔 案 <br />

✞<br />

[root@dywHome2 rpm]# rpm -Vp kplayer-0.5.3-5mdv2007.0.i586.<br />

rpm<br />

圲 S.5....T /usr/bin/kplayer<br />

✡✝<br />

✆<br />

7. 查 詢 結 果 第 一 項 資 訊 說 明 :<br />

圲<br />

✞<br />

S :file Size differs 檔 案 的 容 量 大 小 被 改 變<br />

De-Yu Wang CSIE CYUT 337


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

圴<br />

圶<br />

圸<br />

圱 地<br />

圱 圲<br />

圱 圴<br />

圱 圶<br />

M :Mode differs (includes permissions and file type) 檔 案 的 類<br />

型 或 檔 案 的 屬 性 讀 寫 執 行<br />

(//) 已 被 改 變<br />

5 :MD5 sum differs<br />

MD5 加 密 防 駭 的 屬 性 已 被 改 變<br />

D :Device major/minor number mis-match 裝 置 名 稱 已 被 改 變<br />

L :readLink(2) path mis-match<br />

Link 屬 性 已 被 改 變<br />

U :User ownership differs 檔 案 的 所 屬 人 已 被 改 變<br />

G :Group ownership differs 檔 案 的 所 屬 群 組 已 被 改 變<br />

T :mTime differs 檔 案 的 建 立 時 間 已 被 改 變<br />

圱 圸 # 當 檔 案 所 有 的 資 訊 都 被 更 動 過 會 顯 :<br />

SM5DLUGT c filename<br />

✡✝<br />

✆<br />

8. 查 詢 結 果 第 二 項 資 訊 說 明 :<br />

✞<br />

圱 c : 設 定 檔 (config file)<br />

d : 文 件 資 料 檔 (documentation)<br />

圳 g : 鬼 檔 案 ~ 通 常 是 該 檔 案 不 被 某 個 套 件 所 包 含 , 較 少 發<br />

生 。(ghost file)<br />

l : 授 權 檔 案 (license file)<br />

圵 r : 讀 我 檔 案 (read me)<br />

✡✝<br />

✆<br />

• RPM 數 位 簽 章<br />

1. RPM 也 可 利 用 數 位 簽 證 來 判 斷 待 安 裝 的 套 件 檔 案 是 否 有 問 題 。<br />

2. 一 般 使 用 的 是 GPG 的 金 鑰 ( public key )。<br />

3. 應 用 方 法 :<br />

(a) 欲 使 用 某 distribution 釋 出 的 套 件 時 , 需 將 其 釋 出 的 GPG 金 鑰<br />

安 裝 在 自 己 的 <strong>Linux</strong> 系 統 上 。<br />

(b) 當 安 裝 該 distribution 釋 出 的 套 件 時 , 就 會 檢 查 兩 者 的 key 是<br />

否 相 同 : 如 果 相 同 就 直 接 安 裝 ; 否 則 顯 示 未 安 裝 GPG 金 鑰 訊 息 。<br />

4. 使 用 網 路 安 裝 金 鑰 套 件 gnupg-1.4.5-1mdv2007.0:<br />

✞<br />

圱 [root@dywHome2 ~]# rpm -ivh http://ftp.isu.edu.tw/pub/<strong>Linux</strong>/<br />

Mandriva\<br />

>/official/2007.0/i586/media/main/release/gnupg-1.4.5-1<br />

mdv2007.0<br />

✡✝<br />

✆<br />

De-Yu Wang CSIE CYUT 338


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

5. 查 詢 金 鑰 檔 案 及 其 設 定 檔 :<br />

✞<br />

[root@dywHome2 ~]# find /etc /usr -name RPM-GPG-KEY*<br />

圲 /etc/RPM-GPG-KEYS<br />

/usr/share/doc/rpm-4.4.6/RPM-GPG-KEY<br />

✡✝<br />

✆<br />

6. 匯 入 金 鑰 :<br />

✞<br />

圱 [root@dywHome2 ~]# rpm --import /usr/share/doc/rpm-4.4.6/RPM-<br />

GPG-KEY<br />

✡✝<br />

✆<br />

7. 查 詢 所 有 金 鑰 :<br />

✞<br />

圱 [root@dywHome2 ~]# rpm -qa gpg-pubkey*<br />

gpg-pubkey-78d019f5-3fd7504d<br />

圳 gpg-pubkey-db42a60e-37ea5438<br />

gpg-pubkey-22458a98-3969e7de<br />

圵 gpg-pubkey-70771ff3-3c8f768f<br />

✡✝<br />

✆<br />

8. 查 詢 金 鑰 內 容 :<br />

✞<br />

圱 [root@dywHome2 ~]# rpm -qi gpg-pubkey-78d019f5-3fd7504d<br />

Name : gpg-pubkey Relocations: (not<br />

relocatable)<br />

圳 Version : 78d019f5 Vendor: (none<br />

)<br />

Release : 3fd7504d Build Date: Fri<br />

28 Dec 2007 08:15:11 AM EST<br />

圵 Install Date: Fri 28 Dec 2007 08:15:11 AM EST Build Host<br />

: localhost<br />

Group : Public Keys Source RPM: (none<br />

)<br />

圷 Size : 0 License:<br />

pubkey<br />

Signature : (none)<br />

圹 Summary : gpg(MandrakeContrib )<br />

Description :<br />

圱 圱 -----BEGIN PGP PUBLIC KEY BLOCK-----<br />

Version: rpm-4.4.6 (beecrypt-4.1.2)<br />

圱 圳<br />

mQGiBD/XUE0RBAC/sGlzkZ7WofaPgL2A7Vmi4aMLF9xNkIUzeekk2kxnZ+3<br />

P277i2wckvIox<br />

圱 圵 gGl13OvqWUf6+20jBPWrOGz6hs+MUve7k+A7sgmg3n2P6fa999nxWTK+7<br />

m7705x+2qXb+dxF 中 間 省<br />

略<br />

De-Yu Wang CSIE CYUT 339


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

--------<br />

圱 圷 41trJiEWiEkEGBECAAkFAj/XUE4CGwwACgkQRFk1+<br />

HjQGfWi6wCeJPiCFBej0nfnBfaOWh98<br />

aNq3XfUAoKIfvhoiijsRwjSNmygJtZbiKOWC<br />

圱 圹 =yJ39<br />

-----END PGP PUBLIC KEY BLOCK-----<br />

✡✝<br />

✆<br />

9. 安 裝 Fedora 7 rpm 套 件 baghira:<br />

✞<br />

[root@dywHome2 rpm]# rpm -ivh baghira-0.8-1.fc6.i386.rpm<br />

圲 warning: baghira-0.8-1.fc6.i386.rpm: Header V3 DSA signature:<br />

NOKEY,<br />

key ID ff6382fa error: Failed dependencies:<br />

圴<br />

rtld(GNU_HASH) is needed by baghira-0.8-1.fc6.i386<br />

✡✝<br />

✆<br />

10. 移 除 金 鑰 :<br />

✞<br />

[root@dywHome2 ~]# rpm -e gpg-pubkey-78d019f5-3fd7504d<br />

✡✝<br />

✆<br />

11. 再 查 詢 所 有 金 鑰 :<br />

✞<br />

圱 [root@dywHome2 ~]# rpm -qa gpg-pubkey*<br />

gpg-pubkey-db42a60e-37ea5438<br />

圳 gpg-pubkey-22458a98-3969e7de<br />

gpg-pubkey-70771ff3-3c8f768f<br />

✡✝<br />

✆<br />

• RPM 資 料 庫 初 始 與 重 建 :<br />

1. 選 項<br />

✞<br />

rpm {--initdb|--rebuilddb} [-v]<br />

圲 --initdb : 產 生 一 個 新 的 資 料 庫<br />

--rebuilddb : 重 已 安 裝 套 件 標 頭 (headers) 重 建 資 料 庫<br />

✡✝<br />

✆<br />

2. 產 生 一 個 新 的 資 料 庫<br />

✞<br />

圱 [root@dywHome2 ~]# rpm --initdb -v<br />

✡✝<br />

✆<br />

3. 重 建 資 料 庫<br />

De-Yu Wang CSIE CYUT 340


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

✞<br />

圱 [root@dywHome2 ~]# rpm --rebuilddb -v<br />

✡✝<br />

✆<br />

練 習 題<br />

1. rpm 指 令 執 行 時 , 若 要 察 看 細 部 的 安 裝 資 訊 , 要 使 用 什 麼 選 項 <br />

Sol. -v<br />

2. rpm 指 令 執 行 時 , 若 僅 列 出 錯 誤 訊 息 , 要 使 用 什 麼 選 項 <br />

Sol. --quiet<br />

3. rpm 指 令 執 行 時 , 若 要 列 出 大 量 除 錯 訊 息 , 要 使 用 什 麼 選 項 <br />

Sol. -vv<br />

4. rpm 指 令 執 行 安 裝 時 , 要 以 什 麼 選 項 做 為 開 頭 <br />

Sol. -i<br />

5. 如 何 以 rpm 指 令 安 裝 套 件 a.i586.rpm, 並 以 安 裝 資 訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm<br />

6. 如 何 以 rpm 指 令 同 時 安 裝 套 件 a.i586.rpm 與 b.i586.rpm, 並 以 安 裝 資 訊<br />

列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm b.i586.rpm<br />

7. 如 何 以 rpm 指 令 安 裝 網 路 套 件 http://ftp.isu.edu.tw/a.i586.rpm 與<br />

b.i586.rpm, 並 以 安 裝 資 訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh http://ftp.isu.edu.tw/a.i586.rpm<br />

8. 如 何 以 rpm 指 令 測 試 套 件 a.i586.rpm 是 否 可 以 被 安 裝 到 目 前 的 環 境 , 並<br />

以 安 裝 資 訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm --test<br />

9. 如 何 以 rpm 指 令 , 不 檢 查 rpm 套 件 的 相 依 性 下 , 安 裝 套 件 a.i586.rpm,<br />

並 以 安 裝 資 訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm --nodeps<br />

10. 如 何 以 rpm 指 令 , 不 檢 查 rpm 套 件 的 MD5 資 訊 下 , 安 裝 套 件<br />

a.i586.rpm, 並 以 安 裝 資 訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm --nomd5<br />

11. 如 何 以 rpm 指 令 , 直 接 覆 蓋 已 存 在 的 檔 案 方 式 , 安 裝 套 件 a.i586.rpm, 並<br />

以 安 裝 資 訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm --replacefiles<br />

12. 如 何 以 rpm 指 令 , 重 新 安 裝 已 安 裝 套 件 方 式 , 安 裝 套 件 a.i586.rpm, 並 以<br />

安 裝 資 訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm --replacepkgs<br />

De-Yu Wang CSIE CYUT 341


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

13. 如 何 以 rpm 指 令 , 重 新 安 裝 已 安 裝 套 件 且 直 接 覆 蓋 已 存 在 檔 案 的 方 式 , 安 裝<br />

套 件 a.i586.rpm, 並 以 安 裝 資 訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm --force<br />

14. 如 何 以 rpm 指 令 , 安 裝 套 件 a.i586.rpm 至 目 錄 /usr/local, 並 以 安 裝 資<br />

訊 列 顯 示 安 裝 進 度 <br />

Sol. rpm -ivh a.i586.rpm --prefix /usr/nomd5<br />

15. rpm 指 令 執 行 套 件 升 級 時 , 要 以 什 麼 選 項 做 為 開 頭 <br />

Sol. -U<br />

16. rpm 指 令 執 行 套 件 更 新 時 , 要 以 什 麼 選 項 做 為 開 頭 <br />

Sol. -F<br />

17. rpm 指 令 升 級 與 安 裝 之 差 異 為 何 <br />

Sol. 升 級 後 所 有 舊 版 套 件 皆 被 移 除 。<br />

18. rpm 指 令 更 新 與 安 裝 之 差 異 為 何 <br />

Sol. 若 舊 版 未 安 裝 , 則 無 法 更 新 , 即 套 件 不 會 被 安 裝 。<br />

19. 若 系 統 未 安 裝 套 件 a.i586.rpm, 則 可 以 那 兩 種 方 式 ( 再 ) 安 裝 <br />

Sol. rpm -ivh a.i586.rpm 或 rpm -Uvh a.i586.rpm<br />

20. 若 系 統 已 安 裝 套 件 a.i586.rpm, 則 可 以 那 三 種 方 式 ( 再 ) 安 裝 <br />

Sol. rpm -ivh a.i586.rpm 或 rpm -Uvh a.i586.rpm 或 rpm -Fvh<br />

a.i586.rpm<br />

21. 若 系 統 未 安 裝 套 件 a.i586.rpm, 則 執 行 rpm -Fvh a.i586.rpm, 出 現 什 麼<br />

狀 況 <br />

Sol. 無 法 安 裝 , 沒 有 任 何 訊 息 顯 示 。<br />

22. rpm 指 令 執 行 套 件 移 除 時 , 要 以 什 麼 選 項 做 為 開 頭 <br />

Sol. -e<br />

23. 如 何 以 rpm 指 令 移 除 套 件 baghira<br />

Sol. rpm -e baghira<br />

24. 如 何 以 rpm 指 令 同 時 移 除 套 件 mplayer 與 baghira<br />

Sol. rpm -e mplayer baghira<br />

25. 如 何 以 rpm 指 令 測 試 是 否 可 以 移 除 套 件 mplayer<br />

Sol. rpm -e mplayer --test<br />

26. 如 何 以 rpm 指 令 測 試 不 要 檢 查 rpm 套 件 的 相 依 性 下 , 是 否 可 移 除 套 件<br />

mplayer<br />

Sol. rpm -e mplayer --test --nodeps<br />

27. rpm 指 令 執 行 套 件 查 詢 時 , 要 以 什 麼 選 項 做 為 開 頭 <br />

Sol. -q<br />

De-Yu Wang CSIE CYUT 342


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

28. 如 何 以 rpm 指 令 查 詢 套 件 mplayer 是 否 安 裝 <br />

Sol. rpm -q mplayer<br />

29. 如 何 以 rpm 指 令 查 詢 套 件 mplayer 的 所 有 目 錄 與 檔 案 <br />

Sol. rpm -ql mplayer<br />

30. 如 何 以 rpm 指 令 查 詢 套 件 mplayer 的 相 關 說 明 資 料 <br />

Sol. rpm -qi mplayer<br />

31. 如 何 以 rpm 指 令 查 詢 套 件 mplayer 的 設 定 檔 <br />

Sol. rpm -qc mplayer<br />

32. 如 何 以 rpm 指 令 查 詢 套 件 mplayer 的 說 明 檔 <br />

Sol. rpm -qd mplayer<br />

33. 如 何 以 rpm 指 令 查 詢 套 件 mplayer 的 相 依 套 件 <br />

Sol. rpm -qR mplayer<br />

34. 如 何 以 rpm 指 令 查 詢 檔 案 /bin/sh 是 由 那 個 套 件 提 供 <br />

Sol. rpm -qf /bin/sh<br />

35. 如 何 以 rpm 指 令 查 詢 未 安 裝 套 件 kplayer-0.5.3-5mdv2007.0.rpm 的 相 依<br />

套 件 <br />

Sol. rpm -pqR kplayer-0.5.3-5mdv2007.0.rpm<br />

36. 如 果 誤 刪 /etc/crontab, 如 何 以 rpm 指 令 查 詢 它 屬 於 那 個 套 件 , 以 重 新 安<br />

裝 <br />

Sol. rpm -qf /etc/crontab<br />

37. 如 何 以 rpm 指 令 查 詢 系 統 中 含 player 字 串 的 套 件 <br />

Sol. rpm -qa | grep "player"<br />

38. 如 何 以 rpm 指 令 知 道 系 統 中 以 c 開 頭 的 套 件 有 幾 個 <br />

Sol. rpm -qa | grep ^c | wc -l<br />

39. 請 說 明 RPM 驗 證 使 用 時 機 。<br />

Sol. 1. 當 資 料 不 小 心 遺 失 ;2. 誤 殺 了 某 個 套 件 的 檔 案 ;3. 不 知 道 修 改 到 某<br />

一 個 套 件 的 檔 案 內 容 。<br />

40. RPM 套 件 安 裝 相 關 訊 息 資 料 庫 在 那 個 目 錄 <br />

Sol. /var/lib/rpm<br />

41. RPM 驗 證 , 主 要 是 將 目 前 <strong>Linux</strong> 系 統 環 境 與 什 麼 資 料 庫 比 對 <br />

Sol. /var/lib/rpm 資 料 庫<br />

42. rpm 指 令 執 行 套 件 驗 證 時 , 要 以 什 麼 選 項 做 為 開 頭 <br />

Sol. -V<br />

43. 如 何 以 rpm 指 令 驗 證 套 件 logrotate 是 否 被 更 動 過 <br />

Sol. rpm -V logrotate<br />

De-Yu Wang CSIE CYUT 343


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

44. 如 何 以 rpm 指 令 驗 證 檔 案 /etc/crontab 是 否 被 更 動 過 <br />

Sol. rpm -Vf /etc/crontab<br />

45. 如 何 以 rpm 指 令 查 詢 kplayer-0.5.3-5mdv2007.0.i586.rpm 內 被 更 動 過 的<br />

檔 案 <br />

Sol. rpm -Vp kplayer-0.5.3-5mdv2007.0.i586.rpm<br />

46. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 一 項 SM5DLUGT 中 S 代 表 意 義 為<br />

何 <br />

Sol. 檔 案 的 容 量 大 小 被 改 變<br />

47. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 一 項 SM5DLUGT 中 M 代 表 意 義 為<br />

何 <br />

Sol. 檔 案 的 類 型 或 檔 案 的 屬 性 ( 讀 / 寫 / 執 行 ) 已 被 改 變<br />

48. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 一 項 SM5DLUGT 中 5 代 表 意 義 為<br />

何 <br />

Sol. MD5 加 密 防 駭 的 屬 性 已 被 改 變<br />

49. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 一 項 SM5DLUGT 中 D 代 表 意 義 為<br />

何 <br />

Sol. 裝 置 名 稱 已 被 改 變<br />

50. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 一 項 SM5DLUGT 中 L 代 表 意 義 為<br />

何 <br />

Sol. Link 屬 性 已 被 改 變<br />

51. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 一 項 SM5DLUGT 中 U 代 表 意 義 為<br />

何 <br />

Sol. 檔 案 的 所 屬 人 已 被 改 變<br />

52. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 一 項 SM5DLUGT 中 G 代 表 意 義 為<br />

何 <br />

Sol. 檔 案 的 所 屬 群 組 已 被 改 變<br />

53. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 一 項 SM5DLUGT 中 T 代 表 意 義 為<br />

何 <br />

Sol. 檔 案 的 建 立 時 間 已 被 改 變<br />

54. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 二 項 出 現 c 代 表 檔 案 類 型 為 何 <br />

Sol. 設 定 檔 (config file)<br />

55. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 二 項 出 現 d 代 表 檔 案 類 型 為 何 <br />

Sol. 文 件 資 料 檔 (documentation)<br />

56. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 二 項 出 現 g 代 表 檔 案 類 型 為 何 <br />

Sol. 鬼 檔 案 (ghost file)<br />

De-Yu Wang CSIE CYUT 344


17.3. RPM 套 件 管 理 程 式 CHAPTER 17. * 套 件 修 補 、 檢 驗 與 管 理<br />

57. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 二 項 出 現 l 代 表 檔 案 類 型 為 何 <br />

Sol. 授 權 檔 案 (license file)<br />

58. 若 以 rpm 指 令 驗 證 某 套 件 , 驗 證 資 訊 第 二 項 出 現 r 代 表 檔 案 類 型 為 何 <br />

Sol. 讀 我 檔 案 (read me)<br />

59. RPM 數 位 簽 章 用 途 為 何 <br />

Sol. RPM 利 用 數 位 簽 證 來 判 斷 待 安 裝 的 套 件 檔 案 是 否 有 問 題 。<br />

60. 若 要 使 RPM 數 位 簽 章 , 必 須 安 裝 那 個 套 件 <br />

Sol. gnupg<br />

61. RPM 數 位 簽 章 金 鑰 檔 案 為 何 <br />

Sol. RPM-GPG-KEY<br />

62. 若 RPM 數 位 簽 章 金 鑰 檔 案 為 RPM-GPG-KEY, 如 何 將 其 匯 入 <br />

Sol. rpm --import RPM-GPG-KEY<br />

63. 若 已 安 裝 RPM 數 位 簽 章 在 目 前 的 mandriva 系 統 , 現 安 裝 Fedora 7 之<br />

rpm 套 件 , 會 出 現 什 麼 問 題 <br />

Sol. 沒 有 簽 章 金 鑰 , 故 無 法 安 裝 。<br />

64. 如 何 移 除 RPM 數 位 簽 章 金 鑰 gpg-pubkey<br />

Sol. rpm -e gpg-pubkey<br />

65. 如 何 產 生 一 個 新 的 RPM 資 料 庫 <br />

Sol. rpm --initdb<br />

66. 如 何 重 建 RPM 資 料 庫 <br />

Sol. rpm --rebuilddb<br />

De-Yu Wang CSIE CYUT 345

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!