# 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.


* 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 : 作業系統分成很多資源可讓你調用,而且很公平、有順序、很安全地。
### 作業系統的好功用(讚讚)

### 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裡面,檔案的架構就像一棵樹。

第一次登入時,你會出現在家目錄(home directory)。
**myfile2** 的路徑會在 ```/usr1.b/bobk/myfile2```
所有路徑的起點都會在根目錄(/)。
### cat 建立檔案 / 查看檔案內容

-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 檢視檔案內容

```shell=
more myfile
//輸出 : hello world
```
若要輸出的東西已經大於 Terminal 的篇幅了,則下面會顯示百分比,代表目前顯示了多少。
若要換行則按 ```<space>```,要換頁按```<Enter>```,要結束則按 ```<Q>```。
### cp 複製檔案

EX : 假設我要copy myfile1 的 內容到 myfile2,則 :
```shell=
cp myfile1 myfile2
```
若要複製到某位置(ex:/usr/bin)的話,則 :
```shell=
cp myfile1 /usr/bin
```
就會看到在 ```/usr/bin``` 的地方出現 myfile1。
### mv 移動文件

第一個 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 刪除檔案

因為UNIX裡面沒有「資源回收桶」,所以一旦刪除了就很麻煩。
```shell=
rm file
```
刪除 "file" 檔案。
刪除裡面有東西的資料夾務必使用 ```rm -r dicname```
不過因為 ```rm``` 牽涉到非常多權限問題,之後會再補充。
### ls 列出檔案

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

印出所有檔案的詳細資料。
共有八個欄位 :
1. 第一個欄位代表資料屬性,```d```:目錄,```l```:symbol link,```-```:檔案,其他由 ```r,w,x,-```組成則代表檔案存取權限。
2. 儲存位置(硬碟)的編號。
3. 擁有者的名字。
4. 群組名稱。
5. 檔案大小。
6. 檔案建立日期。
7. 檔案名稱。
```shell=
ls -la 檔案名
```
則會列出單一檔案的許多資訊。
假設要找出某個特定開頭的檔案,可以 ```ls``` 搭配特定開頭加星號。
```shell=
ls my*
```
可以找到 ```myfile```, ```myfile1```。
**星號**有替代任何東西的功能。
### mkdir 創建資料夾

```shell=
mkdir dict
```
創建叫做 "dict" 的目錄(資料夾),若沒特別指出路徑則代表在當前目錄下創建。
* -p 確保目錄名稱存在,不存在就創一個。
### rmdir 刪除資料夾

```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 當前路徑

```pwd```指令會顯示你當前所在路徑(絕對路徑)。
### man 查詢指令的功能
很讚的指令,考試不會可以拿來查。

Ex:

顯示 ls 指令的說明文件,想換下一頁按 <space> ,結束按 <Q>。
### whatis 查詢指令的功能

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

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

**who**: 印出所有使用者名稱。
**hostname**: 印出使用者名稱及裝置
Hint : Use the ```hostname``` command to find out what host computer you are logged on to.
### lpr 列印(for PC-BSD)

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

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

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

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

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

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

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

當你沒有任何參數而單獨使用了 ```alias``` 時,它會列出所有已經存在的**假名**。
### unalias 刪除假名
```shell=
unalias ls
```
刪除假名 ```ls```。
```shell=
unalias -a
```
刪除所有假名。
### INTRODUCTION TO UNIX SHELLS
在Unix shell中輸入指令,他會幫你執行該指令。
當你的 shell 接收到你傳送了 <Ctrl+D> ,它會自動結束並登出。
```shell=
echo $PATH
```
輸出環境變數。

**shell的演進**

```shell=
echo $SHELL
```
輸出預設的shell是哪個。
```shell=
chsh
輸入密碼
/usr/bin/csh
```
輸入chsh切換shell,接著輸入要切換shell所在的路徑,切換完成!
### 正規表示式



### THE SUDO AND SU COMMANDS
**sudo** : 以最高權限者身分執行。
**su** : 切換身分為最高管理者。最高管理者有最高權限,擁有所有 檔案的權限,所以輸入這兩個指令需要核對密碼。
## Editing Text File
### Text Edit
* vi
* vim
* Emacs
* gvim
### 牛刀小試
當我們要(創建)執行一個文字檔時,可以直接利用 ```vi file1```。

* ```A``` 是 append。
* ```wq``` 是儲存並退出。
一進去不能馬上就輸入東西,你必須輸入 ```A``` 。
vi是文字介面,其他vim、gvim則有圖形化介面。
這些文字編輯器都有暫存空間(buffer),可以存放複製貼上的字串。
### Buffer
尚未儲存前做的那些更動。
### shell script file
腳本,電腦會依序執行腳本上的指令。


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

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

常用觀念 :
* **Command mode**: 指令模式,可存檔,可移動游標。
* **Insert mode**: 輸入模式,可輸入內容。
* 一開始進來時在Command mode。
* ```:``` ,進入最後模式。
* 可使用```h、j、k、l```移動游標。
* ```u``` : 取消上一次做的動作。
大小寫差異 :

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



接下來的東東滿重要的 :

### yank and put(copy and paste)

### Substitute (Search and Replace)

## Ch4 Files and File System structure
在Unix中,檔案就是一個byte序列,很多東西,像網卡,硬碟,USB,鍵盤,列表機,都是檔案的一種。

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

**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** :

### Name Pipe
Named pipe (FIFO): 命名管道
處理多程序,讓多個程序互相溝通,並讓他們有 relative 的關係。
### Socket
* 在網路上的進程可以透過 AF_INET 這個 domain 的 socket 進行互相對話。
* 在同一個機器上的進程可以透過 AF_UNIX 來進行互相對話。
### FILE SYSTEM STRUCTURE
在 UNIX 裡面,檔案系統就像樹一樣的結構,而且是由上到下的。
所有檔案結構都從一個主要的目錄開始,叫作 ```root``` **根目錄** 也以 ```/``` 表示。

代表有 46 個 **目錄加檔案** (並不是只有檔案而已)。
* ```.``` : 代表當前目錄。
* ```..``` : 代表目錄的上一層。
檔案的結構(樹狀)圖 :

### 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``` 時 :

都是用 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```

``` ls -i``` : 顯示 inode 編號。

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

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

例如 :

p.s. 有個東西叫 ```core dumps``` ,如果程式執行到一半當機,會被創造出來,叫作 ```core```,你可以利用他來判斷為啥會當機。
### File Representation and Storage in UNIX
Unix中,所有檔案都有一個專屬的編號(inode number),利用這個編號來查表(inode table),表格上會記錄檔案在硬碟上的位置,就可以順利取得內容了。

* ```link count``` : 有幾個不同名字的檔案在系統中。
* ```file mode``` : 當打開時狀態是讀取或寫入等等...。
* ```user ID``` : 檔案擁有者的ID
* ```access permission``` : 誰可以存取這個檔案。
### STANDARD FILES AND FILE DESCRIPTORS
UNIX都會裡用三個檔案來做執行,稱作標準檔案。

要改變其他檔案的話 :
* ```<``` : input
* ```>``` : output
### END-OF-FILE (eof) MARKER
表示檔案結束,value 是 -1。