---
# System prepended metadata

title: CMD101 & GIT101

---

# CMD101 & GIT101

# Command Line Interface
與電腦溝通的工具, 屬於純文字介面，與我們平常熟悉的圖形化使
用者介面不同Graphical User Interface(GUI)

## 基本操作
我們可以利用`git bash`來實際執行我們的CLI介面

### pwd (print working directory)
印出目前所在位置
![](https://i.imgur.com/VQdQATS.png)

### ls
印出現在位置的檔案清單
`-al` 會印出所有的資料例如檔案權限、檔案大小
![](https://i.imgur.com/6A11kky.png)

### cd (change directory)
切換資料夾 
1. `cd 資料夾名稱`
2. `cd ..` 回到上一層

### man
指令使用手冊，介紹指令的使用方式
例如: `man ls`

## 檔案操作

### touch
建立檔案與更改檔案時間
![](https://i.imgur.com/iDh92ZQ.png)

### rm
可以刪除你要的檔案
![](https://i.imgur.com/vlHnvXs.png)

如果要刪除資料夾的話在後面加`dir` ->  `rmdir 資ㄦ料夾名稱`
也可以用 `rm -r 資料夾名稱` 
參數`-f`則是強制刪除 **(小心使用)**

### mkdir
建立資料夾
![](https://i.imgur.com/1AV6YMo.png)

### mv(move)
移動檔案或是改名
![](https://i.imgur.com/hwJUb9u.png)
`mv 檔案名稱 ..`把檔案移到上一層

### cp (copy)
複製檔案或者資料夾
![](https://i.imgur.com/vIAUObr.png)
如果要複製資料夾的話則需要多使用一個參數`-r`
![](https://i.imgur.com/Bm9s2D1.png)

### grep
抓取關鍵字
![](https://i.imgur.com/TRV7h1F.png)

### wget
下載檔案

### curl
送出 request
我們可以利用`curl API網址`，電腦就會利用get方法把respond給展示出來。因此可以用來測試API

## redirection (>)
利用`>`把input/output給重新導向
![](https://i.imgur.com/rBMtMsn.png)
以這個例子，我們就利用`>`把資料重新導向到list_result的這個檔案裏面，並且如果再重新導向到同一個檔案`>`會把後面之前的內容全部覆蓋掉
![](https://i.imgur.com/0LAr374.png)

如果我們要新增資料的話則是用兩個箭號 `>>`代表append的意思
![](https://i.imgur.com/vrotuHO.png)

## pipe (|)
可以把左邊指令的輸出變成右邊指令的輸入
![](https://i.imgur.com/zmvBlNo.png)

# Vim
Vim 是一個文字編輯器，可以直接輸入`vi`就可以呼叫之
`vim 檔案名稱`
就可以進入編輯，如果要插入文字的話需要先輸入`i`，讓見面進入到編輯模式，按`esc`可以返回到普通模式，這時候就不能插入文字，只能刪除或者複製貼上。
離開的話則是輸入`:q`的指令，即可離開，而`:wq`則會儲存後再離開

`cat 檔案名稱` 則可以顯示檔案的文字內容


# Git
Git 是⼀種分散式版本的版本控制系統，就像是我們以前做報告時，會把一份報告根據不同的更改紀錄而有不同的名稱，一個檔案會有不同的版本，我們希望能夠把這些版本都保存起來
![](https://i.imgur.com/75Tei8x.png)
我們這樣做會難以照到報告之間的關係是什麼，很難以得知哪一個檔案是根據哪一個為基底去做更改。因此當檔案量很多的話，我們就會希望有一個版本控制的系統來幫助我們使用

在團隊上，一個軟體的開發會有不同的分支，要從某一個版本切出不同的分支，再由這些分支合併
![](https://i.imgur.com/kMcylrx.png)

版本控制的流程:
1. 需要一個新版本時: 開一個資料夾，把資料放進去
2. 不想加入版本控制: 不要加入資料夾
3. 避免版本號衝突: 用看似術數的東西當作資料夾名稱
4. 知道位新版本: 用一個檔案來存
5. 會有個檔案來記錄歷史順序

通常我們是開一個新的branch 來做專業，為了保持master的穩定而不直接在master上面操作
## Git 指令

### git init
對我們的專案使用git這個軟體，主要⽬的是要讓 Git 開始對這個⽬錄進⾏版本控制。
![](https://i.imgur.com/Fn6P8wS.png)
這個指令會在這個⽬錄裡建立⼀個 .git 隱藏⽬錄，整個 Git 的需要的東西都在這個⽬錄裡。
![](https://i.imgur.com/jreNRN7.png)

### git status
查看目前版本控制的狀態
![](https://i.imgur.com/lxLwepA.png)

### git add
把我們想要的檔案加入倒版本控制中，而加入的同時我們可以看他們的狀態。如果出現
- untracked: 表示沒有加入到版本控制
- staged: 已經加入到版本控制，但還沒有正式加入倒新的版本
(changed to be committed 這區塊) 
![](https://i.imgur.com/mu7P2RO.png)

如果有很多檔案要加入的話，可以輸入 `git add .`，就可以一口氣把所有的檔案都加入到版本控制，也可以輸入資料夾名稱，把資料夾的所有檔案都加入版本控制
![](https://i.imgur.com/DbMCsoS.png)

要記得加入版本控制這個動作是每次都要做一次，才能接下來的`git commit`的動作
### git commit
新建一個版本，就像是新建一個資料夾，而它的名稱就是那一長串的亂碼編號
通常是在於完成一個小進度時再commit
![](https://i.imgur.com/rrD0LoK.png)
沒有成功是因為我們沒有commit message，因此要改為`git commit -m "要輸入的訊息"`
![](https://i.imgur.com/hdbCINo.png)
再來查看他的狀態是否已經有新的版本
![](https://i.imgur.com/GnD9fJf.png)

我們可以利用一個合併的語法，把`git add`和`git commit` 合併起來
`git commit -am "要輸入的訊息"`就可以把修改的檔案加入倒版本控制並且新建一個版本，但要記得她不會把新的檔案加入倒暫存區裡面

如果我們不小心訊息輸入錯誤的話，則可以利用`git commit --amend`來更改訊息
![](https://i.imgur.com/8DA6xZq.png)
![](https://i.imgur.com/fjlRuGh.png)

### git reset HEAD^
如果不想要這個commit時，想要收回可以利用`git reset HEAD^ --hard` 就會全部不見(包含改過的檔案)

![](https://i.imgur.com/3kBw3CM.png)

![](https://i.imgur.com/MkaG1s5.png)

![](https://i.imgur.com/7wWd8ba.png)
我們就把它移除了，因此git log的時候剛剛的commit完全不見
如果想要改過的檔案還在的話，可以用`git reset HEAD^ --soft`指令
![](https://i.imgur.com/kgh4NKa.png)

`HEAD^`: 上一個的意思，head指最前面的那個


### git log
可以用來查看歷史紀錄
![](https://i.imgur.com/kmFmA70.png)
`git log --oneling`: 可以顯示出比較簡短的歷史紀錄
![](https://i.imgur.com/sgeOG7Z.png)

### git checkout
可以回到過去的版本
`git checkout` 編碼: 回到那個狀態的檔案
`git checkout master` : 可以讓你回到最新的狀態

如果想要把檔案改回到還沒改過的檔案時，可以利用`git checkout --檔案名` 會回復到你上一個commit的狀態
![](https://i.imgur.com/DCFAutx.png)

![](https://i.imgur.com/uYLZwZV.png)

### .gitignore
可以把想要忽略的檔案放在裡面，可以想像這檔案會被排除在資料夾外
像我們之前的例子，有一個檔案test是我們不想要放進版本控制內的檔案(利入log紀錄檔或者作業系統的檔案，跟此專案本身沒什麼關係)，因此我們可以把要忽略的檔案放在.gitignore裡面，做完後記得這個檔案本身也要加入到版本控制內(因為其他專案的人也要看到是什麼檔案被忽略)
![](https://i.imgur.com/N3QuMSB.png)
![](https://i.imgur.com/VXssHcu.png)
(把test加入進去)


### git diff
可以看在你commit之前，做了哪些事情，看你這一次跟上一次的差別在哪

![](https://i.imgur.com/fTWdqJa.png)

## Branch
![](https://i.imgur.com/cdp5IQI.png)
一條線的開發模式，其實問題很大，因為沒辦罰同時處理很多事情，因為東西都在同一條commit上

![](https://i.imgur.com/PUw0wT3.png)
引進branch後，大家可以分工各做各的事情，平行開發，最後做完再把它們合併起來

再合併的部分其實就是把branch後面的分支拿下來，因為他們有共同的祖先，然而最麻煩的是兩個branch改道同一個檔案，會不知道要合併哪個檔案=> **conflict**
![](https://i.imgur.com/UgvnQS4.png)


### git branch
就像是複製一個資料夾近來
`git branch -v` 可以看到目前有哪些branch
再git裡面，master為主幹(最主要的分支)

如果要建立新的branch則輸入`git branch 名稱` 即可
![](https://i.imgur.com/Ybxdfc6.png)

刪除特定的branch `git branch -d 名稱`
NOTE:`-d` 通常都是刪除的意思

如果要改名的話可以用`git branch -m 新的名稱`來執行

如果要抓遠端branch的話則可以直接利用 `git checkout branch名稱` git就會直接把遠端的branch給抓下來

### git checkout
跟前面的checkout用法一樣
`git checkout branch-name`
![](https://i.imgur.com/B3knR3C.png)
我們讓這個分枝有個commit新的資料夾
![](https://i.imgur.com/trMBE8T.png)

### git merge
當我們在分支開發完後，需要合併回master
![](https://i.imgur.com/pb4MAqY.png)
指令: `git merge 名稱` 把新的分支**合併進去到master**
合併完後就可以把之前的那個branch給移除
![](https://i.imgur.com/c8VpKev.png)



conflict
假如在處理專案時，與同事同時更改到同一專案時，git會無法判別要使用哪一個檔案
![](https://i.imgur.com/KHNrfG6.png)


此時需要手動來解決，git會出現衝突並且此時出現的衝突在哪裡，自己可以手動解決，最後在commit 即完成
![](https://i.imgur.com/URlPjLs.png)
Head 代表目前所在位置的檔案，我們必須決定合併完的內容要長怎樣
![](https://i.imgur.com/hkThlvz.png)

# github
主要功能可以放git repository的地方，讓大家可以多人協作共用一個git的project
![](https://i.imgur.com/riGbBt5.png)
issue: 可以當作一個專案的討論區
contributor: 有誰跟你一起協作

pull request: 當有一個branch想要合併到另一個branch的時候，可以利用它來做審核，直接在上面可以看到有直接在上面可以看到那些檔案改變，並且給予建議以及合併

## 上傳code
首先直接點選github裡面的`new repository`
![](https://i.imgur.com/iKb2DHu.png)
接著跟著只是
```
git remote add origin https://github.com/impala8012/test1.git
git push -u origin master
```
把指令輸進去 就可以順利把檔案上傳進去
Note: 如果要複製貼上的話不能使用一般的Ctrl+c/+v
而是要用
```
Ctrl+ins  複製  
Shift+ins 貼上
```
![](https://i.imgur.com/iTajM2i.png)
![](https://i.imgur.com/kbuGJXb.png)

### git push 指令
利用push指令來把本地最新的改變給傳上去
![](https://i.imgur.com/SaJn08v.png)
Github這邊也上傳成功
![](https://i.imgur.com/Q5YFeHd.png)

此外也可以上傳一個branch
![](https://i.imgur.com/7fL7V9f.png)
![](https://i.imgur.com/A79sml4.png)

### git pull
如果有人改變了這個repository，我們要利用pull把這個改變給抓下來

首先假如我們在github裡面有座先更改
![](https://i.imgur.com/QQ4QaHo.png)
接著我們利用`git pull origin master`把最新的資料抓下來
![](https://i.imgur.com/UOP8Tcs.png)

### pull request
可以在github的介面裡合併兩個branch，並且會顯示兩個file中的變化
![](https://i.imgur.com/o3Y8ATF.png)
點選compare & pull request
![](https://i.imgur.com/yn6lSX2.png)
![](https://i.imgur.com/lKJ8ujh.png)
最後點選merge,並且可以delete branch
於是可以發現master branch已經把檔案給合併起來了
![](https://i.imgur.com/kZSBsAk.png)
通常都會在github上面利用pull request合併

### git clone
假如我們看到別人的repository不錯，我們可以利用git clone 把牠抓下來
![](https://i.imgur.com/ptsi6Rz.png)
可以複製裡面的網址然後輸入`git clone 網址`就可以把牠抓下來了
但是我們要注意這個是別人的repository，我們只能本地commit但不能push回去，因為我們沒有權限
如果要push上去的話，需要利用fork，把那個repository複製過來然後再重新clone一次
![](https://i.imgur.com/sV7k1zY.png)
最後也可以push回去了
![](https://i.imgur.com/B93dE9m.png)

## github pages
github製造一個免費的靜態網頁的空間

## github workflow
一個github的流程:
1. Create a branch
2. Add commits
3. Open a Pull Request
4. Discuss and review your code
5. Deploy
6. Merge

GitLab 與 Bitbucket有其他類似github的服務



## hook
在程式裏面的hook則代表發生某件事情的時候會通知我，可以偵測某些指令。例如有人commit時通知我或者有人push時通知我等等。

在我們.git的資料夾裡面有一個hook的資料夾

# Shell Script
shell script (程式化腳本)，是一個文字介面底下讓我們與系統溝通的一個工具介面，讓我們以更方便，更自動化的方式來執行想要執行的指令。快速的協助使用者 or 管理者大量地執行重複性的動作與指令。

## Shell Script撰寫
在windows，我們可以利用git bash要執行Shell script
創建一個`.sh`的檔案 => `touch num.sh`
接著可以利用vim文字編輯器在裡面寫入我們要的程式
以Lidemy的作業為例:
寫一個 shell script，可以傳入一個數字 n，然後會產生 1~n 個檔案，檔名是 `{number}.js`。
這時候我們要利用迴圈的方式來完成
我們可以寫
```shell=
for((i = 1; i<=$1;i++)) 
 do
  touch ${i}.js
done
echo "File created"
```

用while迴圈的話則會長這樣
```shell=
i=1
n=$1
while [ $i -le $n ] 
do
    touch $i.js
    ((i++))
done
echo "File Created"
```
注意:讀取參數位置來獲取參數時，需要用 **$1** 到 **$9** 獲取第1到第9個的命令行參數。**$0**為shell名。  
  
參考資料
[技術共筆部落格](https://blog.techbridge.cc/2019/11/15/linux-shell-script-tutorial/)
[鳥哥的Linux私房菜](http://linux.vbird.org/linux_basic/0340bashshell-scripts.php)
[Shell Script 教學](https://crmne0707.pixnet.net/blog/category/3638545)
[it邦](https://ithelp.ithome.com.tw/articles/10136126)
[grep、cut、awk、sed文本处理](https://www.jianshu.com/p/70c390e3fa73)
[sed与awk实例](https://www.jianshu.com/p/dbba519191af)
[shell判斷式](https://www.itread01.com/content/1548064116.html)

:bow: 
:ok_woman:
