# 程式設計 linux環境配置
![](https://i.imgur.com/FVFE5Zi.png)
## 原因
為何會需要使用到終端機這樣原始的環境?而不使用window系統上的IDLE,如DEV-C++/CODE:BLOCK等?
* 包好的IDLE,若程式牽涉到較多原理、組語等內部結構,會難以調整
* 介面醜到不行,效率很差,背景純白如果長時間打code眼睛會爆掉
* 開IDLE速度很慢,每新寫一段code就要新增一堆東西,效率很差,此外,如果IDLE(整合式開發環境)開的速度慢,你就不會有事沒事去開他了,而是「真正刻意」要寫程式才會去開他,是吧?
* 練題目,測資大,你會輸入到想死
* 我只能說,非常難看,看起來又很LOW,當然,如果你使用輕量級的Text editor沒話說,如sublime
## 優點
* 不會為了一個程式語言而去裝一個IDLE,如py裝pycharm或python原版的直譯器,c++/c裝dev-c++,java裝eclipse...你並不會因為語言的轉換而去更改你的環境
* 更加了解原理,而且比較能掌控程式
* 速度快、開啟速度超快、效率較高
* 使用linux的terminal環境,根本不只寫程式這件事情能做呢
* 若你使用原生的文字編輯器,如vim, emacs, nano,你可以透過遠端連線,用手機、電腦,或用電腦連手機都可以,在學校電腦遠端連自己電腦,而不需要重新設定你的環境
* 如果你靠資訊吃飯,用IDLE......Well, 也許他自動補全很方便,但他速度真的爆慢,而且很多事情在vim也做的到,速度、效率還更高,emacs也做的到
## 缺點
* 針對window的使用者,配置較麻煩
* 針對linux使用者隨開隨用
* 針對mac使用者也是隨開隨用
## Window的配置選擇
* VM 虛擬機
* 電腦效能需高些
* Lag是常態
* 隨身碟灌linux
* 隨身碟開機操作會比較lag
* 安裝較難,雖然我不覺得會很難...
* WSL
* 有幾種配置,像是cmder+wsl/VS+wsl
* 本篇筆記會提供cmder+wsl的文章和隨身碟linux文章
## 文章教學
* [VM 虛擬機](https://drive.google.com/file/d/1aHr1PgaoDi_LzIkcXLFK9XZcipBXY6aB/view?usp=sharing)
* 10801程式設計-A班助教品新學長 製作
* [Repl 線上寫code](https://repl.it/~)
> 可以直接線上寫code,也可選編輯器vim/emacs/預設,環境為ubuntu,常用的套件都有裝,像是git, g++, gcc, grep等等
* Docker
> 比起上面的VirtualBox,個人比較推薦這個,簡單而言,他就是個輕量級的VM,精確來說模擬機是割捨自己的硬碟空間,去佈署專屬於自己的OS環境,而Docker則是可以建立多個container,共享一個OS核心,詳細使用方法可問GOOGLE
<br>
* 隨身碟灌Linux (第二推薦)
* **[隨身碟LIVE](https://blog.xuite.net/yh96301/blog/450717778-Ubuntu+18.04%E8%A3%BD%E4%BD%9CLive+USB%E9%9A%A8%E8%BA%AB%E7%A2%9F%E7%9A%84%E8%BB%9F%E9%AB%94rufus)**
* **[灌LINUX](https://blog.gtwang.org/linux/install-ubuntu-linux-to-usb-stick/)** <br><br>
> 你要準備兩個隨身碟\
> 一個是廢棄不需要用到的,容量小沒關係\
> 另一個是效能較好容量大的隨身碟,linux會裝在裡面
<br>
* ==WSL+Cmder教學 (個人推薦)==
* **[主要文章](https://medium.com/hungys-blog/windows-subsystem-for-linux-configuration-caf2f47d0dfb)**
* [參考文章](https://blog.miniasp.com/post/2015/09/27/Useful-tool-Cmder)
## 初次使用教學
### 終端機如何更新
* Update (先更新套件的網址清單)
```bash
$ sudo apt-get update
```
* Upgrade (再按照網址清單,去更新套件)
```bash
$ sudo apt-get upgrade
```
### 安裝
* python (p.s 你要寫python的話再裝)
```bash
$ sudo apt-get install python
```
> sudo代表super do,也就是以超級使用者的權限(提高權限)的意思,後面apt-get是套件安裝普遍會使用到的字眼,install代表安裝,後面接python就是安裝python,他會自動幫忙裝好
* C++
```bash
$ sudo apt-get install g++
```
* C
```bash
$ sudo apt-get install gcc
```
* Makefile
```bash
$ sudo apt-get install make
```
> 拿來編譯很方便,建議裝一下 \
> 此外,你會發現,其實安裝就只是同樣一串文字,後面加上自己要裝的東西而已
---
### 文字編輯器
#### 題外話
> 意即,幫助文字編輯的介面,但很多人不清楚 <br>
> 老手常用的有vim, emacs,兩者間還有 神之編輯器之戰 <br><br>
> vim 被稱為**編輯器之神** \
> emacs 也被稱為 **神之編輯器** <br><br>
> 順帶一提,個人很愛vim,emacs很不喜歡,因為他沒有mode模式,雖然你輸入很方便,但要移動,或做任何操作,為了不要讓鍵盤一按就馬上鍵入文字,需要用到Ctrl或Alt鍵,然而,每個按鍵組合一定要按這兩個東西加其它按鍵,個人覺得非常不方便,效率很差 <br> <br>
> 當然,emacs有他厲害的地方,他擴展性很高,並且能在上面做任何事情,包括小遊戲、開pdf檔、網頁瀏覽等等,但我認為文字編輯方面他還不是那麼優秀<br><br>
> vim我認為是最強大的文字編輯器,不使用任何插件只配置number, autoindent等等,他效率已經非常高,幾乎到達眼到鼠標到的境界,雖然學習成本蠻高的,但在很多地方都用的到,在每個linux系統都是內建的文字編輯器,編輯效率極高<br><br>
> 然而,加上插件他會更恐怖,包含自動補全、括號匹配,全部都做的到,對了,我這篇文也是用vim寫markdown語法所做的哦
---
#### 可使用
**終端機環境**
* Vim
* emacs
* Nano
> 對於初學者而言,nano簡單好入手\
> 能夠使用nano進行簡單文書操作後,推薦學vim,效益很高\
> 當然,學習曲線也是很高啦...<br><br>
網路上,流傳這麼一張圖...
![](https://i.imgur.com/6j1D8Dl.png)
**非終端機模式**
* Gedit
* Sublime
* Visual Studio(簡稱VS)
* Visual Studio Code (又稱VS CODE)
* mousepad
* notepad
* etc.
> 上述最常有人用的就是Sublime跟VS了,不過個人是vim狂人不怎麼用那些東西,非終端機模式最大問題就是要額外開一個視窗,開啟可能要一些時間<br><br>
> 此外如果配置好了在其它電腦上卻要重新配置,終端機的文字編輯器則可以直接用ssh, putty等東西遠端連到自己電腦
---
### 程式執行教學
前情提要,在終端機下有幾個指令能用
* ls
> 即list的意思,列出目前目錄下的所有檔案\
> 後面+ -a 可顯示隱藏檔案/-l 會顯示詳細資料
![](https://i.imgur.com/xq49zSI.png)
* pwd
> 列出目前路徑位置\
![](https://i.imgur.com/VwC43al.png)
* chmod
* 改變權限\
![](https://i.imgur.com/MiBBInm.png)
* 我想讓Makefile可以執行,於是...
```bash
$ sudo chmod +x Makefile
```
![](https://i.imgur.com/zMVIsx9.png)<br><br>
**其它指令**
|指令|用途|備註|
|:--|:--|:--|
|rm|移除檔案|rm [filename]|
|mkdir|新增目錄|mkdir [dirname]|
|cd|切換目錄|cd 路徑/絕對路徑|
|cat|抓取檔案內容顯示於終端機上|cat [filename]|
|cp|複製檔案|cp [filename 1] [filename 2]|
|mv|重新命名或移動檔案|mv [filename 1] [filename 2]|
---
**C語言篇**
* 新增檔案\
![](https://i.imgur.com/LYa30py.png)
* 隨便寫個程式\
![](https://i.imgur.com/MZ2qnft.png)
* 編譯\
![](https://i.imgur.com/QDh0Vs1.png)
* 你可以選擇編譯時不加-o,如下:
![](https://i.imgur.com/hlTCCHF.png)\
會產生的是a.out檔案
* 多一個檔案(可執行檔)\
![](https://i.imgur.com/XV1rBNT.png)
* 執行\
![](https://i.imgur.com/TJCcDro.png)
<br> <br>
* 此外,這邊要介紹一個方法可方便編譯程式
* 新增檔案 Makefile\
![](https://i.imgur.com/bHwqmqJ.png)
* Makefile內容\
![](https://i.imgur.com/cfiGgqC.png)
> 可以簡單寫成all:\
> 下面寫下想要執行的指令就好\
> 對了,前面的空格請使用tab而非空格,不然會出事哦!
* 輸入make\
![](https://i.imgur.com/bjKQgcz.png)
**test.c**
```c=
#include <stdio.h>
#include <stdint.h>
int main(){
printf("Hello World!\n");
return 0;
}
```
**Makefile**
```Makefile=
all:
gcc test.c -o test
```
---
**C++篇**
* 新增檔案&編輯檔案\
![](https://i.imgur.com/TU13G1L.png)<br><br>
* 編譯&執行檔案\
![](https://i.imgur.com/1tmLaI7.png)
---
**test.cpp**
```cpp=
#include <iostream>
#include <string>
using namespace std;
int main(){
string str;
cout << "Please enter a string: ";
cin >> str;
cout << str << endl;
return 0;
}
```
---
**Python篇**
* 新增檔案&編輯檔案\
![](https://i.imgur.com/AlhywEq.png) <br><br>
* 編譯&執行\
![](https://i.imgur.com/MOUljSa.png)
**<p>test.py</p>**
```python=
num = [int(e) for e in input('請輸入一連串的數字: ').split() ]
for i in range(len(num)):
print(num[i], end=' ')
print()
```
---
### 指令詳細用法說明
#### cd
* 即 change directory (切換目錄)
* **範例**
1. 切換目錄到 /usr/bin\
```$ cd /usr/bin```
2. 切換到上層目錄
```$ cd ../```
3. 切換到根目錄\
```$ cd```\
or \
```$ cd ~```
#### clear
* 同字面意思,清除終端機上的文字
#### exit
* 離開終端機(以任何型態使用,都是離開該環境的意思)
#### history
* 同字面意思,可查詢最近使用過的指令
* **範例**
1. 清除之前history的紀錄\
```$ history -c```
2. 刪除紀錄中指令編號的紀錄\
```$ history -d [number]```
3. 列出最近使用過的指令\
```$ history```
#### cp
* 即copy簡寫,可以複製檔案或目錄
* **範例**
1. 將檔案1 (filename_1) 複製為 檔案2 (filename_2)\
```$ cp filename_1 filename2```
2. 將 /tmp 目錄複製到當前目錄下\
```$ cp -r /tmp ./```
3. 複製檔案時保留原檔案的屬性\
```$ cp -p /usr/bin/passwd ./```
4. 來源檔案如果比目標檔案時間還晚,才覆蓋過去
```$ cp -u filename_1 filename_2```
|參數|敘述|
|:--|:--|
|-b|覆蓋之前會先備份檔案,備份檔案字尾會加上~|
|-f|強迫複製|
|-i|詢問模式,如果會覆蓋,則會先詢問操作者|
|-p|保留原始檔案之屬性(如範例)|
|-r|有r代表遞迴處理,複製目錄下所有檔案|
|-u|若來源檔時間較晚才覆蓋,否則不動作|
#### pwd
* pwd (print the working directory) $\to$ 列出目前所在目錄 (直接使用即可)
#### rm
* rm(remove),可移除檔案、目錄(若移除空目錄可用rmdir)
|參數|敘述|
|:--|:--|
|-f|(force),強制移除檔案或目錄|
|-i|(inquire),刪除之前會先詢問|
|-r|(recursive),遞迴處理,會將改目錄下所有檔案、子目錄都刪除|
* **範例**
1. 有些壞蛋會教你輸入 ```sudo rm -rf ~/``` \
先來說文解字一下,sudo代表用超級使用者權限執行這項指令\
$rm \to remove$ \
$rf \to force + recusive$ (強制移除+遞迴處理)\
~/ $\to$家目錄\
\
**因此,這個指令會把你家目錄下所有檔案都刪掉,千萬不要執行**
2. 刪除當前目錄下名稱為 test.c的檔案,刪除之前還會詢問你\
```rm -i test.c```
#### mv
* 即move,可以移動檔案或目錄,移動前後可以取不同的名字,因此也可以拿來當作改變名稱的指令
> 經過上面的指令介紹相信大家很清楚如何操作了\
> 因此下表就直接騰列參數表
|參數|敘述|
|:--|:--|
|-b|(backup),目標檔案若存在,覆蓋時會備份原本的目標檔,名稱後方加上~|
|-f|(force),強迫執行|
|-i|(inquire),覆蓋前會詢問|
|-u|若來源檔時間比較新才會覆蓋,反之不會執行|
#### ls
* 即list,列出檔案或目錄
|參數|敘述|
|:--|:--|
|-a|列出所有檔案(包含隱藏檔)|
|-C|使用欄位排列顯示清單|
|-f|不按照字母排序,而是按進入磁碟的順序排序|
|-h|用容易閱讀的方式顯示檔案大小,像是MdB replaced by M|
|-k|用KB列出檔案大小|
|-l|列出長清單(比較仔細)|
|-m|水平排列顯示每個指令,指令間用逗號區隔|
|-n|使用者名稱、群組名稱分別用UID, GID來取代(代號)|
|-r|以字母的相反順序列出|
|-R|遞迴處理,列出目錄以及子目錄的所有檔案|
|-t|按照檔案最後**修改時間**列出|
|-u|按照檔案最後**存取時間**列出|
|-Z|查看SElinux標籤|
#### man
* 即manual(使用手冊),在linux上,有不熟的指令可以用這個指令來查詢哦!
|參數|敘述|
|:--|:--|
|-a|原本預設只顯示一個章節,此參數會列出所有章節(類似ls -a的意思)|
|-K|顯示所有和該名稱有關的線上說明檔案|
|-w|僅顯示說明檔的位置|