# Linux Ubuntu 安裝&教學
在windows系統安裝ubuntu須裝虛擬器
## Linux Ubuntu 安裝
### 1. 前置準備
虛擬器可從選擇其一
1.VMWare [官方網站](https://www.vmware.com/latam/products/workstation-player/workstation-player-evaluation.html)
2.Virtual Box [官方網站](https://www.virtualbox.org/wiki/Downloads)
下載Ubuntu ISO檔
~~[Ubuntu官方網站](https://www.ubuntu-tw.org/modules/tinyd0/index.php?id=7)~~
現在已更改 [Download](https://ubuntu.com/download/desktop)
可選擇要下載是桌面版 or server版、下載的版本(e.g. 22.04LTS or 20.04LTS or 18.04LTS)最後選擇電腦架構即可下載

### 2.安裝虛擬器步驟
以VMWare為例
1. 選擇創建一個新的虛擬器

2. 選擇下載ubuntu的image file
3. 選擇虛擬器名稱以及儲存位置
4. 選擇虛擬器硬碟大小以及是否儲存成單一檔案或是多個檔案
5. 完成設定前先進入硬體設定
6. 調整適當的記憶體大小以及處理器,調整完close就完成設定。
7. 
### 3.安裝Ubuntu
1. 可選擇語言,選擇完選安裝ubuntu
2. 選擇鍵盤
3. 這邊選擇安裝時要不要更新軟體,這邊我會選正常的安裝大小、安裝時順便更新、安裝第三方軟體
4. 這邊如果是虛擬器可以直接清空硬碟並安裝Ubuntu,
:::danger
若是一台電腦同時安裝2種作業系統不能選清空硬碟
:::

5. 選擇地區
6. 設定個人資料,輸入名稱和密碼,這邊可以選擇自動登入或是登入時需要打密碼

7. 最後等待安裝結束,安裝完成後重開機即可。

8. 安裝完成畫面
### 4. Ubuntu基礎指令
打開terminal : Ctrl+Alt+t
bc 計算機
1. 更新系統
```cpp
sudo apt-get update //軟體資料庫同步
sudo apt-get upgrade //更新
sudo apt-get clean //清除暫存檔
sudo apt-get install package //安装包
sudo apt-get remove package //删除包
sudo apt-cache search package //搜索软件包
sudo apt-cache show package //获取包的相关信息,如说明、大小、版本等
sudo apt-get install package --reinstall //重新安装包
sudo apt-get -f install //修复安装
sudo apt-get remove package --purge //删除包,包括配置文件等
sudo apt-get build-dep package //安装相关的编译环境
sudo apt-get upgrade //更新已安装的包
sudo apt-get dist-upgrade //升级系统
sudo apt-cache depends package //了解使用该包依赖那些包
sudo apt-cache rdepends package //查看该包被哪些包依赖
sudo apt-get source package //下载该包的源代码
sudo apt-get clean && sudo apt-get autoclean //清理无用的包
sudo apt-get check //检查是否有损坏的依赖
```
查看Ubuntu版本
```Linux
lsb_release -a
```
命令行中的ctrl組合鍵
```Linux
Ctrl+c 結束正在運行的程式
Ctrl+d 結束輸入或退出shell
Ctrl+s 暫停屏幕輸出【鎖住terminal】
Ctrl+q 恢復屏幕輸出【鎖住terminal】
Ctrl+l 清空鎖住terminal,【是字母L的小寫】等同於Clear
```
2. 關機指令
```cpp
shutdown [-krhc] [時間] [警告訊息]
/*
-k : 不要真的關機,只是發送警告訊息出去!
-r : 在將系統的服務停掉之後就重新開機(常用)
-h : 將系統的服務停掉後,立即關機。 (常用)
-c : 取消已經在進行的 shutdown 指令內容。
時間 : 指定系統關機的時間!時間的範例底下會說明。若沒有這個項目,則預設 1 分鐘後自動進行。
* /
```
```cpp
[root@study ~]# shutdown -h now
立刻關機,其中 now 相當於時間為 0 的狀態
[root@study ~]# shutdown -h 20:25
系統在今天的 20:25 分會關機,若在21:25才下達此指令,則隔天才關機
[root@study ~]# shutdown -h +10
系統再過十分鐘後自動關機
[root@study ~]# shutdown -r now
系統立刻重新開機
[root@study ~]# shutdown -r +30 'The system will reboot'
再過三十分鐘系統會重新開機,並顯示後面的訊息給所有在線上的使用者
[root@study ~]# shutdown -k now 'This system will reboot'
僅發出警告信件的參數!系統並不會關機啦!嚇唬人!
```
3. Root File system 架構

# Linux指令
1. 如果我們是攝影師並且有大量圖像,我們想將它們組織成年和月,那麼我們可能做的第一件事就是創建一系列以數字“年-月”格式命名的目錄。 這樣,目錄名稱將按時間順序排序。 我們可以鍵入一個完整的目錄列表,但這需要大量工作並且也容易出錯。 相反,我們可以這樣做:

2. Cursor Movement : The following table lists the keys u
to move the cursor:
```Linux
alt + f // 快速向前
alt + b //快速後退
ctrl + L // Clear the screen and move the cursor to the top left corner
```
3. grep + awk
以git status為例
```cpp
git status | grep "modified:" | awk -F: '{print "git rm --cached" $NF}'|sh
列出git status
grep出modified:
awk -F: 印空格
'{
print "git rm --cached"(印出git rm --cached)
$NF(待確認),以這個為例也可以用$2
}'
寫成sh檔自動執行
```
## Permission
* 第一個字符




* chmod 更改權限



如果想遞歸所有目錄加上相同權限,需要加上參數“ -R
例
```Linxux
chmod 777 test/ -R
```
* chattr權限 : 凌駕於r、w、x、suid、sgid之上的權限。
```cpp
//系統中一些重要的檔案可以設定 i 屬性(immutable),防止檔案被刪除會是更改:
sudo chattr +i date.txt
//然後用 lsattr 檢查一下:
lsattr date.txt
//輸出會像這樣:
----i--------e-- date.txt
//可以測試一下用 rm 指令刪除這的檔案:
rm date.txt
//這時候應該就會出現這樣的訊息:
rm: remove write-protected regular file ‘date.txt’?
//就算回答 y,也還是會出現不可以更動的錯誤訊息:
rm: cannot remove ‘date.txt’: Operation not permitted
//而且就算用管理者權限執行刪除的指令:
sudo rm date.txt
//還是一樣:
rm: cannot remove ‘date.txt’: Operation not permitted
```
這樣就可以確保檔案不會被誤刪。
```cpp
//如果真的要刪除這個檔案,就先必須把 i 屬性拿掉才行:
sudo chattr -i date.txt
rm date.txt
```

* umask :umask值用於設置用戶在創建文件時的默認權限,當我們在系統中創建目錄或文件時,目錄或文件所具有的默認權限就是由umask值決定的。
對於root用戶,系統默認的umask值是0022;對於普通用戶,系統默認的umask值是0002。執行umask命令可以查看當前用戶的umask值。
## vim 指令
```Linux
w //到下個單字或標點符號的開頭
W //到下個單字的開頭,忽略標點符號
b //到上個單字或標點符號的開頭
B //到上個單字的開頭,忽略標點符號
gg //go to top of the file
G // go to bottom of the file
o //換行然後insert
x //刪除字元
dG //刪除這行到底的字元
dd //刪除這行並跳到下行
D //刪除這行
u //回復上次狀態
yy //複製這行
p //貼上yy
%s/""/""/g //把整個檔案前面""換成後面""
%s/""/""/gc //可跳出提示
```
### set tabstop=4
[How to set tab to 4 spaces in vim? ](https://superuser.com/questions/505937/how-to-set-tab-to-4-spaces-in-vim)
Create a ~/.vimrc file with this line:
```cmake
set tabstop=4
```
### how-to-use-vim-as-a-hex-editor
Vim 編輯器除了可以編輯文字檔之外,也可以作為 16 進位編輯器(hex editor),編輯二進位(binary)的檔案,只不過在編輯二進位檔案時,要配合 xxd 這個外部指令將資料轉換為 16 進位的排版格式,以下是利用 Vim 編輯一個二進位執行檔的操作步驟。
[Ref](https://blog.gtwang.org/useful-tools/how-to-use-vim-as-a-hex-editor/)
在vim 輸入 `:%!xxd`
## 編譯
編譯時可用 make all 2>&1 | tee xxx.log 才會印出error
[詳解2>&1](https://mks.tw/2928/%E5%AD%B8%E7%BF%92%E7%AD%86%E8%A8%98-linux-command-%E3%80%8C21%E3%80%8D-%E8%BC%95%E9%AC%86%E8%AB%87)
## Text Processing
### 文件內容查看
```Linux
cat -n test.c //看test.c 並把行數列出來(包括空白行)
cat -b test.c //看test.c 並把行數列出來(不包括空白行)
head -n 20 //看頭20行,若沒有指定行數默認10行
tail -n 20 //看尾20行,若沒有指定行數默認10行
```

### uniq 刪除重複行(only cat 時,檔案內不會刪)
```Linux
uniq example.txt //每一段重複的文字行不管重複幾次,處理完之後只會留下一行不重複的文字行
uniq -c example1.txt // 可以在刪除重複文字行之後,標示出每一行的重複次數:
uniq -d example.txt // 將這個輸出中重複的行刪掉
uniq -D example.txt // 只要輸出有重複的文字行
uniq -u example.txt // 只輸出沒有重複的文字行
```

### grep
```Linux
grep [option] pattern [file1 file2...]
grep 'a' 1.txt //在grep命令中輸入字符串參數時,最好引號或雙引號括起來
grep -r 'a' 1.txt //以遞歸的方式查找符合條件的文件。
grep -nr 'a' 2.txt // -nr 列出行數
```
### awk
awk可以幫助我們統計,可以製作表格等等的格式化以後, 做顯示, 算是個報告生成器
```Linux
awk {‘print $欄位 $欄位 $欄位 ….’}
```
* 使用grep + awk 的組合技
```cpp
cat /etc/passwd | grep "boyan" |awk -F: '{print $3}'
```
* awk + Regex(Regular expression) 的組合技
找出所有UserName開頭是b的
```cpp
awk -F ':' '$1~/^b.*/{print $1}' /etc/passwd
// ^是Regex的符號, 用來表示下一個符號一定是搜尋對象的開頭
// .代表任意符號
// *則代表前一個符號可以出現任意次數
```

找出所有UserName開頭不是b的
`awk -F ':' '$1!~/^b.*/{print $1}' /etc/passwd `
### sed
sed 主要功能為自動化的修改文字檔
sed 基本的用法如下: 「sed [-OPTION] [/PATTERN][/REPLACEMENT]/[FLAG] [FILE]」。
sed 最基本的命令為搜尋樣板並取代〝s〞, 旗幟〝g〞為取代全部
舉例來說,我想要把input.txt檔案內的hello改成world,並且輸出到output.txt
```bash
sed 's/要被取代的字串/取代的字串/' 輸入的檔案 > 輸出的檔案
sed 's/hello/world/' input.txt > output.txt
```
-i:sed直接(in-palce)編輯字串功能
```bash
sed -i 's/要被取代的字串/取代的字串/' 直接被取代字串的檔案
sed -i 's/hello/world/' file.txt
```
-e:指定script在哪邊
```bash
sed 's/hello/world/' input.txt > output.txt
sed -e 's/hello/world/' input.txt > output.txt
sed --expression='s/hello/world/' input.txt > output.txt
```
### cut
cut以行為單位,根據分隔符把行分成若干列,這樣就可以指定選取哪些列了。
```cpp
cut -d '分隔字符' -f 選取的列數
echo $PATH|cut -d ':' -f 2 //選取第二列
echo $PATH|cut -d ':' -f 3,5 //選取第三和第五列
echo $PATH|cut -d ':' -f 3-5 //選取第三-五列
echo $PATH|cut -d ':' -f 3- //選取第三列到最後一列
echo $PATH|cut -d ':' -f 1-3,5 //選取一-三列和第五列
```
ex:

* sed
### 使用find找檔案
name & type
```Linux
find . -name "*.c" // 將當前目錄與旗下子目錄底下所有.c檔印出來
find . -name abc.c // 找當前目錄與旗下子目錄底下abc.c檔位置
find . -iname abc.c // 找當前目錄與旗下子目錄底下不分英文大小寫,找尋檔案名稱為abc.c
find . -type f //將當前目錄與旗下子目錄底下所有的一般檔案
find . -type d //將當前目錄與旗下子目錄底下所有的dir
find . -type f -perm 0777 //可以指定檔案的權限,例如列出權限是 777 的所有檔案
```
### -exec
```cpp
find . -type f -name "isp_logo.c" -exec rm -f {} \;
find . -name *.h -exec grep -nr "RTW_INFO" {} \;
```
檔案修改與存取日期
```Linux
-mtime n // 指定檔案的最後修改時間(modification time),單位為天。
-mmin n //指定檔案的最後修改時間,單位為分鐘。
-atime n //指定檔案的最後存取時間(access time),單位為天。
-amin n //指定檔案的最後存取時間,單位為分鐘。
-ctime n //指定檔案狀態相關資訊最後修改的時間(status time),單位為天。
-cmin n //指定檔案狀態相關資訊最後修改的時間,單位為分鐘。
find . -mtime +7 -mtime -14 // 找出上次修改的時間是在 7 天以上、14 天以下的檔案
find . -mmin -60 // 找尋最近一小時內更改過的檔案
```
### cp & mv
cp命令的功能是將給出的文件或目錄複製到另一個文件或目錄中
mv命令用來移動文件或目錄,也可以給文件或目錄重命名。
```Linux
-i //交互式複制,在覆蓋目標文件之前將給出提示要求用戶確認
-v //顯示進度
-r //cp將遞歸複製該目錄下的所有子目錄和文件,目標文件必須為一個目錄名。
-f //強制模式
```
### tar & gzip
此命令可以把一系列文件歸檔到一個大文件中,也可以把檔案文件解開以恢復數據。
tar命令參數很特殊,其參數前面可以使用“-”,也可以不使用
```Linux
-c //生成檔案文件,創建打包文件
-v //列出歸檔解檔的詳細過程,顯示進度
-f //指定檔案文件名稱,f後面一定是.tar文件,所以必須放選項最後
-t //列出檔案中包含的文件
-x //解開檔案文件
```
:::info
除了f需要放在參數的最後,其它參數的順序任意。
:::

* tar與gzip命令結合使用實現文件打包、壓縮。tar只負責打包文件,但不壓縮,用gzip壓縮tar打包後的文件,其擴展名一般用xxxx.tar.gz。
壓縮用法:tar zcvf 壓縮包包名文件1 文件2 …
解壓用法: tar zxvf 壓縮包包名
```Linux
tar zcvf test.tar.gz test.c test1.c test2.c //壓縮
tar zxvf test.tar.gz -C aaa/ //解壓縮,-C為指定位置,aaa為資料夾名稱
```

## 用戶和用戶組管理
* whoami 我是誰
* 查看當前所有登錄系統的用戶訊息 : who
常用選項

## 系統管理
* cal & date
cal -y 可印出整年

* 查看網絡狀態 : netstat
netstat命令用於顯示網絡狀態。
利用netstat指令可讓你得知整個Linux系統的網絡情況。
```cpp
-a或–all 顯示所有連線中的Socket。
-A<網絡類型>或–<網絡類型> 列出該網絡類型連線中的相關地址。
-c或–continuous 持續列出網絡狀態。
-C或–cache 顯示路由器配置的快取信息。
-e或–extend 顯示網絡其他相關信息。
-F或–fib 顯示FIB。
-g或–groups 顯示多重廣播功能群組組員名單。
-h或–help 在線幫助。
-i或–interfaces 顯示網絡界面信息表單。
-l或–listening 顯示監控中的服務器的Socket。
-M或–masquerade 顯示偽裝的網絡連線。
-n或–numeric 直接使用IP地址,而不通過域名服務器。
-N或–netlink或–symbolic 顯示網絡硬件外圍設備的符號連接名稱。
-o或–timers 顯示計時器。
-p或–programs 顯示正在使用Socket的程序識別碼和程序名稱。
-r或–route 顯示Routing Table。
-s或–statistice 顯示網絡工作信息統計表。
-t或–tcp 顯示TCP傳輸協議的連線狀況。
-u或–udp 顯示UDP傳輸協議的連線狀況。
-v或–verbose 顯示指令執行過程。
-V或–version 顯示版本信息。
-w或–raw 顯示RAW傳輸協議的連線狀況。
-x或–unix 此參數的效果和指定"-A unix"參數相同。
–ip或–inet 此參數的效果和指定"-A inet"參數相同。
```
[Ref](https://blog.gtwang.org/linux/linux-netstat-command-examples/)
* 查看process訊息 : ps & 以樹狀圖顯示 pstree
process是一個具有一定獨立功能的程序,它是操作系統動態執行的基本單元。

* 動態顯示process : top & htop
top命令用來動態顯示運行中的進程。top命令能夠在運行後,在指定的時間間隔更新顯示信息。-d參數可以指定顯示信息更新的時間間隔。

* 終止process : kill
kill命令指定進程號的進程,需要配合ps使用。
* shutdown & reboot

* 檢測硬碟空間
df命令用於檢測文件系統的硬碟空間佔用和空餘情況,可以顯示所有文件系統對節點和硬碟的使用情況。


* 檢測目錄所佔硬碟空間
du命令用於統計目錄或文件所佔硬碟空間的大小,該命令的執行結果與df類似,du更側重於硬碟的使用狀況。

* 查看或配置網路卡訊息 : ifconfig
可修改IP, sudo ifconfig enp3s0 192.168.xxx.xxx

* 測試遠程主機連通性:ping

## 硬碟管理
* df : 獲取硬碟被佔用了多少空間,目前還剩下多少空間等訊息。
```
-a :列出所有的文件系統,包括系統特有的/proc 等文件系統;
-k :以KBytes 的容量顯示各文件系統;
-m :以MBytes 的容量顯示各文件系統;
-h :以人們較易閱讀的GBytes, MBytes, KBytes 等格式自行顯示;
-H :以M=1000K 取代M=1024K 的進位方式;
-T :顯示文件系統類型, 連同該partition 的filesystem 名稱(例如ext3) 也列出;
-i :不用硬盤容量,而以inode 的數量來顯示
```
:::danger
有機會再用
:::
## Linux pipe line
Linux的pipe line是'|',通過它可以對數據進行連續處理,常用來作為接收數據管道命令有: less,more,head,tail,而ls, cp, mv就不行。
* wc : 統計次數
可以計算文件的Byte數、字數、或是列數。沒有指定就是-lwm。也可以同時計算多份文件
```cpp
wc -lwm //l是統計行數,w是統計幾個英文單字,m是統計有幾個字符
```


* cut 可擷取字元 or 擷取欄位
對於欄位寬度是固定的資料,可以使用擷取固定位置字元的方式,把指定的欄位抓出來。如果要擷取多個不連續的的區段,逗號分隔每個區段。

也可以排除字元 : --complement

* sort 參數說明:
-f :忽略大小寫的差異,例如A 與a 視為編碼相同;
-b :忽略最前面的空格符部分;
-M :以月份的名字來排序,例如JAN, DEC 等等的排序方法;
-n :使用『純數字』進行排序(默認是以文字型態來排序的);
-r :反向排序;
-u :就是uniq ,相同的數據中,僅出現一行代表;
-t :分隔符,默認是用[tab] 鍵來分隔;
-k :以哪個區間(field) 來進行排序
* tee : 同時輸出多個文件
很常用
* tr : 替換指定的字符
https://zh.wikipedia.org/zh-tw/Tr_(Unix)
## 其他
* scp : 若要在不同的 Linux 主機之間複製檔案,最常用的方法就是使用 scp 指令,它可以透過 SSH 安全加密傳輸的方式,將本地端的檔案或目錄複製到遠端,或是將遠端的資料複製到本地端。
scp也可以複製目錄、保留檔案時間與權限、資料壓縮、限制傳輸速度(單位為 Kbit/s)、自訂連接埠、IPv4 與 IPv6
```cpp
scp [帳號@來源主機]:來源檔案 [帳號@目的主機]:目的檔案
// 從本地端複製到遠端,本地端的 /path/file1 複製到 192.168.0.1 這台主機上的 /path/file2,而登入 192.168.0.1 這台主機時,是以 myuser 這個帳號登入:
scp /path/file1 myuser@192.168.0.1:/path/file2
//也可以把遠端的檔案複製到本地端:
//從遠端複製到本地端
scp myuser@192.168.0.1:/path/file2 /path/file1
//複製目錄
scp -r /path/folder1 myuser@192.168.0.1:/path/folder2
// 保留檔案時間與權限
scp -p /path/file1 myuser@192.168.0.1:/path/file2
// 資料壓縮
scp -C /path/file1 myuser@192.168.0.1:/path/file2
//限制傳輸速度為 400 Kbit/s
scp -l 400 /path/file1 myuser@192.168.0.1:/path/file2
// 使用 2222 連接埠
scp -P 2222 /path/file1 myuser@192.168.0.1:/path/file2
//使用 IPv4
scp -4 /path/file1 myuser@192.168.0.1:/path/file2
//使用 IPv6
scp -6 /path/file1 myuser@192.168.0.1:/path/file2
```
* crontab : Linux 的管理者或使用者如果需要定期執行某些指令或程式,最常見的方式就是使用 cron 來幫忙管理例行性工作排程,只要設定好 crontab 設定檔之後,系統就會自動依照設定的時間,定期執行重複性的工作。
[用到再說](https://blog.gtwang.org/linux/linux-crontab-cron-job-tutorial-and-examples/)
## 安裝putty
```Linux
sudo apt-get install putty
```
執行dmesg 查出 device name:
```Linux
sudo dmesg | grep tty
```
這邊我們就可以看到 device name 是 ttyUSB0。
:::danger
開啟putty要用sudo 不然會閃退
:::
## find + grep + awk的組合拳
在shell scrip中,要執行自動化的腳本可以使用組合拳
```bash
#設定變數TOP
TOP=../../../build/
#要使用變數前面要加$
CUSTOMER=$(find $TOP -name version_info.txt | xargs grep "CustomerVersion="| awk -F= '{print $2}' | tr -d \" | tr -d '\r')
echo $CUSTOMER
```
分解說明
* find
* find `路徑` -name `名稱`
>在使用 find 命令查找文件時,如果需要對找到的文件進行進一步操作,可以使用管道符號 | 將 find 命令的輸出傳遞給其他命令。但是,由於 find 命令的輸出可能包含空格或其他特殊字符,這可能會導致其他命令無法正確處理文件名。因此,為了避免這個問題,可以使用 xargs 命令將 find 命令的輸出轉換為命令行參數,然後將這些參數傳遞給其他命令。
* xargs
* xargs 這個指令會標準輸入(standard input)讀取資料,並以空白字元或換行作為分隔,將輸入的資料切割成多個字串,並將這些字串當成指定指令(預設為 /bin/echo)執行時的參數。
* grep
* 尋找關鍵字
* awk
* awk 為處理文字檔案的語言
* `-F` 該命令可以按照字符`=`作為分隔符
* print $2
* 印出第二個字段
* tr
* 是一個用於刪除字符的命令
* tr -d \"
* 刪除字串中的字符
* 因為做完處理之後有 ^M,^M是回車符,會有問題。
* tr -d '\r' 把回車符刪除
>不用空格或是`''`, `""`
# 不知道也不會怎樣的冷知識
## 查看CPU核心
切換到/sys/devices/system/cpu目錄下,執行ls -al, 可以看到電腦有幾個核心:

執行cat online 可以看到線上工作的有幾個核心

執行`echo 0 > /sys/devices/system/cpu/cpu1/online` 關掉cpu1這個核心,再看cat online 就剩3個在工作了,cat offline 不在線的有1個(不敢試,取自網路)

## Linux 使用 qpdf 移除 PDF 密碼
Linux 想要移除 PDF 設定的密碼,可以使用 qpdf 來達成。
* 安裝qpdf
* apt-get install qpdf
* qpdf 移除密碼語法
* qpdf --password=`PASSWORD` --decrypt `ENCRYPT-FILE.pdf` `DECRYPT-FILE.pdf`
* ENCRYPT-FILE.pdf:加密的檔案
* DECRYPT-FILE.pdf:輸出移除密碼的檔案
## 使用 Vim 加密、解密 檔案內容
https://blog.longwin.com.tw/2018/01/vim-encrypt-decrypt-file-content-2018/