# Linux 使用筆記 [TOC] --- ## 打開終端機: 使用鍵盤輸入: Ctrl + Alt + T ## 一些簡單指令: ### 知道當下的路徑: ```bash= $ pwd ``` ### 列出當下所在路徑的所有檔案及資料夾: ```bash= $ ls # 以樹狀表示: $ tree ``` ### 印出文字/創建檔案: ```bash= # 印出文字 $ cat 檔名 # 創建檔案 $ touch 檔名 ``` ### 建立新目錄: ```bash= $ mkdir 資料夾名稱 # 同時建立許多目錄在同一層: $ mkdir 目錄1 目錄2 目錄3 # 建立多層目錄: $ mkdir -p /目錄1/目錄2/目錄3 #-p:parent #若目錄1本來就存在,但沒有目錄2及目錄3,則會在目錄1下先建立目錄2,再建立目錄3 ``` ### 切換工作目錄: ```bash= #相對路徑(切換至當下目錄中已存在的目錄) $ cd 目錄名稱 #絕對路徑(需要完整的輸入路徑,可以一次多層移動) $ cd /home/username/Documents/dir1/dir2 #返回上一層目錄 $ cd .. #返回兩層目錄(以"/"分割..) $ cd ../.. #切換到上一層目錄中其他的子目錄 $ cd ../子目錄名稱 #改回上一個更改前的目錄 $ cd - #回到家目錄(即/home/username): $ cd ~ ``` ### 刪除檔案或目錄: ```bash= # 刪除單一檔案: $ rm 檔案名稱 $ rm -i 檔案名稱 #刪除前會先詢問是否刪除此檔案 $ rm -f 檔案名稱 #強制刪除 -f:force # 刪除空目錄: $ rm -d 目錄名稱 #內部不能有東西才能刪除 # 刪除該目錄及以下所有的檔案及子目錄: $ rm -r 目錄名稱 #-r:recursive ``` ### 複製檔案: ```bash= $ cp 路徑/檔案名稱 /目的地的路徑/(檔案名稱[若要改名]) ``` #### 舉例說明: 例子1. 在share下建立dir1與dir2,在dir1下建立test,將其複製到dir2,並改名為temp ```bash= $ mkdir dir1 dir2 $ cd dir1 $ touch test $ cp test ../dir2/temp ``` ![](https://i.imgur.com/qK87OKb.png) 例子2. 在share下建立dir1與dir2,在dir1及dir2下都建立test,將dir1的test複製到dir2 ```bash= $ mkdir dir1 dir2 $ cd dir1 $ touch test $ cd ../dir2/ $ touch test $ cd ../dir1/ $ cp -i test ../dir2/ #用參數"-i"時,當複製檔名一樣時會提出警告 ``` ![](https://i.imgur.com/khFjtGx.png) 例子3. 複製所有dir1目錄下的所有檔案至dir2 ```bash= $ mkdir dir1 dir2 $ cd dir1 $ touch test1 test2 test3 $ cp -r * ../dir2/ ``` ![](https://i.imgur.com/6HArF53.png) ### 移動檔案或重新命名: ```bash= $ mkdir dir1 dir2 $ cd dir1 $ touch test $ mv test temp #改名 $ mv temp ../dir2/ #移動 ``` ![](https://i.imgur.com/3HMgHSq.png) ## Vim: 共有三種模式,分別為一般指令模式(command mode)、編輯模式(insert mode)、指令列命令模式(command-line mode) ### 一般指令模式(command mode) ### 編輯模式(insert mode) ### 指令列命令模式(command-line mode) ## C語言: 在linux系統上使用GCC編譯器,將C的程式碼編譯為執行檔 ### 編譯C code: 寫好一支C code 如下並命名為helloworld.c: ```c= #include <stdio.h> int main(){ printf("hello world\n"); return 0; } ``` 執行gcc的命令將其轉為執行檔: ```bash= #編譯C code $ gcc helloworld.c ``` gcc會直接產生一個**a.out**的檔案,現在來執行程式: ```bash= #執行gcc編譯完成的程式 $ ./a.out ``` 輸出: hello world ### gcc 其他參數使用 --- 若要指定輸出執行檔的名稱,加上"-o"這個參數即可: ```bash= #編譯helloworld.c這個檔案,並將執行檔改名為hello $ gcc -o hello helloworld.c $ ./hello ``` --- 若要編譯時加上除錯的功能,加上"-g"這個參數即可,為gdb除錯的意思 ```bash= $ gcc -g helloworld.c ``` 舉例說明,寫好一支C code如下,使用gcc -g的除錯功能: ```c= #include <stdio.h> int main(){ printf("hello world\n"); return 0 #(故意忽略此處的分號) } ``` ```bash= $ gcc -g helloworld.c ``` ![](https://i.imgur.com/XJObvn8.png) --- 若要加上編譯時出現的警訊(warning),則需要加上"-Wall"這個參數,一定要大寫! 舉例說明,寫好一支C code(testwall.c)如下,使用gcc -Wall的警訊功能: ```c= #include <stdio.h> void main(){ int a=0.01; return 3; } ``` ```bash= $ gcc -Wall -o testwall testwall.c ``` ![](https://i.imgur.com/BRPIZ97.png) (通常在編譯的時候最好都加上-Wall -g 去檢視自己的code) --- 若只想要編譯且不需要進行連結,那可以使用 -c 這個參數,將會產生.o的檔案供日後使用。假如現在有hello.c的檔案,若要將其轉換成目標檔: ```bash= gcc -c hello.c ``` ## Makefile: 在寫程式的時候,可能會有許多副程式,或是標頭檔,那在編譯時,要如何將他們串接起來呢?倘若編譯完成後,需要修改內部某一個檔案,並不需要重新編譯所有的檔案,只要該程式有連結到的檔案編譯即可。make便是幫我們解決這個問題的好幫手,因此我們可以透過makefile粗略了解該程式的架構為何。 一般來說makefile的架構如下: ```bash= target: dependencies command ``` target為目標文件要將其編譯為什麼東西,而dependencies則是要告訴電腦這個target會依賴於那些文件,而後在下一行加上一個tab鍵後,輸入要對其做的命令即可。 ### 簡單的Makefile實作1: 假設現在有一個hello.c如下: ```c= #include <stdio.h> int main(){ printf("Hello world\n"); return 0; } ``` 那我們想要使用makefile去編譯他,所以要建立一個名為makefile的檔案,而內部要寫入要對這個hello.c所做的事。makefile如下: ```makefile= hello:hello.c gcc hello.c -o hello clean: rm -f hello ``` 因為只有編譯一個hello.c檔,因此在linux終端輸入make時,便會執行gcc hello.c -o hello將其編譯為一個hello的執行檔案,而後輸入make clean時,便會將hello刪除。 ### 多程式的Makefile實作2: 接著我們要在main.c這個檔案中使用其他的.c檔的function,那要如何撰寫makefile呢?先來看看這幾個.c檔: main.c ```c= #include <stdio.h> #include "tool.h" int main(){ int array[5]={1,8,3,4,5}; int max=findMax(array, 5); printf("max=%d\n", max); return 0; } ``` 可以看到使用了外部程式"findMax"的function。及include了tool.h。 tool.c ```c= #include "tool.h" int findMax(int array[], int size){ int max=array[0]; for(int i=0;i<size;i++){ if(array[i]>max) max=array[i]; } return max; } ``` 在這邊定義了"findMax"的function,將其寫入tool.h,使得在main.c這個檔案中可以被呼叫。 tool.h ```c= int findMax(int [], int); ``` 一般在linux的terminal若要編譯上面的這兩個程式(main.c tool.c)為一個執行檔(main),需要輸入: ```bash= gcc -g -Wall main.c tool.c -o main ``` 倘若程式的規模變大,這樣又臭又長的編譯指令真的令人心煩,此外,若修改內部的一個分支的程式,所有程式都需要重新編譯一次,因此這時候我們便需要makefile來建立依賴關係,並且精簡編譯指令。因此這個例子的makefile可以這樣寫: ```makefile= main: main.c tool.o gcc -g -Wall main.c tool.o -o main tool.o: tool.c gcc -c tool.c clean: rm *.o main ``` 在第一行,我們告訴編譯器要產生一個名為main的執行檔,而與該執行檔有關的檔案是main.c及tool.o,而後在第二行輸入要如何對其編譯。當編譯器在執行這邊的時候會發現尚未找到tool.o這個物件檔,因此會往後尋找tool.o這個檔案要如何產生,因此便會看到第4行,可以看到tool.o的依賴關係為tool.c,是透過tool.c編譯而成的物件檔。因此我們在linux終端輸入make時,執行順序應為: ```bash= gcc -c tool.c gcc -g -Wall main.c tool.o -o main ``` 先將tool.c編譯但不連結成為tool.o的物件檔,在將其與main.c一同編譯為main的執行檔。 ### 多程式的Makefile實作3: 剛剛的實作2是呼叫一個外部寫好的function而已,這次來試看看呼叫兩個: main.c ```c= #include <stdio.h> #include "max.h" #include "min.h" int main(){ int array[5]={1,8,3,4,5}; int max=findMax(array, 5); int min=findMin(array, 5); printf("max=%d\n", max); printf("min=%d\n", min); return 0; } ``` max.c ```c= #include "max.h" int findMax(int array[], int size){ int max=array[0]; for(int i=0;i<size;i++){ if(array[i]>max) max=array[i]; } return max; } ``` min.c ```c= #include "min.h" int findMin(int array[], int size){ int min=array[0]; for(int i=0;i<size;i++){ if(array[i]<min) min=array[i]; } return min; } ``` 那makefile要如何寫呢?先觀察彼此間的依賴關係main.c需要呼叫max.c及min.c的function,因此makefile寫法如下: ```makefile= main: main.c min.o max.o gcc -g -Wall main.c min.o max.o -o main min.o: min.c gcc -c min.c max.o: max.c gcc -c max.c clean: rm *o main ``` ### 多程式的Makefile實作4: 透過上面的三個實作應該對makefile比較了解了,但是上面的那種寫法僅能產生一個執行檔而已,倘若我需要產生兩個執行檔那要如何寫makefile呢? 我們將上面寫的兩個findMax及findMin兩個function分別在main_max.c及main_min.c中呼叫,並分別產生兩個main_max及main_min的執行檔。 main_max.c ```c= #include <stdio.h> #include "max.h" int main(){ int array[5]={1,8,3,4,5}; int max=findMax(array, 5); printf("max=%d\n", max); return 0; } ``` main_min.c ```c= #include <stdio.h> #include "min.h" int main(){ int array[5]={1,8,3,4,5}; int min=findMin(array, 5); printf("min=%d\n", min); return 0; } ``` 那根據上述規則我們應該可以寫出的makefile如下: ```makefile= main_max: main_max.c max.o gcc -g -Wall main_max.c max.o -o main_max main_min: main_min.c min.o gcc -g -Wall main_min.c min.o -o main_min max.o: max.c gcc -c max.c min.o: min.c gcc -c min.c clean: rm *.o main_max main_min ``` 實際執行會發現仍然只有產生一個名為main_max的執行檔,而終端只有執行了兩行: ```bash= gcc -c max.c gcc -g -Wall main_max.c max.o -o main_max ``` 原因是在第一行尋找main_max的依賴關係時,與main_min根本沒有相關,因此在編譯完main_max之後便結束了,要解決這個問題只需要在最上面加上所有要編譯的執行檔名稱即可,因此makefile改為: ```makefile= all: main_max main_min main_max: main_max.c max.o gcc -g -Wall main_max.c max.o -o main_max main_min: main_min.c min.o gcc -g -Wall main_min.c min.o -o main_min max.o: max.c gcc -c max.c min.o: min.c gcc -c min.c clean: rm *.o main_max main_min ``` 那麼輸入make後可以看到執行了: ```bash= gcc -c max.c gcc -g -Wall main_max.c max.o -o main_max gcc -c min.c gcc -g -Wall main_min.c min.o -o main_min ``` 也就成功的產生兩個main_max及main_min的執行檔了。 ### Makefile實作5-使用變量: 在上面的makefile實作中,可以發現我們一直使用到gcc 或是在編譯時使用的參數-g -Wall等等,我們可以將其視為一個變量,要使用時以$(變量名稱)使用即可。 以實作4的makefile為例子: ```makefile= all: main_max main_min main_max: main_max.c max.o gcc -g -Wall main_max.c max.o -o main_max main_min: main_min.c min.o gcc -g -Wall main_min.c min.o -o main_min max.o: max.c gcc -c max.c min.o: min.c gcc -c min.c clean: rm *.o main_max main_min ``` 我們可以將其改為: ```makefile= CC = gcc CFLAGS = -g -Wall all: main_max main_min main_max: main_max.c max.o $(CC) $(CFLAGS) main_max.c max.o -o main_max main_min: main_min.c min.o $(CC) $(CFLAGS) main_min.c min.o -o main_min max.o: max.c $(CC) -c max.c min.o: min.c $(CC) -c min.c clean: rm *.o main_max main_min ``` 改成以變量使用可以去掉重複修正的問題,並且較容易閱讀,也能達到同樣的功能。此外,也能夠透過閱讀makefile快速搞懂整個程式的架構及編譯流程。 ## python: ### 創立虛擬環境 為了讓專案之間不要彼此汙染並且能夠有一個乾淨的環境,python提供一個創立virtual enviromnent的方法。 1. 在.bashrc加入這一行 (我還不知道什麼意思><) <- SO CUTE ``` export PATH="$HOME/.local/bin:$PATH" ``` 2. 下載virtualenv ``` $ pip install virtualenv ``` 3. 進到要創立虛擬環境的目錄底下 4. 創立它 (輸入以下兩個指令都可以,但我還不知道差別><) ``` $ python3 -m venv venv ``` ``` $ virtualenv -p python3 venv ``` 5. 啟動環境 ``` //in bash: $ source ./venv/bin/activate //in csh/tcsh $ source ./venv/bin/activate.csh ``` 6. 關掉環境 ``` $ deactivate ``` 7. 就可以在這個環境裡為所欲為了 ``` $ pip list ``` ## git使用: ## Atom(文字編輯器)使用: ## 聊天區: 我打玩了! 還有什麼更詳細的會再補充Xd 借我當成做筆記的地方哈哈 晚安! 好啊 晚安