Quick Tutorial of Linux and Workstation


Posted by a113062130630210 on 2022-06-20

UNIX是一種多用戶、多工的作業系統,提供不同的使用者能夠同時在一台主機上進行各種項目服務。Linux是建構在UNIX上開發出來的核心,Ubuntu是以Linux為核心所發行的一套作業系統
可以想成UNIX是猩猩,Linux是演化後的智人(兩者能力不相同,有上下關係),而Ubuntu是白種人,Debian是黃種人,Redhat是黑種人(有相同基本能力,但是用不一樣的外觀或套件服務)
Application > Shell > Kernal
kernal: 核心,作業系統的最底層,負責和硬體溝通和真正執行我們的指令(更改記憶體,跟螢幕說要印出什麼東西)
shell: 負責將我們的輸入(也就是指令)轉換成kernal看得懂的語言,ex: gcc,ls,chmod
application:將這些指令包裝成一般的應用程式,如各種軟體、app,都是由一連串的指令或程式碼轉換成人容易操作的圖形界面

Workstation

系上的工作站大多使用Linux發行版之一的Debian,只要有電腦和網路,就能透過ssh連上工作站。SSH(Secure Shell Protocol),是一種安全的網路協定,提供我們遠端連到伺服器的服務

如何連到工作站

在Windows的cmd或是Mac/Ubuntu的terminal輸入
$ ssh <account>@<IP address>
比方說要連到meow1的話就是
$ ssh b09901133@meow1.csie.ntu.edu.tw$ ssh b09901133@meow1.csie.org
當然也可以更改ssh config,這樣的話只要打
$ ssh meow1就能連上去了,或是寫一個shell script執行ssh的指令,這樣就不用每次連工作站都打一長串了

ssh key

注意到每次連工作站都要打密碼,如果不想打密碼的話可以按照以下步驟:
1.$ ssh-keygen生成ssh key
2.之後terminal會跳出Enter file in which to save the key (~/.ssh/id_rsa)問你key要存在哪裡,直接按enter會存在預設的位置
3.Enter passphrase (empty for no passphrase):如果輸入的話,之後登入就要輸入passphrase,直接enter,就不用輸入
4.$ ssh-copy-id <account>@<IP address>並且輸入你的密碼確認,這樣之後就可以用ssh key登入了

登出工作站的話,輸入$ exit$ logout即可

Linux檔案路徑

~: home,家目錄,也就是登入系統後進入的目錄
/: root directory,根目錄,所有目錄的開始
.: working directory,當前目錄
..: parent directory,上一層

對於一個檔案系統,只有一個根目錄,對於一個使用者,只有一個家目錄(ex: b09901133的家目錄是/home/student/09/b09901133)

絕對路徑: 以/開頭,表示從根目錄開始
相對路徑: 以./開頭,表示從當前目錄開始,而一般如果不寫的話就是預設從./開始

以下介紹幾個常見的目錄
/bin: 可執行檔
/dev: 週邊設備
/lib: 函式庫
/etc: 系統設定
/home: 家目錄
/usr: 軟體資源
/tmp: 暫存檔
/var: 動態數據

以下介紹幾個常用的指令
pwd: print working directory,印出現在所在的目錄
ls: list,列出本目錄
常用參數有:

  • -a(all) 列出包含隱藏檔案的所有檔案(隱藏檔案檔名開頭會有.)
  • -l(long listing) 用清單格式列出,可以看到檔案的權限、時間戳、檔名、大小
  • -t(time) 依照最後編輯時間列出
  • -h(human readable) 用好讀的方式印出
    $ ls dir/     列出./dir下的所有檔案
    $ ls -al      列出當前目錄的所有檔案,用清單方式列出,包含隱藏檔
    
    cd: change directory,前往指定的目錄
    $ cd   回到家目錄
    $ cd ~ 回到家目錄
    $ cd /home/student/10 到/home/student/10這個目錄
    $ cd .. 到上一層目錄
    $ cd / 到根目錄
    

上傳/下載檔案

sftp
ssh file transfer protocol
$ sftp b09901133@linux1.csie.ntu.edu.tw
登入之後:

