---
# System prepended metadata

title: Unix筆記

---

# Unix筆記

## Ch1. Introduction

### What is an operating system?
* 公平
* 多工
* 開源
* 軟硬兼施

**AUI** (application user interface) : The AUI is glued to the operating system kernel via the language libraries and the system call interface.

![](https://i.imgur.com/PuW6I19.png)

![](https://i.imgur.com/a4yc267.png)

*  Device Driver Layer: 硬體控制層，執行檔案可以translate給其他硬體。
*  UNIX Kernel: UNIX核心，負責管理電腦內的所有程序，擁有actual operating system。
   - File management : 檔案管理器，對檔案做移動、建立、移除，掌管檔案存取權限。
   - Primary and secondary storage management : 劃分儲存位置。
   - Pipe: 可以在一台電腦上同時執行多個程序
   - IPC : 讓兩個執行緒傳輸訊號的方法，client-server-based。
   - Process management : 決定誰先誰後。
   - BSD socket : 允許兩個或多個process在一個network裡 communicate。
   - CPU scheduler : 決定記憶體要給誰。
   - Disk Management: 分配檔案在硬碟中所佔的空間
* System call interface : 叫kernel去做事。
* UNIX shell : 使用者和電腦的互動介面。
* Language Libraries: 程式語言函示庫，例如: C/C++/Java…

### Top-down v.s Bottom-up

* Top down : 當你在執行東西時你不用去考慮過多東西，例如:位址、記憶體、結構等等...，只需下簡單的指令。
* Bottom up : 作業系統分成很多資源可讓你調用，而且很公平、有順序、很安全地。

### 作業系統的好功用(讚讚)

![](https://i.imgur.com/n8F60Ib.png)

### Character user interface v.s Graphical user interfaces

* 命令列介面: character user interface (CUI) == command line interface (CLI) ，利用指令傳送操作給作業系統。
* 圖形使用者介面: Graphical user interface (GUI)，有圖形化的東西讓你操作(ex: Windows)。

## Ch2. Quick Start

### Begin

```shell=
$command [[-]option(s)][option argument(s)][command argument(s)]
```
* $ : 代表 shell。
* command : 你準備輸入的指令。
* [-option(s)] : 可增加的參數 (ex: -l, -a)。
* [option argument(s)] : 參數的參數 (x。
* [command argument(s)] : 你的command要對誰下手。

在UNIX裡面，檔案的架構就像一棵樹。

![](https://i.imgur.com/jOjAkVV.png)

第一次登入時，你會出現在家目錄(home directory)。

**myfile2** 的路徑會在 ```/usr1.b/bobk/myfile2```

所有路徑的起點都會在根目錄(/)。

### cat 建立檔案 / 查看檔案內容

![](https://i.imgur.com/s5BoeFS.png)

-A  ：相當於 -vET 的整合選項，可列出一些特殊字符而不是空白而已。
-b  ：**列出行號**，僅針對**非空白**行做行號顯示，空白行不標行號！
-E  ：將結尾的斷行字元 $ 顯示出來。
-n  ：列**印出行號**，連同**空白行**也會有行號，與 -b 的選項不同。
-T  ：將 [tab] 按鍵以 ^I 顯示出來。
-v  ：列出一些看不出來的特殊字符。

```shell=
cat > myfile
hello world
<Ctrl + D> //這是停止繼續輸入，並建立檔案的意思。
```

建立叫 "myfile" 的檔案，並輸入 "hello world"。

```shell=
cat myfile

//輸出 : hello world
```

把 "myfile" 的檔案內容顯示出來。

### more 檢視檔案內容

![](https://i.imgur.com/jJJd6u0.png)

```shell=
more myfile

//輸出 : hello world  
```

若要輸出的東西已經大於 Terminal 的篇幅了，則下面會顯示百分比，代表目前顯示了多少。

若要換行則按 ```<space>```，要換頁按```<Enter>```，要結束則按 ```<Q>```。

### cp 複製檔案

![](https://i.imgur.com/qFKk6YP.png)

EX : 假設我要copy myfile1 的 內容到 myfile2，則 : 

```shell=
cp myfile1 myfile2
```

若要複製到某位置(ex:/usr/bin)的話，則 : 

```shell=
cp myfile1 /usr/bin
```

就會看到在 ```/usr/bin``` 的地方出現 myfile1。

### mv 移動文件

![](https://i.imgur.com/ZDvbgC9.png)

第一個 argument 是 sourse file，第二個 argument 是 destination。

```shell=
mv myfile1 myfile
```

這樣就能達到改名的作用，額外一題，其實也可以搭配絕對路徑。
Ex:
```shell=
mv /usr/bin/myfile1 /tmp/myfile
```

檔名最好不要有空白，若要有空白則要加上 ""。
Ex:
```shell=
mv myfile1 "This is new file"

//則檔案名稱就變成 "This is new file"。
```

### rm 刪除檔案

![](https://i.imgur.com/lwZjrCL.png)

因為UNIX裡面沒有「資源回收桶」，所以一旦刪除了就很麻煩。

```shell=
rm file
```

刪除 "file" 檔案。

刪除裡面有東西的資料夾務必使用 ```rm -r dicname```

不過因為 ```rm``` 牽涉到非常多權限問題，之後會再補充。

### ls 列出檔案

![](https://i.imgur.com/36TPan0.png)

```ls``` 會列出你所在目錄下的檔案。

* -a : 把「全部」的檔案列出來，包含隱藏檔(.開頭的檔案)。
* -d : 僅列出目錄本身(.)，而不是列出目錄內的檔案。
* -F : 在名字後面顯示符號，代表屬性，例如 : ```*```->二進位執行檔，```/``` -> 資料夾，```@```代表符號連結。
* -i : 列出 inode 的號碼。
* -l : 長資料串列出，包含檔案的屬性與權限等等資料。

Ex:

```shell=
ls -la
```
![](https://i.imgur.com/L8l3U06.png)

印出所有檔案的詳細資料。

共有八個欄位 : 
1. 第一個欄位代表資料屬性，```d```:目錄，```l```:symbol link，```-```:檔案，其他由 ```r,w,x,-```組成則代表檔案存取權限。
2.  儲存位置(硬碟)的編號。
3.  擁有者的名字。
4.  群組名稱。
5.  檔案大小。
6.  檔案建立日期。
7.  檔案名稱。

```shell=
ls -la 檔案名
```

則會列出單一檔案的許多資訊。

假設要找出某個特定開頭的檔案，可以 ```ls``` 搭配特定開頭加星號。

```shell=
ls my*
```
可以找到 ```myfile```, ```myfile1```。

**星號**有替代任何東西的功能。


### mkdir 創建資料夾

![](https://i.imgur.com/qhKo8IL.png)

```shell=
mkdir dict
```

創建叫做 "dict" 的目錄(資料夾)，若沒特別指出路徑則代表在當前目錄下創建。

* -p 確保目錄名稱存在，不存在就創一個。

### rmdir 刪除資料夾

![](https://i.imgur.com/xyNFMdb.png)

```shell=
rmdir dict
```

把叫作 "dict" 的資料夾給刪了。

跟上面一樣，如果要把不為空的資料夾刪了記得要加 ```-r```。

### cd 更改路徑

在UNIX下最常使用的指令。

* cd 絕對路徑。ex: ```cd /usr/bin```
* cd 相對路徑。ex: 在usr目錄下 ```cd bin```

```shell=
cd dict
```

移動到 dict 目錄裡面。

```shell=
cd ..
```

回到目錄上一層。

```shell=
cd ~
```

回到家目錄。

```shell=
cd /
```

回到根目錄。

### pwd 當前路徑

![](https://i.imgur.com/xy6oSFi.png)


```pwd```指令會顯示你當前所在路徑(絕對路徑)。


### man 查詢指令的功能

很讚的指令，考試不會可以拿來查。

![](https://i.imgur.com/7M65ApS.png)

Ex:

![](https://i.imgur.com/NADT1xR.png)


顯示 ls 指令的說明文件，想換下一頁按 <space> ，結束按 <Q>。
    
### whatis 查詢指令的功能
    
![](https://i.imgur.com/BHrvTAO.png)

```man``` 的精簡版。
    
### whereis 找尋檔案路徑

![](https://i.imgur.com/qmtDi9h.png)

Ex:
```shell=
whereis data
```

就能找出 ```data``` 這個檔案在哪裡(絕對路徑)。
如果不同目錄底下有很多 ```data```，則會列出很多行。
    
### whoami 查詢使用者名稱

![](https://i.imgur.com/1NF4U87.png)

**who**: 印出所有使用者名稱。
**hostname**: 印出使用者名稱及裝置

Hint : Use the ```hostname``` command to find out what host computer you are logged on to.
    

### lpr 列印(for PC-BSD)

![](https://i.imgur.com/ioEgKPT.png)

Ex:
```shell=
lpr doc1
```
列印出叫作 "doc1" 的文件。

```shell=
man ls | lpr -P hp1
```
利用 "hp1" 印表機將 "ls" 的說明文件給列印出來。
    
### lp 列印(for solaris)

![](https://i.imgur.com/msXkpXH.png)    

-n # 表示列印#份
    
```shell=
lp -d hp1 -n 3 doc1
```
    
用 “hp1” 印出三份 doc1。
    
### cal 顯示日曆

![](https://i.imgur.com/DbVxtN3.png)

如果沒有參數，則會顯示今天的日期。
    
如果只有一個參數，那它會當**年**來看。
    
```shell=
cal 3 2005
```
顯示 2005 年 3 月的日曆。
    
```shell=
cal 1969
```
顯示 1969 年 12 個月的日曆。
    
### write 寫訊息給其他使用者

![](https://i.imgur.com/FDDXNDM.png)

你可以用 ```who``` 指令來查看你要寫給誰。

Ex:

![](https://i.imgur.com/ruIZ0nu.png)

* **mesg**: 設定是否開啟接收以及傳遞訊息的權限，y 開啟，n 關閉，沒參數的話就回傳目前是關閉著還是開啟著。
* **biff**: 設定接收到通知是否要立刻通知使用者，y 開啟，n 關閉。
    
### alias 創造假名

![](https://i.imgur.com/cXnKnjp.png)

alias 在某些 shell 中用法不太相同。

![](https://i.imgur.com/rBmUtVr.png)

如果要傳參數的話記得要用 ```\!*```

![](https://i.imgur.com/kQ0cv0M.png)

當你沒有任何參數而單獨使用了 ```alias``` 時，它會列出所有已經存在的**假名**。

### unalias 刪除假名

```shell=
unalias ls 
```
刪除假名 ```ls```。

```shell=
unalias -a
```
刪除所有假名。
    

### INTRODUCTION TO UNIX SHELLS

在Unix shell中輸入指令，他會幫你執行該指令。

當你的 shell 接收到你傳送了 <Ctrl+D> ，它會自動結束並登出。
    
```shell=
echo $PATH
```
輸出環境變數。

![](https://i.imgur.com/d75SYLl.png)

**shell的演進**

![](https://i.imgur.com/Q13JSVg.png)

```shell=
echo $SHELL
```
輸出預設的shell是哪個。

```shell=
chsh
輸入密碼
/usr/bin/csh
```
輸入chsh切換shell，接著輸入要切換shell所在的路徑，切換完成!
    
### 正規表示式
![](https://i.imgur.com/Y1U2gwm.png)
![](https://i.imgur.com/hjZB3f2.png)
![](https://i.imgur.com/gZNWfJF.png)

### THE SUDO AND SU COMMANDS

**sudo** : 以最高權限者身分執行。

**su** : 切換身分為最高管理者。最高管理者有最高權限，擁有所有 檔案的權限，所以輸入這兩個指令需要核對密碼。

## Editing Text File

### Text Edit 
* vi
* vim
* Emacs
* gvim

### 牛刀小試

當我們要(創建)執行一個文字檔時，可以直接利用 ```vi file1```。
![](https://i.imgur.com/2ZHuyUh.png)

* ```A``` 是 append。
* ```wq``` 是儲存並退出。
    
一進去不能馬上就輸入東西，你必須輸入 ```A``` 。

vi是文字介面，其他vim、gvim則有圖形化介面。
    
這些文字編輯器都有暫存空間(buffer)，可以存放複製貼上的字串。

### Buffer

尚未儲存前做的那些更動。


### shell script file

腳本，電腦會依序執行腳本上的指令。

![](https://i.imgur.com/hejpy2I.png)
![](https://i.imgur.com/HS6ECKz.png)

所以利用 ```vi``` 把指令寫在文字檔裡，再用 ```sh``` 去執行，便會依序執行文字檔裡輸入的指令。
    
### How to start vi

![](https://i.imgur.com/ytoDJyd.png)

vi command 有很多模式，要熟記!!!!

![](https://i.imgur.com/pzwPVaE.png)

常用觀念 : 
* **Command mode**: 指令模式，可存檔，可移動游標。
* **Insert mode**: 輸入模式，可輸入內容。
* 一開始進來時在Command mode。
* ```:``` ，進入最後模式。
* 可使用```h、j、k、l```移動游標。
* ```u``` : 取消上一次做的動作。
    
大小寫差異 : 
![](https://i.imgur.com/UHImWMc.png)

### vi 的一些酷酷操作。
* dd，刪除游標在的那一行。
* u，取消之前的操作(undo)。
* x，刪除游標所在的字。
* :w，存檔。
* :w filename，存檔，檔名為filename。
* :q，離開編輯器。
* :q!，離開編輯器但不儲存檔案。
* :ZZ，儲存的功能，有時候 ```w``` 不能使用時很好用。
    
以下看看就好。

![](https://i.imgur.com/yC1VQQD.png)

![](https://i.imgur.com/rbY8lMV.png)
    
![](https://i.imgur.com/BjlbAg7.png)

接下來的東東滿重要的 : 

![](https://i.imgur.com/TLpVoG6.png)
    

### yank and put(copy and paste)
    
![](https://i.imgur.com/JzhQF9Q.png)

### Substitute (Search and Replace)

![](https://i.imgur.com/wJjgT2r.png)

    
## Ch4 Files and File System structure

在Unix中，檔案就是一個byte序列，很多東西，像網卡，硬碟，USB，鍵盤，列表機，都是檔案的一種。

![](https://i.imgur.com/0Q8Z2wQ.png)

檔案類型可加可不加，不過有些加一下比較好，例如C語言的檔案 -> *.c。
    
### 目錄類別 (directory entry)

結構示意圖 : 
![](https://i.imgur.com/bbqWDtv.png)

**inode number** 有四個 byte 長，是磁碟陣列的索引值 (index value)。

每一個不同的 file 都有不同的 inode 。

### Link File

Link file points to an existing file，代表他可以存取其它路徑的檔案，而不用複製它。

**Symbol link** :　捷徑　（軟連結）
存放某個已存在檔案的絕對路徑。
    
### Special File (跟硬體有關)

每一個硬體設備至少都會有一個 Special File。
    
Character special file : 字元設備文件
Block special file : 塊設備文件

**pseudodevices** : 
    ![](https://i.imgur.com/hLMktCD.png)

### Name Pipe
Named pipe (FIFO): 命名管道
處理多程序，讓多個程序互相溝通，並讓他們有 relative 的關係。
    
### Socket 

* 在網路上的進程可以透過 AF_INET 這個 domain 的 socket 進行互相對話。
* 在同一個機器上的進程可以透過 AF_UNIX 來進行互相對話。
    
### FILE SYSTEM STRUCTURE
    
在 UNIX 裡面，檔案系統就像樹一樣的結構，而且是由上到下的。
    
所有檔案結構都從一個主要的目錄開始，叫作 ```root``` **根目錄** 也以 ```/``` 表示。
    
![](https://i.imgur.com/2qXqSpT.png)

代表有 46 個 **目錄加檔案** (並不是只有檔案而已)。

* ```.``` : 代表當前目錄。
* ```..``` : 代表目錄的上一層。
    
檔案的結構(樹狀)圖 :
    
![](https://i.imgur.com/lm3z91Q.png)

### Pathnames: Absolute and Relative

絕對路徑 : 從根目錄開始就是絕對路徑。

```/home/faculty/sarwar/courses/ee446```

相對路徑 : 根據當前的目錄。
    
### UNIX Standard Directories and Files
    
#### /bin  

也稱作二元目錄。放很多執行檔的地方(包含shell...)。含有非常多會用到的指令。

BSD 系統中的目錄 : /usr/bin
    
#### /boot 

主要放置許多開機會用到的檔案。
    
在我們的系統中可能只會包含 ```loader.conf``` 這個檔案。
    
#### /dev

在Linux系統上，任何裝置與周邊設備都是以檔案的型態存在於這個目錄當中的。

像是: Terminals、Disk drives、Printers…
    
這些檔案稱作 ```special files```。
    
#### /etc
    
很多執行檔、設定檔都放在這邊，不管是應用程式的，還是帳號密碼的檔案(/etc/passwd)...等等。
    
#### /lib
    
系統的函式庫非常的多，而/lib放置的則是在開機時會用到的函式庫， 以及在/bin或/sbin底下的指令會呼叫的函式庫而已。

像是: C/C++ 函式庫
    
#### /tmp

顧名思義，就是存放一些暫存的檔案，存放在這裡的檔案會進行週期性的刪除，所以硬碟不會填滿。
    
也許系統重開機後 ```/tmp``` 就不見了。
    
#### /usr

包含絕大多數的使用者工具和應用程式，注意不是user的縮寫，而是"Unix Software Resource"的縮寫。

常見的有:

* /usr/bin : 包含很多命令列的東西。
* /usr/lib : 有很多語言的函式庫 (ex: C, C++)。
* /usr/home: 存放使用者個人的資料，登入時就是在這個目錄下使用者自己的資料夾，每個人都有自己的家目錄。
    
額外一提:
    
為何我們使用 ```ls -ld /home``` 的時候，會出現類似```/home -> /usr/home```呢?
    
因為系統幫我們把連結直接指向 ```/usr/home``` 了，這可以達到直接存取的效果。(使用 symbol link)
    
#### var

變數檔案——在正常執行的系統中其內容不斷變化的檔案，如紀錄檔，離線檔案，和一些系統中的log檔。
    
### user ID and group ID
    
當我們查看 ```/etc/passwd``` 並去 fetch ```sarwar``` 時 :

![](https://i.imgur.com/lXdLP1O.png)
    
都是用 colon(冒號) 去隔開不同的資訊。
    
* 第一欄代表的是 ```login_name```，也就是使用者名稱。
* 第二欄是 ```password```，是這個使用者的密碼，不過如果你不是超級管理員的話，你只會看到暗碼。
* 第三欄是 ```user_id```，也就是使用者ID，拿來辨認是哪個使用者的，大家都不一樣，比較特別的是 1-999 被保留起來了。
* 第四欄是 ```Group ID```，也就是群組ID，拿來辨認你屬於哪個群組，0-99 被保留。
* 第五欄是 ```user_info```，會出現使用者的全名。
* 第六欄是 ```home_directory```，該使用者家目錄的位置。
* 第七欄是 ```login_shell```，初始shell的位置。
    
兩個分號連在一起就代表該欄資料不見了!!!!!!

### Determining the Absolute Pathname for Your Home Directory
    
第一種方法 : 
    
```shell=
echo $Home

//輸出 : /home/user name
```

第二種方法 : 

```shell=
pwd
    
//輸出 : /home/user name
```
    
### Browsing the File System
    
* cd: 移動到指定目錄
* ls: 印出檔案清單
    
Special : 

```ls -F```
    
![](https://i.imgur.com/mJARCLj.png)

``` ls -i``` : 顯示 inode 編號。
    
![](https://i.imgur.com/AjYJnyy.png)

p.s. 若要顯示目錄的 inode 編號，請記得使用 ```ls -id```。
    
**正規表示式複習** : 

```shell=
ls -l [a-zA-Z]??[1-5].html
```
尋找一個開頭第一個字是(a-z)或(A-Z)的英文字母，中間夾兩個字(隨便)，最後一個是數字並且在(1-5)之間。
    
ex: ```ma77.html```
    
```^``` : 代表false。

### Creating and Removing Directories
    
```mkdir``` : 建立資料夾。
```rmdir``` : 刪除資料夾。
    
### Determining File Attributes

![](https://i.imgur.com/16gFUTH.png)

### Determining the Type of a File’s Contents

不能被檔名後面的檔案類型欺騙!!!
    
因為你也可以幫你的 .c 檔取名叫 .jpg 檔。
    
因此我們需要 ```file``` 命令來知道檔案的特性。

![](https://i.imgur.com/vw9nfVP.png)

例如 : 

![](https://i.imgur.com/n4bEpO0.png)


p.s. 有個東西叫 ```core dumps``` ，如果程式執行到一半當機，會被創造出來，叫作 ```core```，你可以利用他來判斷為啥會當機。
    
### File Representation and Storage in UNIX

Unix中，所有檔案都有一個專屬的編號(inode number)，利用這個編號來查表(inode table)，表格上會記錄檔案在硬碟上的位置，就可以順利取得內容了。
    
![](https://i.imgur.com/pJpkmpY.png)

* ```link count``` : 有幾個不同名字的檔案在系統中。
* ```file mode``` : 當打開時狀態是讀取或寫入等等...。
* ```user ID``` : 檔案擁有者的ID
* ```access permission``` : 誰可以存取這個檔案。
    
### STANDARD FILES AND FILE DESCRIPTORS

UNIX都會裡用三個檔案來做執行，稱作標準檔案。

![](https://i.imgur.com/VI0VggG.png)

要改變其他檔案的話 : 
* ```<``` : input
* ```>``` : output
    
### END-OF-FILE (eof) MARKER

表示檔案結束，value 是 -1。