電腦是由硬體和軟體所構成的,而主要負責運算的部分是作業系統的核心 - Kernel。當使用者下了命令之後,Kernel 就會接收這個命令並且再交由 CPU 進行處理。那 Kernel 是如何接收這些命令的呢 ?
可以看到下面這張圖,使用者和 Kernel 會靠著 Shell
作為一個使用者的介面來進行溝通,也就是說使用者下達了命令後,Shell 會將這些命令轉成 Kernel 可以理解的程式碼,再傳送給 Kernel 好讓 Kernel 可以正確地控制硬體工作。
BASH (Bourne Again SHell)
BASH 是 Linux 預設的 Shell,雖然 Shell 有很多種,但是 BASH 會被作為 Linux 預設的 Shell 是因為他的功能非常強大,下面列出幾個主要的優點 :
- 命令紀錄 (history)
相信只要有碰過 Linux 或是 Windows 的 cmd 都會知道,只要命令輸入並執行過,下次只要按向下
和向上
鍵就可以找回輸入過的指令。這些輸入過的指令會先被記錄在 cache 中,當 Shell 被關閉時就會被寫入到~/.bash_history
中,不過這個檔案只會保持一定數量的命令紀錄。
1 | $ cat ~/.bash_history |
-
命令補全
當輸入命令時,可以只輸入指令或是檔案的前幾個字,接著按下tab
鍵就可以將指令或是檔案補齊。 -
命令別名
有些常用的命令可能比較長,這時候就可以使用alias
指令來設定,將命令設成一個別名,之後只要輸入別名就可以執行了。下面我們來實際操作一下,將
ls -a
這個指令設成la
,接著只要輸入la
就可以達成ls -a
的結果。此外,如果要知道有哪些別名的命令可以直接輸入alias
來查看。1
2
3
4
5
6
7
8
9
10
11$ alias la='ls -a'
$ la
'$RECYCLE.BIN'/ Program/
./ PROJECT/
../
$ alias
alias la='ls -a'
alias ll='ls -l'
alias ls='ls -F --color=auto --show-control-chars' -
程式化腳本 (Shell Script)
可以將多個指令寫在一個檔案中,達成連續下指令的動作。這可以大大簡化輸入常用指令的時間,有點類似於程式語言的作法。 -
萬用字元 (Wildcard)
可以透過萬用字元*
結合指令來進行操作。
查詢指令說明文件
想要查詢指令的說明文件可以使用 help
或 man
指令。但是在介紹這些指令前,要先知道指令有分為內部指令 (builtin shell command)
和 外部指令
。內部命令是指本身已經內建於 Shell 的指令,而外部指令是額外安裝的應用,通常會放在 /bin
、/usr/bin
、/sbin
、/usr/sbin
等等。
help
help 指令只適用內部指令,如果要用於外部指令需使用 指令 --help
。
- 內部指令使用 help 的方法如下 :
1 | help <builtin shell command> |
範例
cd 屬於內建於 shell 的指令,所以可以使用 help
指令來查看說明。
1 | $ help cd |
- 外部指令使用 help 的方法如下 :
1 | <command> --help |
範例
docker 是額外安裝的應用,所以屬於外部指令,可以看到直接用 help docker
就會失敗,改用 docker --help
可以成功列出說明文件。如果沒有安裝 docker 可以用 ls
來測試,ls 雖然很像是內部指令,但其實是外部指令。
1 | $ help docker |
man
man 指令可以比 help 指令得到更多詳細的說明,而且 man 也沒有區分內部或是外部指令,都可以使用。不過經過實測 docker
指令會發現說明內容反而比較少,還建議使用 docker --help
來查看,所以其實 man
和 help
可以混合著用,當在其中一個找不到時可以再用另一個指令找看看。
- man 指令使用方式如下 :
1 | man <command> |
範例
下面這個範例使用 man 指令來查看 cd 指令的說明文件,可以看到列出了一堆指令在前面,要往下找才看的到 cd 的。這是因為 cd 是內部的指令,只要用 man 找內部指令就會列出所有內部指令的說明。建議要看內部指令可以搭配 grep
擷取要找的指令就好,例如 : man cd | grep cd
。
1 | $ man cd |
查詢指令是否為內建指令
前面有提到指令有分為內部指令和外部指令,那要怎麼去分辨指令到底是內部的還是外部的呢 ? 可以使用 type
指令來查看。
type
type 指令的使用方式如下 :
1 | type <option> <command> |
option :
- -t : 顯示出指令的意義
- alias : 指令是用別名所設定
- builtin : 內部指令
- file : 外部指令
- -a : 列出指令的路徑
範例
下面就分別來看一下 cd
、ls
、docker
指令分別是屬於外部還是內部指令。首先可以看到 cd
很明確直接顯示屬於內建的指令。而 ls
是用別名設定的指令,並不是內建的指令。最後 docker
很明確的直接列出指令的路徑,並且顯示 file
就是外部指令。
1 | $ type cd |
type -a <command>
也可以用來找指令的路徑,和 which <command>
有一樣的效果,都可以找到指令執行檔的位置。
執行多個指令
當我們想要一次同時下多個指令時,可以透過 ;
, &&
和 ||
來實現。但三者在使用上是有一點區別的,下面我們就直接透過範例來看。
範例
-
分別
;
如果只是要逐一的執行各個指令而不管指令的執行成功與否就可以透過;
來實現。1
2
3
4$ cd tmp ; mkdir tmp ; cd tmp ; pwd
bash: cd: tmp: No such file or directory # 一開始沒有 tmp
/user1/tmp # 後續指令依然繼續執行 -
AND
&&
如果指令有前後相依性的就必須使用&&
來施行,&&
只會在前面的指令執行成功後才執行後面的指令。1
2
3
4$ cd tmp && mkdir tmp ; ls
bash: cd: tmp: No such file or directory
# 一開始沒有 tmp 所以切換目錄失敗後就不會執行建立資料夾的動作 -
OR
||
||
的用法與&&
相反,如果前一個指令執行失敗就會執行第二個,反之如果第一個執行成功就不會執行的二個。1
2
3
4
5
6
7$ cd tmp || mkdir tmp ; ls
bash: cd: tmp: No such file or directory
tmp # 雖然第一個指令失敗但還是執行了第二個
$ mkdir tmp1 || mkdir tmp2 ; ls
tmp tmp1 # 第一個指令執行成功了就不會執行第二個
指令換行
有時候指令會很長,雖然很長並不會有問題,但是對自己來說卻很不好讀。這時候就可以在要換行的時候輸入 \
+ Enter 來跳離 Enter 鍵,此時游標就會跳到下一行就可以繼續輸入了。
範例
下面來看一下實際使用的方式,通常 docker 指令如果有很多設定都會寫很長,這時候使用換行就可以一目了然輸入的指令了。這裡只是要顯示使用的效果,如果不知道 docker 是甚麼也沒有關係,了解換行怎麼用就好。
可以看到在輸入反斜線+換行後,下一行的前面會出現 >
的圖案,這時候就代表可以繼續進行輸入了。
1 | $ docker run \ |
👁🗨 前面有提到換行後會出現 >
符號,這是自動生成的,若是預先打好指令要貼到 terminal 執行時不要自己加上 >
,這樣反而會不能執行。所以如果要預先打好指令則要像下面這個範例 :
1 | docker run \ |
更換 Shell
如果想要切換到其他的 Shell,可以使用 chsh
指令,也就是 change shell
。
1 | chsh <option> <shell name> |
option :
- -s、
--shell
: 代表後面要指定更換的 Shell 名稱。 - -l、
--list-shell
: 列出支援的 Shell。
shell name : 要更換的 Shell,如果 option 是用 -l
要列出支援的 Shell 則不用填 shell name。
範例
下面這個範例列出了目前支援的 Shell,並且我們將 Shell 改成 bash。這就會用在如果你想要安裝其他的 Shell,在安裝完成後就可以透過 chsh
指令來做切換。
1 | $ chsh -l |
Summary
本篇簡單介紹了 Shell 的基本概念,也提供了如何查詢指令說明文件的方法,當不知道或是忘記了指令該怎麼用時,就可以快速的找到指令的說明文件。
參考
[1] 認識與學習BASH
[2] linux:幫助命令help、man、info
[3] No man page for the cd command
[4] 善用 man 指令查詢 Linux 線上手冊(Man Page)