$ get <remote-path> [local-path] 從remote-path下載到local-path
$ put <local-path> [remote-path] 從local-path上傳到remote-path
$ cd 移動遠端路徑
$ ls 查看遠端資料

如果要上傳或下載整個目錄的話,要加上-r

wget <URL>
World Wide Web get
$ wget http:example.com
$ wget -O hi.html http:example.com 下載檔案,檔名為hi.html
$ wget -O - http:example.com 下載檔案,並且當作文字檔案輸出到terminal
相似的指令有curl,預設是把檔案內容直接輸出到terminal:
$ curl <url> 產生的結果類似 $wget -O - <url>

Terminal小技巧

tab鍵

按tab可以自動補足指令或目錄或檔案名稱,但是遇到多個可能會停在分岔點,連按兩次可以列出所有可能性

上下鍵

可以回到上一個指令/下一個指令

萬用字元(*)

代表零或不限個數個任何字元
ex: abc.caabbcc都是*c

複製/貼上/刪除

在terminal中,複製是 ctrl+shift+C,貼上是ctrl+shift+V,刪除的話是ctrl+W(刪除一個字)和ctrl+U(整行刪除)

clear: 清空目前畫面
ctrl+C: 中止目前程式
ctrl+D: 在stdin中代表EOF,windows中則是ctrl+Z
exit: 離開terminal,包括ssh連上工作站或是sftp連上工作站或是自己開一個terminal的時候都可以這樣離開terminal
alias: 設定或印出指令的別名,如果自己想要個人化一些指令的話可以使用這個

$ alias ll 告訴你執行ll的時候實際上執行什麼
$ alias md="mkdir -p" 設定執行md是執行mkdir -p

cheat.sh: 用$ curl cheat.sh/<command name>可以看到command的常見用法,個人認為比man好用一點
man <command name>: manual,可以看到指令的詳細用法

檔案管理與操作

cp: copy,複製檔案,被複製的在前,複製出的在後,可以用路徑指定複製出的東西的位置,要複製整個目錄要-r

$ cp <file1> <file2> 在當前目錄將file1另存新檔為file2
$ cp <file> dir/ 將file複製到某個目錄當中
$ cp -r dir1/ dir2/ 將dir1內的所有東西複製到dir2

mv: move,移動或重新命名一個檔案或目錄

$ mv dir1/ dir2/ 如果dir2不存在就將dir1重新命名為dir2,否則將整個dir1移動到dir2裡面
$ mv <file1> dir1/ 將檔案file移動到目錄dir裡面
$ mv <file1> <file2> 將檔案file1重新命名為file2

rm: remove,永久移除檔案
常用參數:

  • -r: 遞迴的移除某個目錄以及其底下的所有檔案目錄
  • -f: 強制移除,系統不會一一詢問(預設是系統會一一詢問是否要移除掉這個檔案)
  • -d: 移除掉空的目錄
    $ rm <file> 將file移除
    $ rm -f *.c 將當前目錄以.c為結尾的所有檔案移除
    $ rm -rf dir/ 將dir目錄下所有檔案移除
    $ rm -rf * 將當前目錄所有檔案移除
    
    mkdir: make directory,建立新目錄
    常用參數
  • -p: (parent),如果需要的話,將parent directory一起新增
    $ mkdir dir/ 新增dir目錄 
    $ mkdir -p dir1/ dir2/ 在dir1裡新增dir2目錄,如果dir1不存在,就順便新增dir1
    
    rmdir: 刪除空的目錄,跟$ rm -d一樣
    touch: 點擊/戳一個檔案,如果不存在的話就建立它,可以用來改變時間戳
    $ touch <file> 新增file,或是改變file的時間戳

檔案與目錄權限

因為Linux是一個多人、多工的作業系統,因此對於一個檔案或目錄,需要去規定不同使用者知簽的權限。而在Unix-Like的作業系統中,我們會將一個檔案/目錄的權限針對擁有者(user)、同群組使用者(group)、和其他用戶(group)分為以下三種:

