【技術分享】小乖乖的 Linux/Ubuntu 歷險記
阿新 • • 發佈:2020-11-14
本文將同步釋出於 [WHU-TD](https://www.cnblogs.com/WHU-TD/) 的部落格。
這是一篇自帶故事背景的部落格。
總所周知,寫的多,錯的多,更何況一個剛剛接觸 Linux 的小白。雖然只是介紹一些非常基礎的內容,還是希望大家在發現錯誤時可以及時指出。我一定會虛心地更正。
說起來這種又臭又長還沒什麼營養的部落格大概沒什麼人看吧。如果拆成幾篇專門寫某個部分的話大概看的人會更多吧。emmm 不過我還是想寫一篇這樣的部落格,雖然網上的教程已經足夠豐富了。如果要問為什麼,大概是想整理自己的學習成果,還有,就是想搞點不太一樣的東西吧。
可能有點自說自話,請見諒。我會盡可能寫清楚的。雖然很幼稚,跟小乖乖這個名字很配。
還有,本文面向小白。
本文以 Linux 小白小乖乖的身份,介紹了想在 Linux 下編寫 `Hello World.cpp` 時遇到的種種問題,並由這個特定的情境,引入介紹了 Linux 的相關基礎知識。
此外,Linux 下開啟終端的方法有三個:
1. 在資料夾或桌面上右鍵 “用終端開啟(run in terminal)”
2. **Ctrl + Alt + T**
3. Alt + F2 輸入 gnome-terminal
P.S. 除了第零章,每一章的第一節都是特定的場景,可能沒有什麼用處,大家也可以跳過。
P.S. 本文主要基於 **Ubuntu 20.04.1 LTS** 當然各種版本毫無疑問是有共同性的。
~~P.S. 我忘記壓縮一下圖片了嗚嗚嗚~~
好的我壓縮好了改過來了。現在載入應該快了吧 ~
應該不至於看不清吧。(委屈.jpg)
# 零、我們是開發者
(這一章屬於吹水部分。自行斟酌跳過。)
## 小乖乖不想學 Linux
相信大家多多少少對 Linux 都有一定的瞭解。比如,廢物小乖乖就知道 Linux 是一種作業系統,CCF 的評測系統就是在 Linux 上跑的(大概)。
在上一期 zpy 大佬的部落格中,我們學習了 Linux 系統的幾個優點,然而固執的小乖乖並沒有因此燃起學習 Linux 的興趣。
為什麼總有人告訴我要學 Linux ?Windows 用著不香嗎?Windows 就不能跑程式碼了嗎?~~氣抖冷~~
事實上,對於學習 Linux ,小乖乖有兩個**極端**的看法:
1. 學習 Linux 就是學習作業系統的原理和開發。管它安不安全開不開源,開了我也看不懂,這跟現階段還在學 C 語言的我也太遙遠了吧?
2. Linux 系統是 Windows 系統的備胎。就跟 Android 和 IOS 差不多,反正都只是作業系統,會一個就行了。我現在 Windows 還用的好好的,讓我去學 Linux 幹什麼?
總而言之,基於功利性的“**學了有什麼用**” 的思維方式,小乖乖原本並沒有心思去學 Linux。
不過,在部長 hxj 的悉心指導下,小乖乖逐漸明白了學習 Linux 的意義和目的。
(以下內容為查詢各種資料後,得出的、純屬個人意見的對學習 Linux 與 Linux 優點的理解,部分內容可能會與上一篇部落格相重疊。也許你們會說部落格應該以技術分享之類的硬核內容,但我認為,有必要先講清楚學習的目的。就個人的看法而言,我不喜歡在看完麵包的介紹前,就被人強行塞進嘴巴里。當然,我也只是一名 Linux 的初學者,許多觀點和看法可能是幼稚而錯誤的,希望大家能指出發現的錯誤。)
在我看來,Linux 與 Windows 最大的區別在於:前者主要是為服務端、開發者設計的系統,後者主要是為客戶端的使用者體驗而設計。
Windows 擁有豐富的圖形介面和大量方便的娛樂、辦公應用程式,而 Linux 雖然沒有那麼強大的圖形介面,但由於開源的優勢以及對開發者強大的吸引力,Linux 擁有大量開發者編寫的外掛、工具。
同時,Windows 複雜的圖形介面,實現起來必然是繁瑣而複雜的,而在這個實現的過程中,步驟越多,可能出現的漏洞也就越多,可能暗藏的被攻擊的缺口都越多。而 Linux 不同,Linux 具有的圖形介面較為基本,主要的操作都需要利用命令列來實現。同時,Linux 作為開源專案,是大型的網路開發專案,參與 Linux 維護的開發者數量遠多於 Windows 。**“足夠多的眼睛,就可以讓問題浮現”**。 這也是 Linux 透明化、安全性高的原因。
同時,上篇部落格中提到的**可移植性**,也使得 Linux 在人工智慧/智慧裝置等領域有較高的適應性。
當然,也許這些對於現階段的我們,並沒有多大的意義。我們並不明白怎麼利用圖形介面下隱藏的漏洞,不明白怎麼利用 Linux 的開源資源來進行自己的開發,我們也沒有任何管理服務端的經驗(開過 MC 服或過於神仙的大佬請自習忽略這段話)。
我想,我們學習 Linux,不僅僅要把它當成一種使用者端的作業系統,熟悉其圖形介面與 Shell 下基本的操作,也不僅是學會 git 或是 gdb 這樣的特定工具(當然這裡列舉的工具並不限定於 Linux 系統),更重要的是利用學習 Linux 的踏板,熟悉命令列下的操作、轉變自己的思維方式。
我想,**我們是開發者**,不應讓由於熟悉和習慣產生的惰性遮住我們的眼睛,不應讓自己成為套死在某種別人開發好的工具上的猴子。
上面那句話是一個剛接觸 Linux 的小白一廂情願地對自己說的,僅代表個人極不成熟的觀點,你們可以忽略。
## 命令列的重要性
~~命令列的重要性在於裝逼。~~
跟圖形介面下的操作不同,命令列操作需要你對自己想要幹什麼有一個清晰的認識,才能選擇恰當的命令,這有助於整理自己的思維。
同時,命令列相對較為**簡潔**。你不用像圖形介面下那樣,一層一層開啟視窗。
命令列也方便於操作的**記錄**,便於你回想起你的上一步在幹什麼。
部分的命令列操作是圖形介面所無法完成的,比如訪問 / 目錄(霧)。
下面以 Windows 下的 cmd 控制檯為例。
P.S. Windows Dos 的命令與 Bash 有很大的區別,比如給命令新增的要求不是用 `-` 而是 `/`。不過可以多去試試,便於熟悉。(畢竟使用 `help` 和 `/?` 就可以很輕鬆的查到詳細的中文提示,如果單純的想試命令列操作,學起來是飛快的。~~至於複雜的迴圈、條件結構和各種運算子語法,度娘可以解答一切~~)其實 Bash 也可以用 `--help` 和 `-?` 來查指令,就是可能沒有中文。
以 Windows 下刪除某個資料夾中的可執行檔案為例。
我們進行 C 語言基礎程式設計學習已經有一段時間了。相信大家也已經編寫了大量的程式。細心的同學還會用不同的資料夾來存放程式碼。於是,一個問題就出現了。編譯產生的可執行檔案,一不留神就攢下了一堆。這些檔案大多隻是在老師檢查作業的時候執行以下就沒再碰了,但堆多了就顯得資料夾很亂,也佔用空間。
在一般情況下,我們要刪除這些檔案,無非就是一個資料夾一個資料夾地找,然後用 ctrl 鍵把它們選定,然後一點一點地刪掉。
但使用 dos 命令可以很快地完成這個工作。
```dos
cd /d D:\_ACM
del /s *.exe
```
如果你厭煩一次一次輸入,你也可以建立一個 .bat 字尾的檔案,將上面的程式碼複製進去,每次只需要點開它就行了。
~~好尬啊這個應該都會吧~~
至於 `/d` `/s` 這些引數還有命令,都可以在 cmd 視窗快速的查詢。如:
```dos
cd /?
```
P.S. cd (change directory) 是**改變當前工作目錄**的指令。後面會提到一點的絕對路徑和相對路徑,大概會加深你對這個命令的理解。此外 /d 是 Windows 下切換磁碟,而 Linux 下並沒有 C盤 D盤 這樣的概念。 cd 命令或許會成為之後我們使用最為頻繁的指令之一。
好吧我跑題了,記得是要講 Linux 來著。
你可以把在 Linux 桌面上雙擊 a.txt 的操作理解為 gnome 捕獲滑鼠動作後幫你執行了 `gedit a.txt`。
總之知道**命令列和指令碼語言很有用**就對了。
## 學會獲取幫助文件
以 `ls` (list files) 命令為例如:
```bash
ls --help
man ls
info ls
```
雖然大多沒有中文,而且**help 裡有的中文翻得像機翻**,但這並不能阻礙各位英語大佬們閱讀文件的熱情(確信)。
需要小心的是,info 下的鍵入某個鍵時,會被讀取為**命令**,例如,按下 q 是退出,游標移動到連結上按下 space 會進入文件。info 提供的是一種閱讀解釋文件的方式。
如果沒有使用 info 的經驗,可以直接用不帶任何引數的 `info` 命令來檢視說明。
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113132548092-1248845440.png)
如果你習慣把某個命令的幫助資訊寫入檔案中方便閱讀,可以這麼做:
```bash
man ls > ls.txt
```
其實在 dos 裡也有類似的用法 就是把命令執行後輸出的資訊寫入某個檔案中。
```dos
dir /? > dir.txt
```
P.S. dir 命令在 Linux 下似乎同樣有效。與 ls 有相似的效果,都是列出當前目錄下的檔案或目錄。
記住命令的方式之一就是**聯想英文全稱**。
比如刪除檔案,在 dos 裡是 `del`,在 bash 裡則是 `rm`,其全拼分別為 delete 和 remove 。
所以如果你不知道某個命令叫什麼,把能想到的縮寫都用 `man` 查一遍,總能找到的。`man` 的各種引數可以用 `man --help` 或 `man man` 查到。
~~雖然我當時沒猜到 rm ,直接跑去百度了。~~
[runoob](https://www.runoob.com/linux/linux-command-manual.html) 上的 Linux 教程其實相當詳細。去上面學習可以很快地掌握。
啊啊雖然這麼說但是先別跑啊把我的部落格看完(霧)
雖然部分內容我在部落格中給出了較為完整的程式碼,但實現的方式其實不止一種。例如換源時你們可以用 root 使用者來修改。
我不希望看完我的部落格後,你們只知道複製貼上我或是其它部落格的程式碼。
# 一、跨出的第一步
## 小乖乖以為要搭建環境
Linux 下 C 語言開發環境的配置快得飛起,把沒見過世面的小乖乖嚇壞了。
在 Windows 上,我們需要下載 mingw64 ,然後進行一系列亂七八糟的安裝或是環境變數的配置。
而在 Linux 下,只需要這麼一行:
```bash
sudo apt install gcc g++ gdb vim
```
(其實這裡面有些東西比如 gdb 是自帶的,這個命令執行後只是把它更新了一遍。)
當然 vim 並不是必須的,**vim 是終端下一個很強大的包含程式碼高亮的文字編輯器**。
Linux 本身自帶了一個 vi ,gnome 桌面則自帶了一個 gedit。gedit 類似於 Windows 下的記事本,而 vi/vim 則是基於命令列的。
在第二章中,會對 vi/vim 文字編輯器的基礎操作做簡單的介紹。與前文講到的 info 有一定的相似之處。
P.S. 輸入密碼時游標是不會移動的,也就是說**不會**像輸入 qq 密碼那樣顯示星號和圓點。輸完按回車就行了。如果你一直密碼錯誤,可以檢查一下你的數字小鍵盤是不是關掉了、大寫鎖定是否打開了之類的。如果你連密碼都記錯了,emmm 那你可以參考[這個](https://zhidao.baidu.com/question/1513019502500260580.html)。
## apt 指令與 root 使用者
首先,當涉及軟體包的安裝和更新時,我們需要在指令前加上 **sudo** 。這有點類似於 Windows 下的“以管理員身份執行”。
如果不習慣使用指令安裝,也可以通過 **Ubuntu Software** 來搜尋並安裝,操作類似於 Windows 下的應用商店。(它的搜尋圖示在左上角,有點小。)
需要注意的一點,使用指令安裝時是在**設定的下載源處**檢索軟體包。如果下載源沒有收錄你想要的軟體包的話是無法安裝的。
實際上,也有很多軟體需要在**官網或 Github** 上找到後按它的提示進行安裝。如 Typora,oh-my-zsh,linux qq 之類的東西。
此外,預設情況下,apt 會把軟體安裝到**當前使用者**下。
```bash
# 更新軟體列表
sudo apt update
# 安裝軟體(以zsh為例)
sudo apt install zsh
# 刪除軟體(以zsh為例)
sudo apt remove zsh
# 升級軟體包(全部)
sudo apt upgrade
# 還有 search list 等各種命令,可以自行通過 man 查詢。
```
既然提到了使用者,我們就來談談 **root** 吧。
sudo 可以理解為 “以管理員身份執行” 。據目測,在使用 sudo 輸入密碼後,我們 5 分鐘左右不用再輸一次密碼。
大家如果用過安卓系統的一些遊戲修改器之類的,想必對 root 許可權,或是 超級使用者許可權 這樣的詞彙不會感到陌生。(當然,現在大多數手機出於安全和穩定的考慮已經無法輕易開啟 root )
再或者,有一些電腦(比如高中時機房的電腦)的預設使用者是 Administrator ,實際上這也是超級管理員。
初次使用 root 使用者,需要為 root 使用者設定密碼。之後就能使用 `su` (switch user) 命令切換到 root 下了。
```bash
sudo passwd root
# 輸入一次當前賬戶密碼、兩次給 root 設定的密碼。
su root
```
下面這兩張圖大概可以在某種程度上說明 root 使用者與普通使用者的區別。
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113132642130-821844167.png)
root 使用者可以直接使用 `apt install` 而不需要新增 sudo。
此外,不難發現,由於我將 oh-my-zsh 安裝在了 qing-lkyi 下,並且所有的配置都在普通使用者下完成,所以 zsh 的高亮消失了,shell 恢復成了預設的 bash。
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113132701503-1677355403.png)
普通使用者不加 sudo 許可權不足。
同時,從 `pwd` (print work directory) 的結果來看不難發現,普通使用者的 ~ (預設工作目錄) 要比 root 的 ~ 處在更末端的位置。
這種表述可能有點不太精確,但我想不到更合適的說法了。
在後面終端美化時,我會向大家建議使用 root 使用者進行操作。
此外,別亂用 root。小心帶來破壞。
~~破壞就破壞唄,反正虛擬機器,多玩玩熟悉一下也好。~~
## Ubuntu 換源
~~首先,換源指的是換 apt 指令的預設下載源,不是換 Ubuntu 的原始碼。~~
在師兄第一次讓我講換源時,我就產生了這種奇妙的誤解。
實際上,各個國內映象站的指南在如何操作上講得已經非常詳細了。不過我還是簡單地介紹一下兩種方式吧。
第一種是圖形介面下的操作。不需要多做解釋。
先找到這個
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113132735444-1707899210.jpg)
然後修改下載源 (在“其它”裡選)
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113132749756-437431588.png)
第二種是命令列下的操作。此處以清華源為例。
第一步是拷貝原有的軟體源配置檔案。
```bash
# 此處可以注意區別兩種方式
cd /etc/apt
# 這裡是方式1 會在 /etc/apt 下建立一個拷貝檔案
sudo cp sources.list sources.list.copy
# 這裡是方式2 拷貝到 ~ 的下級資料夾
cp sources.list ~/Desktop/sources.list.copy
```
P.S. 檔案不一定要命名為 .copy ,我只是為了方便區分。
由於普通使用者沒有在 ~ (也就是 /home/qing-lkyi) 的上級目錄中建立檔案的許可權,所以在使用時需要 sudo。
而 `cp` 到當前使用者的工作目錄下(也就是在當前工作目錄下建立檔案),則不需要 sudo。
當然,為了防止丟失,備份到 /etc/apt 下還是比較推薦的。
第二步是修改。
```bash
# 選擇自己喜歡的文字編輯器來修改就行了
# cd /etc/apt
sudo vi sources.list
sudo vim sources.list
sudo gedit sources.list
```
同理,普通使用者是沒有修改 ~ 上級目錄中的檔案的許可權的。所以需要 sudo。
將該檔案裡的內容刪掉或註釋掉,直接改成各個映象站提供的程式碼就行了。
如清華源的:(註釋不是我寫的,是它自帶的)
```bash
# 預設註釋了原始碼映象以提高 apt update 速度,如有需要可自行取消註釋
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
# 預釋出軟體源,不建議啟用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
```
儲存(寫入)後退出即可。
有些部落格好像先更改了 sources.list 的許可權再修改,不過我的實際操作中是不需要這一步的。
另外,如果你之前已經安裝過了像 typora 這樣的軟體,可能需要保留安裝時添進去的部分,如
```bash
deb https://typora.io/linux ./
# deb-src https://typora.io/linux ./
```
如果你不確定自己的刪減是否會對這些軟體的更新產生什麼樣的影響,那麼建議採用圖形介面下的換源方式,它會自動為你保留這些額外的軟體源。
P.S. 其它國內源的操作同理。這裡給出幾個公認能夠信任的源的幫助頁面作為參考。
清華源: https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/
網易源: http://mirrors.163.com/.help/ubuntu.html
中科大源:http://mirrors.ustc.edu.cn/help/ubuntu.html
阿里源: https://developer.aliyun.com/mirror/ubuntu?spm=a2c6h.13651102.0.0.3e221b116UQE41
~~雖然我不太清楚映象站是幹啥的,不過好牛逼的樣子~~
無論哪種方式,在完成換源後,最好使用如下指令來更新:
```bash
sudo apt update
sudo
```
P.S. 在上面我們 `cd` 到了 /etc ,那麼這個資料夾是幹什麼的呢?
(以下內容引自[百度知道](https://zhidao.baidu.com/question/426469556.html))etc是 and so on 的意思,來源於法語的 et cetera 。在/etc下面存放的是配置檔案等一些零碎的東西。
感興趣的可以 cd 到 / 目錄下,看看各個資料夾裡都放了些什麼東西。
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113133150807-323725485.png)
# 二、檔案與目錄
## 小乖乖想建立檔案
小乖乖遇到了一個難題:如何建立一個 hello world.cpp
通過查閱部落格,小乖乖發現 `touch` 可以建立一個新檔案。
於是小乖乖自作聰明的鍵入了這樣的命令:
```bash
cd ~/Desktop && mkdir ACM && cd ACM
touch hello world.cpp
```
於是建立了 hello 和 world.cpp 兩個檔案(霧)
小乖乖不服,又鍵入了:
```bash
rm hello world.cpp
touch "hello world.cpp" && ls -a
```
心想著這次總該創建出來了吧,結果 ls 出來一個帶單引號 'hello world.cpp'。
沒見過世面的小乖乖嚇壞了,開啟圖形介面下的資料夾一看,才發現這個單引號只是為了 ls 展示時避免誤會加上去的,真實的檔名並沒有引號。
~~愚蠢的小乖乖流下了不爭氣的眼淚。~~
P.S. 其實空格也可以用 \ 轉義。比如小乖乖就可以這樣開啟檔案:
```
vim "hello world.cpp"
# 或是
vim hello\ world.cpp
```
## 命令列下的檔案操作
首先談談建立檔案與資料夾。
在上面的情境中,我們已經看到了 `mkdir` `touch`的效果。
其中 `mkdir` (make directory) 就是建立資料夾。而 `touch` 嚴格來說並不是新建檔案,而是 change file timestamps (修改檔案時間屬性) ,在沒有 -a 情況下,如果檔案不存在,就會建立一個空檔案。
`rm` (remove) 在第零章也有點到。rm 預設只是刪除檔案,如果想刪除包括資料夾在內的整個目錄(如 ACM),需要使用 `rm -r ACM`
同時,在上面的情境中大家也不難發現,touch 和 rm 可以在後面同時接多個檔案。
關於這兩個命令跟深入的解釋及其建議,可以通過 man rm 來查詢。
ls 命令則可以列出某個目錄下的檔案,及其許可權、數量、時間等。如:
```bash
# 檢視 sources.list 的許可權要求
ls -l /etc/apt/sources.list
```
P.S. 使用 ls 指令列出檔案時,你可能會看到兩種不同的顏色,這是為了區分檔案與資料夾。使用 -a 引數,則可以列出隱藏的檔案(大多是 . 開頭的)。至於那些比較特殊的,高亮跟別的不一樣的檔案,我也不明白其中的原因。(例如 /usr/bin/mount 或是 /etc/localtime 之類的,目測都是一些可執行的檔案)
此外,你還可以通過文字編輯器來建立新檔案。如:
```bash
# 當前不存在 a.txt
gedit a.txt
vim a.txt
```
需要注意的是,文字編輯器的原理是在某處建立一個臨時檔案,然後你會在文字編輯器中修改這個臨時檔案。只有儲存、寫入了,這個檔案才算真正建立完成,不然你只是打開了文字編輯器而已。
## 絕對目錄與相對目錄
Linux 的檔案路徑,有點類似於 Android。
啊不對我說反了,應該說 Android 的檔案路徑,有點類似於 Linux。
二者都**以 / 為根目錄**,也都用**正斜槓**來分割目錄。
前面也有提到,Linux 下沒有 C盤 D盤的說法。關於這一點我不想討論(因為我也不會)。
在此處,我想介紹一下 **相對路徑** 與 **絕對路徑**。
其實我想這一點大家都非常清楚,沒有介紹的必要。只是我在一開始接觸 Linux 時,遇到過一個難以理解的問題。
由於 Linux 的根目錄是 / ,而子目錄與父目錄間也是靠 / 分割開,所以我一開始看到 /usr/bin 這樣的路徑時,我完全沒轉過彎來。我以為這個最前面的 / 是用來分割子、父目錄的,以為加與不加沒有區別。我甚至猜測了好久這個 /usr/bin 是在哪個目錄下才存在的相對路徑。
直到後來,我才知道第一個 / 可以理解為根目錄,這個 /usr/bin 是絕對路徑。
下面舉兩個例子,一個 Windows,一個 Linux:
1. 假設當前 cmd 處在 C:\ 目錄下,而 C:\ 的子資料夾 Windows 中存在一個檔案 py.exe ,此時,這個檔案的相對路徑就是 Windows\py.exe ,而絕對目錄則是 C:\Windows\py.exe。
2. 假設當前 shell 的工作目錄是 ~ (/home/qing-lkyi) ,而桌面的 ACM 資料夾中有一個 a.cpp ,則相對路徑為 Desktop/ACM/a.cpp ,絕對路徑為 /home/qing-lkyi/Desktop/ACM/a.cpp
使用 cd 可以改變當前工作目錄,使你能夠使用更短的相對路徑。在你需要在某個資料夾中執行很多操作時,cd 進去會讓你的工作方便許多。
P.S. 在使用 ls -a 時我們會發現每個目錄最開始基本都有兩個這樣的東西:. 和 .. 。其用法是 `cd .. ` ,可以前往上一級的目錄。
前面介紹過的 pwd 指令則可以告訴你當前的工作目錄。
此外,Linux 中也有類似於 Windows 中 %path% 那樣的環境變數的東西。如:
```bash
# 查詢當前正在執行的是哪種 shell
echo $SHELL
```
(echo 與 dos 中的使用方法相同,效果類似於 C 中的 printf)
P.S. 使用 `ls /usr/bin` ,你會發現各種各樣的命令都放在那裡面。不難發現,與 Windows 中每一個 dos 命令其實都是在呼叫 `%path%` 目錄下的某個可執行檔案的原理類似,而每個 bash 命令也是在執行某處存在的可執行檔案,而你在命令後輸入的引數,則是那個檔案執行時傳入的引數。而**這也是我們在使用 gcc 編譯指令時需要在環境變數 path 裡新增 mingw64\bin 的原因**。
# 三、文字編輯與 Vim 配置
## 小乖乖不會用 Vim
沒錯,小乖乖不會用 Vim。
Vim 的具體使用教程可以參考[runoob](https://www.runoob.com/linux/linux-vim.html)
此處只對一些最基本的使用和注意事項進行一些介紹。
首先,Vim 是基於終端的文字編輯器。
我們知道,在 Linux 的終端下,游標並不會隨著我們滑鼠的點選而移動。但是,我們仍可以利用滑鼠選定一段文字,然後使用 Ctrl+Shift+C 拷貝。
P.S. 貼上和拷貝 (Ctrl+Shift+V) 操作在終端上需要用上 Shift ,而非終端介面下則不需要。以及游標不會隨滑鼠點選移動這一點,是使用 Vim 需要適應的第一個問題。
使用 vim 指令開啟一個檔案後,我們需要通過鍵盤鍵入命令。
![Vim 鍵盤圖](https://www.runoob.com/wp-content/uploads/2015/10/vi-vim-cheat-sheet-sch.gif)
P.S. 不要亂按鍵盤!不要亂按鍵盤!不要亂按鍵盤!在進入底線命令列模式或插入模式前,你在鍵盤上的每次敲擊都可能會被解讀為命令。
目前,小乖乖只會按 **i** 進入插入模式後在上面輸入內容,然後按 **Esc** 退出插入模式,輸入 **:** 進入底線命令列模式。
此處再引用一下 runoob 的三個圖片:(節省空間,只放連結不展開)
[1](https://www.runoob.com/wp-content/uploads/2014/07/078207F0-B204-4464-AAEF-982F45EDDAE9.jpg),
[2](https://www.runoob.com/wp-content/uploads/2014/07/1C928383-471E-4AF1-A61E-9E2CCBD5A913.jpg),
[3](https://www.runoob.com/wp-content/uploads/2014/07/B2FB5146-327C-4019-AC96-DD7A8EE7460C.jpg)。
在底線命令列模式下,比較常用命令如下:
- :w 儲存 (write) 或者說寫入
- :w! 強制寫入只讀檔案 (需要許可權)
- :q 退出,在後面加上 ! 則是不儲存強制退出
- :wq 上面的命令和 ! 也可以組合起來用
- :h 檢視幫助文件(同樣需要 :q 來退出幫助文件)
- :! command 暫時離開 vim 執行某個 shell 命令 (在編寫 shell 指令碼時忘了語法就可以用這個指令)
Vim 有自帶的程式碼縮排。而且高亮也挺好看。可以去試一試。
## 環境變數與 Vim 簡單配置
其實這部分我本來沒打算寫的。結果翻了下網上的部落格,發現自己根本沒有 VIM 這個變數,~ 目錄下也找不到 .vimrc 。被迫自己亂翻了一通。所以乾脆也寫一下好了。
首先是第一個問題:找到配置檔案的位置。
根據網上的部落格,Vim 在安裝時會預設為我們預設一個環境變數 VIM ,只需要 `cd $VIM` 然後找到 vimrc 就可以進行修改。
而現實是,由於某種不知名的原因,我根本沒有這個變數。
P.S. 想檢視環境變數的值,可以使用 `echo $HOME` ,若輸出空行,表明變數為空或不存在。
既然它沒有,那我們可以手動搞一個。 ([參考](https://jingyan.baidu.com/article/ea24bc399a73bcda62b33104.html))
```bash
# 檢視 vim 的安裝和配置檔案位置。
vim --version
# 使用隨便一個文字編輯器開啟 /etc/profile 檔案
sudo vim /etc/profile
# 開啟後在檔案最後加入一行:
# export VIM=/usr/share/vim
# 儲存後,手動在右上角登出就行了。
# 你也可以直接重啟(好像沒區別?)
reboot
```
需要注意的是, export 後面跟的是一個完整的表示式,不能在亂加空格,否則會被解讀為多個並列表示式。此外,/usr/share/vim 這個是根據 `vim --version` 查到的,建議自己查一下不要照搬。
(其實 /etc/vim 裡頭也有一個這樣的東西)
你也可以試著看一下 profile 檔案裡面是啥。~~一不小心可能就學會了 shell 指令碼的迴圈和 if~~
另外,profile 檔案的修改需要登出後生效。
P.S. 直接使用 export 指令也可以設定環境變數,不過跟 Dos 的 set 一樣,設定的這個環境變數是暫時的。想要永久地儲存,只能通過修改系統檔案。
這裡也可以大膽猜測一波,profile 是每次登出重啟後會自動執行的檔案。
事實證明,在我往這個檔案的最末尾新增 `gedit` 後,每次重啟時它都會開啟一次 gedit 的介面。猜想成立。
~~(不過這個是危險動作,在沒有把握時請勿隨意模仿,別亂改檔案把系統改崩了)~~
P.S. 《演算法競賽入門經典第二版》的最後部分有寫到 Linux 下的常用命令,其中有提到 set 可用於修改環境變數。然而在實踐中,我發現 set 指令並沒有這樣的功能(只能顯示而不能修改)。也可能是版本不同的緣故吧。當然,Windows 下的 set 確實有修改變數的功能。
此外,不知道為啥 man export 查不到幫助文件。
嗯,好像跑題了,讓我們繼續 vim 的配置。
經過一波猛如虎的操作,我們打開了 `$VIM/vimrc`
```bash
sudo vim $VIM/vimrc
```
然後小乖乖看到了如圖的註釋,發現裡面並沒有配置項,需要自己寫進去,於是小乖乖意識到需要找到註釋裡的 debian.vim 來參考。
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113133402949-1971270176.png)
~~接著小乖乖發現自己連 VIMRUNTIME 這個環境變數都沒有,根本找不出來。本節完。~~
沒辦法,小乖乖只能去找官網了。結果發現官網要登陸,於是又灰溜溜地回來了。
然後小乖乖試著運行了如下命令: `sudo find / debian.vim`
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113133925271-309684580.png)
當場去世。小乖乖終於意識到自己可能裝了個假 vim。
(也許只是誤會了註釋的含義 debian.vim 這個檔案本來就不存在)
由於裝逼失敗,所以被迫向部落格屈服。小乖乖挑了個[部落格教程](http://www.ruanyifeng.com/blog/2018/09/vimrc.html) 開始照著打了(霧)。
```bash
cd ~ && touch .vimrc
vim .vimrc
# 然後在開啟的檔案中輸入
set tabstop =4
set shiftwidth =4
set nowrap
# :wq 儲存並退出即可
# 至於為什麼要加這兩項配置,因為預設的八空格 tab 是真的毒瘤
```
P.S. 其實 Vim 還有其它強大的功能和外掛,大家可以自行查詢資料,或者我們後續的部落格中也會講到這樣的內容。
## Linux 檔案許可權
小乖乖的 hello world 打炸了。需要寫個對拍。
但是小乖乖不會 bash,所以只能從最基礎的開始學起了。
(其實這裡我想直接抄紫書的程式碼上來的,但是解釋起來太麻煩了,不解釋又顯得很毒瘤,就乾脆隨便編一個別的了)
啊我是不是忘了解釋 shell 是什麼了。可以簡單地與 Windows 下的 cmd 控制檯類比。Shell 是一個應用程式,提供了一種**通過終端視窗用命令列作業系統**的方式。或者說,shell 是一種命令列直譯器。
Linux 的指令碼與 dos 下的指令碼(也就是我們常說的批處理檔案 .bat )非常相似。
簡單地說,指令碼的意義在於把多行的命令提前編寫好,然後通過指令碼來便捷的執行。
當然,指令碼語言也有自己獨特的語法,這裡讓我講清楚是不可能的(因為我也不會)。所以此處只是作為檔案許可權的引入。
首先我們寫一個簡單的指令碼。根據指令碼的語言,我們可以自行選擇字尾名(如 py php)也可以不用字尾名。只需要在最開頭宣告自己的型別就好了。
現在,我們新建一個 test.sh 。
```bash
#!/bin/bash
for i in ~/Desktop/ACM/*.cpp; do
cat $i >> a.txt
done
unset i
```
(這個是我模仿 profile 裡的那個迴圈打的。其實沒有啥用。就是把直接目錄下的 .cpp 全部拷貝到 a.txt 裡)
但是,只有這個是不能執行的。因為新建立的檔案並沒有可執行的許可權。
使用 `ls -l test.sh` 可以看到它的許可權。
(以下內容引自[這裡](https://www.runoob.com/linux/linux-file-attr-permission.html))
r 是 readable 即可讀取,w 是 writeable 即可寫入,x 是 executable 即可執行。
查到的許可權分為三部分:
1. 檔案所有者/超級使用者 u (user)
2. 與檔案所有者在同一群組中的使用者 g (group)
3. 其它的使用者 o (others)
目前,我們只需要知道第一部分其實足夠了。
而第二部分可以像上午的網安導論課上老師講的那樣理解:
比如,所有者是“列印員”中的一員,那麼 g 就是其它同樣是列印員的人具有的許可權。
![](https://www.runoob.com/wp-content/uploads/2014/06/file-llls22.jpg)
P.S. ls 查到的第一個引數是檔案型別。d - 目錄(資料夾) ,- 則是檔案。
我們可以使用 `chmod`(change mode) 修改檔案許可權。
```bash
# 賦予所有使用者執行 test.sh 的許可權
# a 表示 all 所有使用者
chmod a+x test.sh
chmod u+x,g+x,o+x test.sh
# 賦予所有使用者完整的 rwx 許可權
chmod 777 test.sh
```
P.S. 許可權的數字表示:1 對應 x,2 對應 w,4 對應 r。是基於二進位制的三個數位的。
例如,我們希望 u 的許可權為 rwx,r 的許可權為 rw-,o 的許可權為 r--。我們可以這麼幹:
```bash
chmod 764 test.sh
```
在修改完後,我們就可以用 `source test.sh` 來執行了。
# 番外、咕咕篇
按照牛頓第三定律,番外篇肯定是要咕的。不然澳大利亞的袋鼠每年也不會參與印第安人的啤酒節聚餐了,特朗普也不會受到二氧化碳排放增加的影響了。
~~說起來現在才講中文設定是不是有點晚了~~
因為寫太多了我已經懶得再解釋了。自己鼓搗或是看別的我參考的部落格吧。
## Linux 中文 & 時區設定
~~自己鼓搗。我懶得截圖了。~~
說不截還是隨便截一下的。
總之就是在桌面找到 Setting 和 Language Support 那兩個圖示基本就可以完成了。
~~大家手機用得那麼溜翻個設定算什麼。~~
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113135124475-637275396.png)
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113135132087-774067245.png)
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113135449139-1228271022.png)
## Zsh 與 Oh-my-zsh 安裝
zsh 是個好東西。至少目前用起來很舒服。比如 tab 路徑補全和 oh-my-zsh 舒適介面。
zsh 的命令跟 bash 很像。除了 help 命令用不了以外基本一致。
參考[這裡](https://www.cnblogs.com/fcchen/p/12914066.html)
```bash
# 先裝 zsh
sudo apt install zsh
su root
# 安裝的指令去官網 https://ohmyz.sh/#install 查
# 使用 curl 的話你還要這個
sudo apt install curl
# 如果你沒有FQ, 建議使用 wget, 至少我遇到了一點錯誤
sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
# 然後你會看到連線失敗 (403) 的是 raw.githubusercontent.com
# 於是去 site.ip138.com 查下 ip
# 然後調個地理位置較近的如 151.101.76.133 (不曉得是不是固定的,所以還是查一下)
ping 151.101.76.133
# 也可以挑別的 ping 一下,看著差不多還行就 Ctrl+C 強制終止執行
# 用文字編輯器開啟
sudo vim /etc/hosts
# 在最後一行加入 (以 151.101.76.133 為例)
# 151.101.76.133 raw.githubusercontent.com
# 然後再跑一次上面的安裝命令
sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
# 看到作者在終端輸出的那個很騷的 Oh My Zsh 才算成功
```
![](https://img2020.cnblogs.com/blog/2160110/202011/2160110-20201113131006393-560394955.png)
其實在終端的圖形介面上也有可以調的。比如字型、配色。可以去試試。
## Oh-my-zsh 外掛與主題
[參考](https://my.oschina.net/u/2266513/blog/3103451)
```bash
# 在這裡查詢自帶的外掛/主題
ls $ZSH/themes
# 每個外掛資料夾裡面都有個 readme.md
ls $ZSH/plugins
# 在這個目錄下獲取其它的非自帶的外掛/主題
cd $ZSH/custom && ls
# 根據作者的註釋編輯這個檔案來設定外掛/主題
vim .zshrc
# 編輯 .zshrc 檔案。註釋很詳細了。
# 如果你是在安裝時自帶的那幾個裡面挑主題,設定時記得別把字尾名也複製進去了
# 外來外掛的安裝可能相對複雜,參考部落格試一試
```
因為我不會,所以以下內容不限期咕咕咕。部裡的其它小夥伴也可以接坑。
## Linux 硬碟
## Linux 各目錄下檔案功能
## Vim 進階操作與外掛/美化
## Git 基礎操作及原理
## gdb 除錯基礎
## 虛擬機器與主機間的檔案共享
## 虛擬機器與主機間的網路通訊
## Gnome 桌面美化/主題更換
## Shell Script 詳解
## ~~Linux 火狐瀏覽器部分 js 失效的處理~~
## Linux 快捷鍵一覽
## 未完待續
**沒錯上面的我都不會。**
# END