# Linux Tutorial

---
# Introduction
----
## Q1: 什麼是 Linux?
----
## A1:
Linux 是一個作業系統,Windows 和 MacOS 也是作業系統。Linux 具有多人多工、權限管理等特性,而且 Linux 是開源且免費的。
----
## Q2: 為啥要用 Linux?
----
## A2:
1. 以後大家一定會用到工作站,工作站大多是 Linux。
2. 以後要走 CS 的話 Linux 是基本中的基本。
3. 世界上現有的 server 很多都是 Linux 架的。
4. Linux 是免費的,你不用再去找什麼 Windows 破解版。而且把 Windows 和 Linux 灌在同一顆 HDD 硬碟上,Linux 的速度是 Windows 的好幾倍 !
5. 寫 code 就要用 Linux!
----
## Q3: 我聽過 Unix / Linux / Ubuntu ,他們之間的關係是啥?
----
## A3-1:
Linux 是 Unix-like (類 Unix) 的 system,除了現在大家常用的開源免費 Linux 外,MacOS 也是由正統的 Unix 系統延伸出的商業化作業系統。
----
## A3-2:
Linux 是作業系統本身(正確來說是 kernel),只有作業系統在動的話沒有其他應用程式的話不太能做什麼事,因此就有很多廠商將 Linux kernel 和其他應用程式包一包(例如包一個桌面環境)發佈出去供大家下載,稱作 Linux 發行版(Distribution)。
----
## A3-3:
Ubuntu 便是眾多發行版的其中之一,他包了許多工具,對新手比較友善。其他常見的發行版有 Mint、RetHat、Debian、Arch、Gentoo 等。想看更多可以點下面的連結。
[Linux Distributions - Wikipedia](https://en.wikipedia.org/wiki/Comparison_of_Linux_distributions)
---
# Basic Concept
----
## Unix Architecture

----
+ <font color=orange>**Hardware**</font>: RAM, CPU, hard disks, mouse ...
+ <font color=orange>**Kernel**</font>: 負責軟體和硬體間的互動,如記憶體管理等
+ <font color=orange>**Shell**</font>: 負責把我們輸入的指令轉換成 kernel 看得懂的語言讓 kernel 做事
+ <font color=orange>**Applications**</font>: 各種軟體,不管是下指令執行的軟體或是有圖形介面的軟體都是
---
# Shell / Terminal
----
+ <font color=orange>**Shell**</font>: 吃 input (command),吐 output
+ <font color=orange>**Terminal**</font>: 偵測你的鍵盤輸入,把指令餵給 shell,把 shell 吐的 output print 給你看。
> shell = 跟 kernel 互動的程式
> terminal = 幫使用者跟 shell 互動的程式
----
## 開一個 terminal 吧!
去應用程式搜尋 terminal 打開,或是按 Ctrl+Alt+T (如果你是 ubuntu)。

應該可以看到類似上圖的東西,這時 terminal 在等你輸入指令,這個叫做 command prompt
----
## Mac OS
去 launch pad 搜尋 terminal

----
## WSL
開始 -> windows terminal -> Ubuntu

----
可以發現 prompt 的最後一個符號是 `$`,因此之後的投影片如果看到
```shell
$ command
```
表示要輸入 `command` 這個指令,不要把 `$` 也輸入了喔。
---
# Path / Directory
----
## 目錄樹

----
## 路徑表示
- `~ ` home, 家目錄,登錄後所在的目錄
- `/ ` root directory, 根目錄,所有目錄的起源
- `. ` working directory, 當前目錄
- `..` parent directory, 上一層
> 對於檔案系統,只有一個根目錄 (`/`)
> 對於一個使用者,只會有一個家目錄 (ex. mark 的家目錄就會在 /home/mark)
----
## 絕對路徑:
(假設桌面現在有一個 hw 資料夾)
- 以 `/` 開頭,代表是從根目錄開始算
```shell
$ cd /home/mortalhappiness/Desktop/hw
```
----
## 相對路徑:
- 不是以 `/` 開頭,看從哪裡算起
完整路徑:
```shell
$ cd /home/mortalhappiness/Desktop/hw
```
從現在位置:
```shell
$ cd ./hw # 假設現在位置在Desktop
```
從家目錄:
```shell
$ cd ~/Desktop/hw
```
若要回到上一層(`Desktop`):
```shell
$ cd .. # 設現在位置在 hw
```
----
## pwd
```shell
$ pwd # print working directory 可以看到現在的目錄所在
```
----
## cd
```shell
$ cd # change directory,前往指定的目錄
```
常用參數:
```shell
$ cd ~ # 前往家目錄,直接打 cd + enter 也會是一樣的
$ cd /home/mortalhappiness/Desktop # 到這個目錄當中
$ cd .. # 到上一層目錄
$ cd / # 到根目錄
```
----
## ls
```shell
$ ls # list 列出本目錄底下有什麼檔案
```
常用參數:
```shell
$ ls -a # 列出所有檔案,包含隱藏檔案 (檔名開頭是 . 為隱藏檔)
$ ls -l # 用清單格式列出,可以看到檔案的目錄權限、時間戳、檔名
```
Example:
```shell
$ ls ~/Desktop # 列出 ~/Desktop 下的所有資料
$ ls -al # 等同於 ls -a -l
```
---
# 檔案管理與操作
----
## cp
```shell
$ cp # copy, 複製檔案
```
```shell
$ cp file1 file2 # 在當前目錄將 file1 另存新檔為 file2
$ cp file dir/ # 將 file 複製到某個目錄當中
$ cp -r dir1/ dir2/ # folder 的話就用 -r (recursive)
```
----
## mv
```shell
$ mv # move, 移動或重新命名一個檔案或目錄
```
```shell
$ mv dir1/ dir2/ # 如果 dir2 不存在就將 dir1 重新命名為 dir2
$ # 否則將整個 dir1 移動到 dir2 裡面
$ mv file dir/ # 將檔案 file 移動到目錄 dir 裡面
$ mv file1 file2 # 將檔案 file1 重新命名為 file2
```
----
## rm
```shell
$ rm # remove, 永久刪除檔案
```
```shell
$ rm file # 移除 file
$ rm -f *.c # 當前目錄以 .c 結尾的都強制移除
$ rm -rf dir/ # 將 dir/ 整個強制移除
$ rm -rf * # 將此目錄下所有檔案強制移除
```
----
## ln
link, 創立捷徑檔(soft link)
```shell
$ ln -s target link_name # 創立一個 soft link
$ # 從 link_name 指向 target
```
註:不加 `-s` 是 hard link,較少用。
----
## touch
```shell
$ touch test.txt # 新增 test.txt 這個空檔案
```
----
## mkdir
make directory, 新增資料夾
```shell
$ mkdir dir # 新增資料夾,名字是 dir
```
----
## rmdir
remove directory, 移除"空"資料夾
```shell
$ rmdir dir # 移除 dir 這個空資料夾
```
----
## find
search for filename
```shell
$ find . -name test.txt # 在此目錄底下搜尋檔名為 test.txt 的檔案
$ # 並輸出它的路徑
```
---
# 文字 / 輸出處理
----
## echo
將文字印到 terminal 上
```shell
$ echo hi
```
----
## cat
con**cat**enate files to standard output
將一個或多個檔案 print 到 terminal 上
```shell
$ cat test.txt # 把 test.txt 的內容印到 terminal 上
```
----
## more
和 cat 類似,但可以用 enter 鍵往下捲動
```shell
$ more test.txt
```
----
## less (常搭配 pipe 使用)
和 cat 類似,但可以用上下鍵或 j/k 上下捲動
```shell
$ less test.txt
```
按 q 離開喔
----
## head
印出檔案的前幾行
```
$ head test.txt # 預設印出前10行
$ head -n 5 test.txt # 印出前5行
```
----
## tail
印出檔案的後幾行
```
$ tail test.txt # 預設印出後10行
$ tail -n 5 test.txt # 印出後5行
```
----
## diff
output the differences of two files
```shell
$ diff test1.txt test2.txt
```
---
# I/O Redirection
IO redirection可以使輸入/輸出不從standard input(鍵盤輸入)和standard output(輸出到螢幕上)來,而是導到特定檔案。
----
## Output redirection (>)
沒有redirection時,輸出會跑到console上:
```shell
$ echo hi
```
Redirect output to `test.txt`:
```shell
$ echo hi > test.txt
```
此時console不會有output,讓我們把 `test.txt` 的內容 print 出來看看:
```shell
$ cat test.txt
```
----
## Append mode (>>)
```shell
$ # 接續剛才
$ echo hello > test.txt # > 會把檔案內容完全蓋掉
$ cat test.txt
$ echo hi >> test.txt # >> 會把內容加到檔尾
$ cat test.txt
```
----
## Input redirection (<)
`cat` 指令單獨使用時 (不加任何參數),會把鍵盤輸入的東西 (standard input) 輸出到螢幕上 (standard output)。
```shell
$ cat
```
試著打幾個字再按enter看看,測試完畢後按 Ctrl+D 離開。
----
現在把剛才的 `test.txt` 的內容重新導向到 `cat` 指令看看。
```shell
$ cat < test.txt
```
:::info
:bulb: 下面這兩個指令有什麼不同呢?
```shell
$ cat test.txt
```
```shell
$ cat < test.txt
```
:::
----
:::info
A:雖然結果一樣,但概念不一樣,第一個是把 `test.txt` 當成參數,所以 `cat` 指令接收到1個參數,而 `cat` 指令接收到一個參數的動作就是把檔案裡面的東西輸出到standard output。而第二個則是 `cat` 指令接收到0個參數,`cat` 指令接收到0個參數的動作就是把鍵盤輸入 (standard input) 的東西輸出到standard output,而我們用"<"把鍵盤輸入 (standard input) 用 `test.txt` 的內容重導向,所以現在鍵盤輸入變成檔案裡面的內容, `cat` 指令就把它輸出到螢幕。
:::
---
# pipe (|)
Pipe 可以把前一個指令的輸出當作是下一個指令的輸入傳下去。
----
## Pipe Example - less
當輸出太長時,我們常用 pipe 搭配 less 指令方便閱讀
```shell
$ seq 90 # seq 會產生一堆照順序的數字
$ seq 90 | less # 用 pipe 灌給 less 這樣就可以上下捲動
```
----
## Pipe Example - grep
grep 是 <font color=red>g</font>et by <font color=red>re</font>gular ex<font color=red>p</font>ression 的縮寫,可以用來過濾輸出
```shell
$ seq 90 | grep 9 # 過濾 seq 的輸出,只印出帶有 9 的字
```
註:grep 後面接的字串其實是 regular expression,因為時間問題這邊不教,有興趣可以自己去搜尋 regular expression 教學
---
# 檔案權限
| 權限 | 對檔案 | 對資料夾 |
| ----------- | ------ | ------------ |
| r (read) | 可讀 | 可 ls |
| w (write) | 可寫 | 可創檔、砍檔 |
| x (execute) | 可執行 | 可 cd |
----
用 ls -l 顯示的第1欄就是權限
1. 第一個字是 - 代表是一般檔案,d 代表是資料夾
2. 接下來每三個為一組,分別代表擁有者、group、other的權限
----
## chmod
change mode
```shell
$ chmod [ugo] [+-] [rwx] file # 語法
$ chmod +x test.txt # 把 test.txt 對所有人新增 x 權限
$ chmod o-x test.txt # 把 test.txt 對 other 拔除 x 權限
```
把 rwx 想成二進位,r=4, w=2, x=1,可以一次指定所有權限
```shell
$ chmod 644 test.txt # 擁有者有 rw 權限,
$ # group 和 other 都只有 r 權限
```
---
# 檔案壓縮 / 解壓
----
## zip
壓縮檔案成zip
```shell=
$ zip -r test.zip ./test/
```
----
## unzip
解壓縮 zip 檔
```shell=
$ unzip test.zip
```
----
## tar
壓縮 / 解壓 tarball
```shell
$ tar zcvf test.tar.gz test/ # 把 test 資料夾壓成 gzip tarball
$ tar zxvf test.tar.gz # 解壓 gzip tarball
```
z: gzip, c: create, v: verbose, f: file, x: extract
註:最常見的是 gzip,其他還有 bzip、xz 等,參數不太一樣,有興趣可以自己查。
---
# 系統資源
----
## free
顯示記憶體用量
```shell
$ free -mh
```
----
## df
查看磁碟分區使用量
```shell
$ df -h
```
----
## top
看記憶體用量、哪些程式在跑、CPU loading 等
```shell
$ top
```
按 q 離開喔
---
# 網路相關
----
## ssh
登入工作站
```shell
$ ssh username@hostname -p port
```
----
## 檔案上傳 / 下載 工作站
```shell
$ sftp -P port username@hostname
```
### 基本 ftp 指令 - 1
| 指令 | 意義 |
| -------- | ------------------------------------- |
| ls | 在工作站上執行 ls |
| !ls | 在本地端執行 ls |
| cd | 在工作站上執行 cd |
| lcd | 在本地端執行 cd |
----
### 基本 ftp 指令 - 2
| 指令 | 意義 |
| -------- | ------------------------------------- |
| pwd | 在工作站上執行 pwd |
| !pwd | 在本地端執行 pwd |
| get file | file 是檔名,把 file 從工作站上載下來 |
| put file | file 是檔名,把 file 上傳到工作站上 |
----
## wget
下載檔案
```shell
$ # 把這張 google icon 圖片載下來
$ wget https://openthread.google.cn/images/ot-contrib-google.png
```
---
# 其他
----
## file
查看一個檔案的 file type
```shell
$ file test.txt
$ file test.zip
$ file test.tar.gz
```
----
## clear
清掉 terminal 上所有內容。
```shell
$ clear
```
----
## history
show command history
```shell
$ history
```
----
## sudo
execute commands as root user (superuser)
```shell
sudo apt install vim
```
----
## type
查看一個 command 是 builtin command 還是 external command
```shell
$ type cd # output: cd is a shell builtin
$ type ls # output: ls is /bin/ls
$ # 或是:ls is aliased to `ls --color=auto'
```
----
## help
查看 builtin command 的說明
```shell
$ help cd
$ help help
```
----
## man <font color=red>[超重要的啦]</font>
manual 的縮寫,收錄了各種指令的詳細說明,但不包含 builtin command
```shell
$ man ls
$ man man
```
----
## tmux
Installation
```shell
$ sudo apt install tmux
```
tmux usage
```shell
$ tmux # 新增一個 tmux 的 session
$ tmux ls # 查看所有 tmux 的 session
$ tmux attach -t <session> # 連上 tmux 的 session
```
----
## tmux
常用快捷鍵
| 按鍵 | 功能 |
| ----------------- | ----------------------------------- |
|Ctrl+b 再輸入 d |脫離目前視窗。|
|Ctrl+b 再輸入 % |垂直分割視窗。|
|Ctrl+b 再輸入 " |水平分割視窗。|
|Ctrl+b 再輸入 方向鍵 |切換至指定方向的 pane。|
----
## tmux
| 按鍵 | 功能 |
| ----------------- | ----------------------------------- |
|Ctrl+b 再輸入 空白鍵 |切換佈局。|
|Ctrl+b 再輸入 x |關閉目前的 pane。|
---
# Useful Hotkeys
----
| 按鍵 | 功能 |
| ----------------- | ----------------------------------- |
| Tab | 自動補齊指令/檔案名稱 |
| Arrow Up | 叫出history裡的上一個指令 |
| Shift + pgup/pgdn | 向上/向下捲動terminal |
| Ctrl + C | 中斷程式執行 |
| Ctrl + D | Exit / EOF |
| Ctrl + Z | 把程式送進背景並暫停執行 |
----
| 按鍵 | 功能 |
| ----------------- | ----------------------------------- |
| Ctrl + U | 從游標處向前刪除指令 |
| Ctrl + A | 讓游標移動到指令的最前面 |
| Ctrl + E | 讓游標移動到指令的最後面 |
| Ctrl + S | lock console |
| Ctrl + Q | unlock console |
| Ctrl + L | clear console (效果等同於clear指令) |
| Ctrl + R | 搜尋指令history |
---
## References
1. https://www.tutorialspoint.com/unix/index.htm
2. http://linux.vbird.org/
---
## Special Thanks
奇聖的投影片
---
# The End
{"metaMigratedAt":"2023-06-15T16:01:09.913Z","metaMigratedFrom":"YAML","title":"Linux Tutorial","breaks":true,"slideOptions":"{\"transition\":\"slide\"}","contributors":"[{\"id\":\"90f81fe6-9642-4f32-9aa7-eaccec059a0f\",\"add\":1276,\"del\":342},{\"id\":null,\"add\":37,\"del\":0},{\"id\":\"3283cada-956a-4fe4-adfc-dbde9b910191\",\"add\":105,\"del\":53},{\"id\":\"a4f7cec5-0d48-4d7e-bc83-4dfab3030445\",\"add\":10032,\"del\":1588},{\"id\":\"7092aa1b-8b34-4092-b91b-a2aa74b2e662\",\"add\":2150,\"del\":299}]"}