r(read),讀取檔案,讀取目錄內部的檔案條目(ls)
w(write),修改檔案,修改目錄屬性(ex: 名稱),並新增、刪除、更名目錄內的檔案
x(execute),執行檔案,進入該目錄內部(cd)

chmod: change mode,改變檔案/目錄的權限

$ chmod [ugo][+-][rwx] <file|dir/> 通式: 將[人]對file|dir [增減] [某權限]
$ chmod +rw <file> 將全部人對file新增讀寫權
$ chmod u+x <file> 新增自己對file的執行權
$ chmod go-r <file> 移除同群組和其他人對file的讀取權
將rwx想成二進位,r = 4, w = 2, x = 1,沒有該權限為0
$ chmod 700 dir/ 目錄權限: drwx------,d代表這是一個directory
$ chmod 644 <file> 檔案權限: -rw-r--r--,因為不是一個directory,所以沒有d這個參數

find [path] [option] [expression]
搜尋指令,只是要花比較久的時間,可以依照權限、擁有者、群組、檔案類型、日期與大小等條件來搜尋
常用參數:

  • -name: 指定檔名搜尋
  • -perm <mode>: 搜尋檔案權限為mode的檔案
  • -exec <command>: 將搜尋出的結果,使用其他指令再處理
    $ find ~ -name lost 在~下搜尋lost,預設為當前目錄
    $ find -perm 777 -exec chmod 755 {} + 將權限為777的檔案都設為755
    

本地相關指令

passwd: password,變更密碼,一般是可以用GUI設密碼的,但如果沒有GUI的話,這個指令其實還不錯好
sudo: superdoer,以superuser的權限執行指令,在工作站上不能用,有些跟安全性或系統內部的指令需要有superdoer的權限才能進行動作

$ sudo apt-get install vim 安裝vim
#apt-get是一個安裝套件的指令

工作管理

process簡介
process是程序,又稱行程、進程,是執行中的程式,每個程序會有一些屬性:

  • PID 程序獨特的識別碼
  • UID 產生這個程序的使用者
  • NICE 一個程序的友好程度,介在-20跟19之間,值越大,代表這個程序的執行優先度越低,越不會跟別人搶系統資源

ps: process status,查看程序的狀態
常用參數:

  • -l: 詳細列出程序的資訊
  • aux: 查看系統上的所有程序
    $ ps -l
    $ ps aux
    

kill: 可以結束指定PID的程序
常用參數:

  • -9: 強制結束
    $ kill 204 結束pid為204的程序

htop: 圖形化界面的程序管理員,可以查看執行中的程序,系統資源用量

CPU

htop最上方會列出各CPU的使用率,這邊顯示的是CPU的邏輯核心數(我也看不懂),譬如電腦有四核心八執行緒,意思是可以同時執行八個thread,那這邊就會顯示八個CPU

而這個使用率的bar會有三種顏色,每個顏色有各自代表的意義

  • 紅色: 代表kernal thread佔用的CPU,像是系統需要自動做process scheduling、memory management等等,是系統中最重要、優先權最高的任務
  • 綠色: 代表normal priority thread,優先度比kernal thread低,一般使用者的程式沒有特別調優先權的話,會被歸在這一類
  • 藍色: 代表low priority thread,優先權比較低,分配到的CPU也比較少,如果CPU很滿或是memory真的不夠用了,第一個kill掉的也是這類程序

Memory & Swp

它的顏色也是有意義的

  • 綠色: 被process佔用的記憶體,比方說瀏覽器、terminal、htop
  • 藍色: buffer pages,譬如說當你第一次ls -l的時候系統會去硬碟撈這個資料夾有哪些檔案、每個檔案的權限,然後存在buffer pages,這樣短時間再ls -l的時候就不用再進入硬碟(因為進入硬碟比較慢),直接從buffer拿即可
  • 橘色: cache pages,跟buffer很像,只不過buffer存metadata,cache存檔案內容,像第一次下cat index.js就會把內容讀取到cache pages,如果cat之後發現檔案太長,只要看前十行就好,那再下head -n 10 index.js就會從cache pages直接讀取

