第二章 常用指令
目錄類型指令
cd
(change directory) 切換目錄
最常使用的指令應該就是切換目錄了。切換目錄的指令為 cd [dir]
, 其中 [dir]
為這個指令的參數, 也就是你想要去到的目錄。如果只有打 cd
, 會切換到自己的家目錄。
TomdeMacBook-Pro:~ yychen$ cd Desktop
TomdeMacBook-Pro:Desktop yychen$
如上面的範例, 我們切換到 Desktop 這個目錄。
絕對路徑 vs. 相對路徑
但究竟 Desktop 這個目錄實際上是在哪裡呢? 在我們打開終端機的時候, 預設的目錄就會是在所謂的家目錄, 以我的帳號 (yychen) 為例, 在 macOS 上, 我的家目錄就會在 /Users/yychen
這個地方。
所以剛剛 cd Desktop
其實是切到 /Users/yychen/Desktop
這個地方來。而 Desktop
就是一個相對路徑, /Users/yychen/Desktop
就是一個絕對路徑。相對路徑就是代表在目前所在目錄的相對位置, 絕對路徑就是從根目錄開始。
上一層的相對路徑
上面舉的例子, 是我在 /Users/yychen
這個位置想要進到 /Users/yychen/Desktop
, 我可以直接打相對路徑 Desktop
進入。但萬一我想要切換目錄到上一層怎麼辦? 上一層的相對路徑就是 ..
TomdeMacBook-Pro:Desktop yychen$ cd ..
TomdeMacBook-Pro:~ yychen$
同樣的, 如果我在 /Users/yychen
想要切換到 /Users/Guest
的話該怎麼做?
TomdeMacBook-Pro:~ yychen$ cd ../Guest
TomdeMacBook-Pro:Guest yychen$
家目錄的縮寫
剛剛看到 ..
代表上一層, 其實家目錄也有一個縮寫, 叫做 ~
。所以如果我在別的地方想要跳到自己家目錄底下的 Desktop, 我可以打下列指令
TomdeMacBook-Pro:Guest yychen$ cd ~/Desktop
TomdeMacBook-Pro:Desktop yychen$
當前目錄的縮寫
其實當前的目錄也有一個縮寫, 偶爾會用到, 它跟上一層目錄很像, 但就只有一個點: .
。所以, ls test
跟 ls ./test
是一模一樣的意思。
Finder 叫出家目錄
其實 macOS 預設左邊的側邊欄是看不到所謂的家目錄的, 你可能會看到「桌面」, 「文件」, 「下載項目」... 等等。如果想要在 Finder 叫出家目錄, 在 Finder 偏好設定的側邊欄勾選就會出現了 (圖示看起來是一個房子的)。
pwd
(Print Working Directory) 列印當前目錄
其實剛剛這樣切來切去很容易搞混, 不知道現在自己在哪裡, 因此 pwd
會列出你現在的位置在哪邊, 也就是它會顯示現在目錄的絕對路徑。
TomdeMacBook-Pro:Desktop yychen$ pwd
/Users/yychen/Desktop
ls
(list) 列出目前目錄的項目
這大概也是其中一個最常用的指令, 列出現在目錄的檔案。如果想要多一點資訊, 可以加上 -l
這個參數。如果想要把隱藏檔 (只要是 . 開頭的檔案都算是隱藏檔), 則可以下 -a
這個參數。所以合併起來就是 ls -al
TomdeMacBook-Pro:test yychen$ ls -al
total 8
drwxr-xr-x 4 yychen staff 136 1 6 2016 .
drwxr-xr-x+ 129 yychen staff 4386 7 31 19:10 ..
drwxr-xr-x 3 yychen staff 102 10 15 2015 node_modules
-rw-r--r-- 1 yychen staff 43 10 15 2015 test.js
其中第一欄的 drwxr-xr-x 之類的東西, 是代表這個項目的屬性, 例如第一個 d 代表這個項目是一個目錄。而第五欄則是檔案的大小。如果想要用人性化一點的方式顯示, 可以加上 -h
TomdeMacBook-Pro:test yychen$ ls -alh
total 8
drwxr-xr-x 4 yychen staff 136B 1 6 2016 .
drwxr-xr-x+ 129 yychen staff 4.3K 7 31 19:10 ..
drwxr-xr-x 3 yychen staff 102B 10 15 2015 node_modules
-rw-r--r-- 1 yychen staff 43B 10 15 2015 test.js
它就會告訴你是多少 Bytes 還是多少 KB。
你也可以讓它列出某一個目錄, 例如
TomdeMacBook-Pro:~ yychen$ ls -alh ~/test
total 8
drwxr-xr-x 4 yychen staff 136B 1 6 2016 .
drwxr-xr-x+ 129 yychen staff 4.3K 7 31 19:10 ..
drwxr-xr-x 3 yychen staff 102B 10 15 2015 node_modules
-rw-r--r-- 1 yychen staff 43B 10 15 2015 test.js
檔案操作
cp
(copy) 複製
複製檔案就是把檔案 A 複製成 B, 那指令就是 cp A B
。例如, 我想要把 test.js
複製另一個叫做 test2.js
, 那我可以這樣下指令
TomdeMacBook-Pro:test yychen$ ls
node_modules test.js
TomdeMacBook-Pro:test yychen$ cp test.js test2.js
TomdeMacBook-Pro:test yychen$ ls
node_modules test.js test2.js
當然, 來源跟目的地不一定是要在同一個目錄, 只要路徑有打對即可。
複製目錄
如果要複製整個目錄, 則需要加上 -r
(recursive) 這個參數才行, 不然它會告訴你錯誤
TomdeMacBook-Pro:~ yychen$ cp test test2
cp: test is a directory (not copied).
TomdeMacBook-Pro:~ yychen$ cp -r test test2
TomdeMacBook-Pro:~ yychen$ cd test2
TomdeMacBook-Pro:test2 yychen$ ls
node_modules test.js test2.js
mv
(move) 移動 (重新命名)
搬移檔案, 或你可以想成「重新命名」就是使用 mv
這個指令。如果要把 A 重新命名成 B (或是 A 移動成 B)。這個指令就沒有目錄或檔案的差別了。如果我們想要把剛剛複製的 test2
變成 test3
, 可以這樣下
TomdeMacBook-Pro:~ yychen$ mv test2 test3
它也可以讓你把目錄搬到別的地方, 譬如說你想要把剛剛的 test3 (~/test3) 搬到 test 這個目錄底下
TomdeMacBook-Pro:~ yychen$ mv test3 test
這邊會比較弔詭, 因為已經有 test 這個目錄了。所以這樣的意思是就是把 test3 移動到 test 這個目錄裡面。
rm
(remove) 刪除
刪除檔案就是使用 rm
, 你可以刪除一個檔案 A: rm A
, 或者是刪除好多個檔案 A, B, C: rm A B C
。這個動作很危險, 下了之後是無法挽救的, 它也不會進到垃圾桶裡, 它就是沒了。
TomdeMacBook-Pro:test yychen$ rm test2.js
刪除目錄
如同複製一般, 刪除目錄也需要加上 -r
(recursive)。加上 -r
的這個動作尤其危險, 下這個指令的時候請三思。
TomdeMacBook-Pro:~ yychen$ rm -r test3
其他
grep
搜尋文字
這一個是寫程式非常好用也非常常用到的, 就是從茫茫檔案裡頭中搜尋某個字串。譬如說, 你想要找當前這個目錄裡的檔案, 有出現 title_en
這個字串的檔案有哪些。這通常在要找某個變數出現在哪裡, 或者是你需要修改所有同樣的字串時等等。
TomdeMacBook-Pro:collection yychen$ grep "title_en" *
admin.py: list_display = ('title', 'title_en', 'dynasty', 'dynasty_year', 'year_ce', 'material', 'size')
Binary file admin.pyc matches
forms.py: title_en = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'maxlength': 45}), required=True)
Binary file forms.pyc matches
grep: migrations: Is a directory
models.py: title_en = models.CharField(u'標題 (英文)', max_length=128, blank=True)
models.py: return u'%s %s' % (self.title, self.title_en)
Binary file models.pyc matches
如果你想要搜尋目前目錄, 包含子目錄一樣搜尋, 一樣可以下 -r
(recursive) 這個參數, (有可能)會得到更多結果
TomdeMacBook-Pro:collection yychen$ grep -r "title_en" *
more
顯示檔案
通常都是顯示純文字檔案, 因為這才能印在終端機上。例如
TomdeMacBook-Pro:test yychen$ more test.js
var $ = require('jquery');
console.log($);
如果超過一頁的話, 它會幫你分頁, 你需要按下空白鍵才能到下一頁, 或是 Enter 到下一行, 或是按下 q 結束。
cat
顯示檔案
跟 more
很像, 但是它會一股腦兒的把檔案全部都秀出來
du
列出佔用多少磁碟空間
基本的指令是 du .
或是 du /Users/yychen
, 就是列出當前目錄或是 /Users/yychen
這個目錄所有檔案的大小。如果你下這個指令, 它會把所有的檔案都列出來。但通常, 我們會想要知道整個目錄的結構佔了多少, 因此我們可以下 -d 1
代表我的深度只要一層, 這樣它就會只列出一層。
譬如, 你想要知道大家的家目錄到底佔了多少空間, 可以這樣下
TomdeMacBook-Pro:Users yychen$ du -d 1 .
1176632 ./Shared
729766840 ./yychen
730943472 .
不過這樣好像會看不太懂, 所以一樣可以使用 -h
來讓我們看得比較了解
TomdeMacBook-Pro:Users yychen$ du -h -d 1 .
575M ./Shared
348G ./yychen
349G .
這樣看起來就明瞭多了!
df
列出磁區
這個指令可能比較少用, 但它是非常快速可以看出你的硬碟是否快要滿的指令。它很簡單, 就是只要打 df
就可以了
TomdeMacBook-Pro:Users yychen$ df
Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted on
/dev/disk1 974700800 954980744 19208056 99% 119436591 2401007 98% /
devfs 675 675 0 100% 1169 0 100% /dev
map -hosts 0 0 0 100% 0 0 100% /net
map auto_home 0 0 0 100% 0 0 100% /home
當然, 一樣的, 如果你覺得看不太懂, 可以加上 -h
TomdeMacBook-Pro:Users yychen$ df -h
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk1 465Gi 455Gi 9.2Gi 99% 119438058 2399540 98% /
devfs 338Ki 338Ki 0Bi 100% 1168 0 100% /dev
map -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net
map auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home
sudo
以 root 身份執行...
這個指令可能比較常是在 Linux 底下會用到。有時候我們執行指令需要有最高權限的管理員去執行, 以 Windows 為例, 常常在安裝程式的時候或出現要你按下候或出現要你按下確定確認權限, 是否真的要安裝或執行程式。在 Linux / macOS 也是一樣, 有時候我們輸入的指令必須要以最高層級的權限來執行。
在 Linux / macOS, 其實是有帳號的概念的, 而擁有最高權限的帳號叫做 root
。早年我們在用 Linux 的時候, 都會使用一個叫做 su
的指令, 讓你「變身」為 root。但是這個指令有個缺點, 就是你需要輸入 root 這個帳號的密碼。所以後來就有了另外一個指令叫做 sudo
, sudo
讓你執行指令時變身為 root, 而且輸入的是自身帳號密碼。
例如, 當你在 Ubuntu (Linux) 想要安裝套件時, 就會需要變身 root 來執行套件管理程式, 如
$ sudo apt-get install tmux
當然, 如果你有一連串的指令都要用到 root 權限, 可以用下面的指令, 你的 shell 就會整個都是 root 了, 只是結束時記得要變回來
TomdeMacBook-Pro:~ yychen$ sudo su -
TomdeMacBook-Pro:~ root#
只是結束的時候要記得變回來, 否則你就等於留了一個最高權限的終端機在那兒, 如果有人路過就可以... 做很多黑黑的事情了!
TomdeMacBook-Pro:~ root# exit
logout
TomdeMacBook-Pro:~ yychen$
ps
列出程序
ps
可以列出目前這台電腦跑的程序, 但如果你只打 ps
, 它只會列出現在這個使用者的相關程序。比較常用的指令是 ps aux
, 它會列出全部這台電腦跑的程序。通常這樣打會有很多, 所以我們可能會搭配 more
讓它分頁
$ ps aux|more
或者是搭配 grep
來搜尋包含特定字串的程序, 例如我想要找 firefox, 我可以這樣下
$ ps aux|grep firefox
yychen 21557 1.0 7.0 5763668 1173380 ?? S 7:03下午 11:35.06 /Applications/Firefox.app/Contents/MacOS/firefox
yychen 21967 0.0 0.0 2435864 792 s001 S+ 7:40下午 0:00.00 grep firefox
其中 yychen 右邊的 21557 以及 21967 就是所謂的 process id (pid), 我們知道這個號碼, 就可以用 kill
這個指令的方式把它強制關閉
$ kill 21557
有時候這樣殺不死這隻 process, 就會用最暴力的 kill -9
來把 process 殺死
$ kill -9 21557
它真的滿暴力的, 通常都是用在你自己寫的程式你關不掉, 就會用這樣的方式把它關掉。如果你是用 Linux, 可能有時候你需要 root 權限來關掉, 就要搭配 sudo
執行
$ sudo kill -9 21557
一些小技巧
重複上一次的指令
其實只要按「上」或「下」, 你就可以快速的瀏覽你之前打過的指令, 所以如果你需要重複之前的指令, 不需要死命活命的把指令打出來, 只要一直按「上」往上捲就可以了。
TAB
自動補齊
如果你在使用檔案/目錄相關的指令, 如 cd
、mv
、cp
... 等等, 也就是你的參數會是檔案或目錄的, 你都可以使用 TAB 來協助你。例如, 你在家目錄, 你想要進到「桌面」, 你不需要直接把 cd Desktop
全部打完。你可以先打 cd Des
, 接著按下 TAB
鍵, 你會發現它會幫你把後面自動補完, 指令瞬間就變成 cd Desktop
了。
但是假設有衝突會怎樣? 先打 cd D
然後按著 TAB
鍵, 你會發現電腦叫了一聲。此時你再按一次 TAB
鍵, 它會提示你有哪些 D 開頭的目錄
TomdeMacBook-Pro:~ yychen$ cd D
Desktop/ Development/ Documents/ Downloads/ Dropbox/
此時, 你再多打一些字, 例如剛剛舉例的, 再多打 es
變成
TomdeMacBook-Pro:~ yychen$ cd Des
然後你再按一次 TAB
, 他就會幫你自動補齊了。
快速鍵: Ctrl-U
(游標所在地刪除至行頭)
這個常用在你打錯了, 假設你整行都打錯了, 當然有一種簡單的方式是直接按 Enter
, 但是如果你那一行是可被執行的, 例如 rm -r test
但其實你不想執行了, 除了一直按倒退鍵按到底之外, 你可以直接按 Ctrl-U 它就會幫你從游標所在地刪除至頭。
這一招也可以用在 ssh
連線的時候密碼打錯, 也可以直接 Ctrl-U
然後再輸入正確的密碼, 你就不需要讓它錯一次再重打
快速鍵: Ctrl-A
(到行頭), Ctrl-E
(到行尾)
如標題, 按下 Ctrl-A
可以跳到第一個字元, 按下 Ctrl-E
可以跳到最後一個字元
結語
其實, 這邊只是教 bash
裡面常用的一些指令, 真正強大的是搭配編輯器 vim
以及多工指令 screen
(或 tmux
), 還有其他常用的程式如 git
、python
等才會明瞭它的威力。像是我常常會拿 python
當作計算機 XD
從接下來的章節開始, Terminal 的命令提示字元都會以 $
開頭, 如果看到例如下面的例子, $
就是代表提示的尾巴, 它後面才是要打的指令
$ echo "aloha"
上面的例子就是在終端機裡面鍵入 echo "aloha"
然後按下 Enter
。假設提示符號是 #
則代表這個指令需要以 root
的身份執行, 不論你是用 sudo
或者直接 su
變身都可以。如:
# vipw
就是必須以 root
的身份鍵入 vipw
然後按下 Enter
。