記憶體使用量並非越低越好,畢竟閒在那邊也沒什麼用,不如讓系統把閒置的部份拿去當buffer跟cache,這樣就可以盡量不碰硬碟,執行速度更快

swap的機制跟buffer還有cache相反,如果memory快不夠了,系統會把記憶體裡面一些東西swap到硬碟上,等真的需要再拿回來,缺點是程式速度會比較慢

Load Average

首先Tasks欄位的488, 1994 thr; 3 running代表目前總共有488個process、1994個thread,其中3個thread正在執行
Load Average是用來判斷目前系統有多忙,三個數字代表系統在最近一分鐘、五分鐘、十五分鐘內,平均有多少個thread需要CPU

PID/USER

PID是每個process的ID,可以用kill -KILL <pid>來殺掉某個process,或用kill -STOP來暫停process然後用kill -CONT讓它繼續執行
USER就是把這個process跑起來的人,不管程式是誰寫的,只要是我把它跑起來,USER就會顯示我的名字

PRI & NI

Priority跟Nice都是跟優先權有關的指標,注意數字越小表示優先權越高,可以分配到更多CPU,PRI是由系統決定的,無法自行更改,Nice預設是0,可以用renice -n 19 -p <pid>調整到最低優先權19,調高的話最高可以調到-20

雖然nice值可以自行調整,但系統不一定會根據nice來分配優先權,有些完全只根據PRI系統根本不在乎Nice

VIRT/RES/SHR

Virtual Memory,Resident,Shared Memory

Virtual Memory可以把它想成process可以存取到的memory總和,譬如說head -n index.js運作的方式就是把index.js打開,然後讀取前十行,雖然只讀取前十行,但head process已經把檔案打開了,它其實有權限access到整個檔案,所以virtual memory會把整個檔案的大小算進去

Resident是物理上佔用了多少記憶體,如果只讀取前十行,那系統就只把前十行從硬碟讀進記憶體,Resident也只算那十行

因此在htop裡Resident一定遠小於Virtual Memory

Shared Memory是可以跟別人分享的memory,像程式時常用的glibc,或是在讀取read-only檔案時,這些東西只要讀進記憶體一次就好了,所以會被算進SHM裡面

State

  • R: process正在跑或是在running queue裡等待CPU排程
  • S: 目前正在睡覺,有事做才會醒來
  • D: 這個也是在睡覺,只不過等待的一定是IO,譬如說讀取檔案、寫入資料庫等等

CPU%/MEM%

CPU%意思是在這段時間平均用了幾顆CPU,因為htop預設3秒更新一次,假如前1.5秒用了一顆,後1.5都沒用,那平均就是50%,如果這3秒用好用滿四個核心,那就是400%

因為CPU%是很短期的數據,所以當電腦當當的時候,看CPU%就可以知道是誰在霸佔CPU

MEM%也很類似,是使用記憶體的比例,並且使用Resident來計算,所以如電腦配有4GB的記憶體,某個process的Resident是1GB,那就是用掉實體記憶體的25%

Time+

代表的並不是程式從啟動到現在總共經過了多久,而是這個程式總共佔用了多少CPU Time

因此如果想知道長期而言哪個程式最佔CPU的話,就看Time+的數值,如果是看短期、目前正在暴衝的程式,就看之前提到的CPU%

常用參數:

  • -u 只顯示特定使用者的程序
  • -p 只顯示特定的程序
  • -s 將程序按照特定資訊欄排序
$ htop -u b09901133 查看b09901133的程序資訊
$ htop -s USER 將程序照使用者排序

ctrl+Z: 暫停目前的程序

jobs: 列出目前terminal中的程序,包含在背景執行或暫停的
$ jobs -l 列出這個terminal裡面的程序,並且附上PID

文字/輸出處理

cat: Concatenate,串接並輸出一個以上的檔案的內容。參數-n可以在每一行加上行號

$ cat <file1> <file2> <file3> 串接file1、file2、和file3輸出
$ cat -n <file> 將file每行前都加入行號輸出
$ cat *.c 將所有.c檔都串接在一起輸出

less: 跟cat類似,不過比較像是閱讀器的功能,可以一頁一頁讀(空白鍵)或是一行一行讀(上下鍵),可以按q離開或是/?搜尋

head / tail: 顯示檔案的前面幾行或最後幾行,預設是10行,可以用-n num-num指定行數

$ head *.c -n 5 顯示檔案結尾為.c的前5行
$ tail file[1-5] -13 顯示file1-file5的末13行

wc: word count,計算一個檔案內的行數(line)/字數(word)/字元數(char),不加參數就是分別顯示以上三者,如果加上一個以上的參數則輸出指定的內容

$ wc <file> 顯示三種資訊(line/word/char)
$ wc -l <file> 顯示行數
$ wc -wc <file> 顯示字數與字元數

管線命令 pipeline

對於每個參數,都會有一個標準輸入(STDIN)、標準輸出(STDOUT)、標準錯誤輸出(STDERR),代表的數字分別是0,1,2

redirect: output(>, >>), pipe(|), input(<)
> 把STDOUT(如指令、程式結果)寫入新檔案(如果檔案名稱已經存在就覆蓋)
>& 把STDOUT+STDERR寫入新檔案(如果檔案名稱已經存在就覆蓋)
2> 把STDERR寫到檔案(如果檔案名稱已經存在就覆蓋)
>> 把STDOUT結果接續在檔案的尾端(如果檔案不存在就建立)

$ ./a.out > hello
$ ./a.out >> hello

| 管線字元可以將左邊指令或程式的輸出(stdout)變成右邊指令的輸入(stdin) 可以很方便的將不同指令寫在同一行

$ ./a.out | less

注意這個跟>不同的地方在於>是將output寫到檔案,而|則是將output當作另一個指令的stdin
兩者左邊都是接受一個指令或程式,但>右邊一定是檔案,|右邊則是另一個指令或程式

< 相較於>是把右邊檔案當作左邊指令的標準輸出(stdout),<則是把右邊檔案當作左邊指令的標準輸入(stdin),兩者可以連用

$ ./a.out < input > output

echo: 輸出文字,不搭配重導向使用就會直接輸出到stdout

$ echo Welcome to Foresight Camp 2021 \OWO/
$ echo hello judgegirl > hello
$ echo hello world >> hello

diff: difference,比較兩個檔案不同的地方,如果前面有pipe的話可以把一個設成-代表該檔案

$ diff sample_output my_output
$ ./a.out | diff sample_output -
$ diff < (./a.out < in.txt) out.txt

sort: 將檔案內容以行為單位根據字典序排序並輸出(不會更改檔案本身)
常用參數:

  • -r: reverse,反向排序
  • -f fold lower case to upper case,忽略大小寫差異
  • -n numerical value,按照數值大小排序
$ sort data
$ sort data > sorted_data

uniq: unique,以行為單位,將檔案中相鄰且重複的內容刪除到只剩一行並輸出(例如有連續五行內容完全一樣,就把四行刪掉),並不會更改檔案本身,常搭配sort使用
常用參數:

  • -c: count,進行計數
  • -i: ignore case,忽略大小寫差異
  • -u: unique,只輸出完全沒有相鄰重複的
$ sort data | uniq > unique_file
$ sort data | uniq -u > uniq_file

簡易正規表達式(Regular Exxpression, Regex)

主要是拿來match一個字串有沒有符合特定規則
*: 前面的字出現任意次數(包含0次)
+: 前面的字出現一次以上
?: 前面的字出現0次或1次
.: 一個任意字元
\: 跳脫字元,把接在後面的字當作一般字元使用
[]: 代表任一括號內的字元
^: 代表字串的開始位置
$: 代表字串的結束位置

ex:
AC\.c AC.c (前後還可以加東西)
AC?\.c AC.c以及A.c (前後還可以加東西)
AC*\.c A.c, AC.c, ACC.c ... (前後還可以加東西)
AC[1-3]\.c AC1.c、AC2.c、AC3.c (前後還可以加東西)
^AC\.c AC.c AC.cpp AC.csv ... (後面還可以加東西)
AC\.c$ AC.c, AAC.c, BAC.c ... (前面還可以加東西)
AC_.*\.c .* 可以是任何內容,可以代表AC_123.c, AC_ac.c等等

Shell中的萬用字元*在正規表達式中相當於.*,也就是任意字元出現任意次數的意思

grep: global regular expression print,從檔案中(沒有檔案就是stdin)找出符合指定字串的那些行並輸出,字串可以不用加引號,或是用regex的語法加引號(只是記得加上-E)

$ grep A+ student_grades | wc -l 從student_grades中計算A+的人數 
$ grep B10902* workstation_usage | sort | unique -c 從workstation_usage中,找出B10的使用者,在排序後輸出每人使用次數
$ ls -l /nfs/undergrad/10 | grep -E "^d[rwx]r" 看家目錄有開可以讀的權限的B10

sed: stream editor,文字串流編輯器,語法是s/origin/replace/g,一個斜線都不能少(s代表substitute,g代表global,不加g代表取代遇到的第一個origin)

$ cat letter > sed 's/love/hate/g' 把love用hate取代
$ car spaces > sed 's/^ *//g' 去除行首空白

壓縮/解壓縮

  • zip 檔
  • 加上 -e代表加密壓縮
    $ zip -r <name.zip> dir/ -r 把dir裡面所有檔案壓縮成name.zip
    $ unzip <name.zip> -d dir/ 把name.zip的檔案解壓丟到dir
    $ zip -r 2021.zip 2021_code/ -r -e
    $ unzip 2021.zip
    
  • tar 檔: 只有打包,沒有壓縮
    $ tar cvf <FileName.tar> dir/ 打包
    $ tar xvf <FileName.tar> 解包
    
  • tar.gz 檔
    $ tar zcvf <FileName.tar.gz> dir/ 壓縮
    $ tar zxvf <FileName.tar.gz> 解壓縮
    

gcc: GNU Compiler Collection,Unix-like作業系統的標準編譯器,在工作站上寫C的程式可以用gcc將原始碼編譯成執行檔
常用參數:

  • -o name: 自訂執行檔名字 預設為a.out
  • -g 讓產生的執行檔可以用GDB debug
  • -Dxxx 可以定義程式裡的xxx(關鍵字: ifdef endif)
  • -O[n] 可以做出不同等級的優化,n = 0 ~ 3, 常用是-O2
  • -Wall 顯示所有警告訊息(沒有初始化的變數、重複宣告的變數、沒被使用的變數等等),debug比較容易知道錯在理
  • -std=c99 等號後面為指定編譯器標準
$ gcc 12345.c
$ gcc problemA.c -o AA -O2 -Wall -std=c11
$ gcc defpractice.c -Ddef

執行檔案

在Linux系統,對於檔案或目錄名稱沒有特殊要求,所以不用像在Windows終需要.exe副檔名代表它的檔案格式,如果想要執行名為filename的檔案,只要在前面打./即可
$ ./filename
可執行的檔案在用ls列出時,檔名會呈現綠色且檔名後面顯示*

time: 替某個指令/程式計時,會有三種時間(real/user/sys),評估程式效率是看user time,real time可能因為工作站忙碌而被拉長

  • real time: 程式從執行開始到執行結束在錶上相差的時間
  • user time: 程式碼不需要消耗系統資源的部份所使用的CPU時間
  • system time: 程式碼需要消耗系統資源的部份所使用的CPU時間
  • user time + system time: 不一定會小於/等於/大於real time
$ time wc problem[1-9].c
$ time ./a.out < sample_input

make: 搭配makefile使用

$ make
$ make clear

tmux: 終端機的多工器,可以同時跑好幾個程式,也可以把程式丟到背景跑,輸入tmux就可以開始使用了,如果tmux不用了,exit即可,否則ctrl+B+D可以回到原本的terminal
常用的有:
tmux ls 看現在有哪幾個在跑
tmux attach -t x 其中x是session編號,可以直接進去那個session,而attach可以直接打a就好










Related Posts

[筆記]ASIC Flow 01-ASIC是什麼?

[筆記]ASIC Flow 01-ASIC是什麼?

[C#] dll tool

[C#] dll tool

一百種想法

一百種想法


Comments