一個關於UNIX檔案系統指令集的簡短指南
我寫這份手冊的目標是讓學習、記憶和查詢主要UNIX檔案系統工具更容易。macOS和GNU/Linux都是UNIX系統,在實際應用中。macOS是基於BSD UNIX的認證UNIX,而GNU/Linux是UNIX相似或UNIX衍生。
在介紹檔案系統和它如何運作之後,我將詳細說明以下指令的細節:
處理資料夾和檔案
mkdir
cd
pwd
rmdir
ls
touch
mv
cp
ln
權限
chmod
chown
chgrp
檔案內容
cat
less
find
cpio
dd
wc
檔案系統如何運作
每台現代化的電腦系統都依賴檔案系統以儲存和擷取程式。並非所有的東西都可以儲存在記憶體中,因為它是珍貴和有限的資源。所以,當電腦重新啟動或關機時,我們需要一個安全的地方來存儲資料。
記憶體在每次電腦重新啟動時都會被完全清除,而磁碟結構是持久存在的。
在這份指南中,我將專門介紹UNIX檔案系統,該系統可以在macOS和GNU/Linux機器上找到。Windows的檔案系統是不同的,雖然安裝了Windows子系統的Windows 10允許您使用我在這裡描述的相同工具。
檔案系統始於/
(根目錄)。這是第一層目錄的根節點。
UNIX系統中通常會找到的目錄有
/bin
包含主系統指令/etc
包含系統配置/dev
包含系統設備/usr
包含使用者檔案/tmp
包含臨時檔案
當然要根據使用的系統類型的不同而有所不同。Linux 通過其Linux Standard Base的努力使這些目錄時一樣的,您通常有:
/bin
主系統指令/boot
用於引導機器的檔案(在macOS上不存在)/dev
系統設備/etc
系統配置檔案/etc/opt
使用者程式配置檔案/home
使用者的家目錄(/Users在macOS上)/lib
系統庫(在macOS上不存在)/mnt
掛載的檔案系統/opt
使用者程式/proc
系統由內核和程序(在macOS上不存在)/root
系統管理者的家目錄(在macOS上不存在)/run
(在macOS上不存在)/sbin
開機系統二進制檔案/tmp
臨時檔案/usr
包含使用者軟件、庫和工具/usr/bin
使用者二進制檔案/usr/include
使用者頭檔案/usr/lib
使用者庫/usr/local
由使用者軟件用於儲存安裝,像在macOS上的Homebrew/usr/sbin
系統二進制檔案/usr/share
包含與架構無關的資料,可能包含大量的其他資訊,包括文件和手冊/usr/src
包含已安裝套件的原始碼(在macOS上不存在)/var
包含臨時檔案,日誌等
macOS有很多不同的目錄,包括
/Applications
存放使用者應用程式/Library
存放系統的全域使用圖書館(設置和資源)/System
存放系統檔案/private
存放系統檔案,日誌等
每個目錄都包含檔案和子目錄,這些子目錄本身又可以包含其他檔案和子目錄,依此類推。
所有的檔案和目錄都有一個名字。
什麼是一個有效的名字? 它可以由1到255個字符組成,必須由任何字母或數字(a-z
/A-Z
/0-9
),底線 (_
),點(.
) 和逗號(,
)字符構成。
您也可以使用空格,但通常不建議使用,因為每次引用檔案/目錄時都必須將空格用反斜線進行轉義。
根據不同的系統,檔案系統可能是區分大小寫的。在macOS上,檔案系統預設為不區分大小寫, 所以您不能有一個名稱為test
的檔案/目錄和一個名為Test
的檔案/目錄。它們是同一樣東西。
現在我要介紹一些不同的實用指令。這些指令在shell (如Bash、Fish或Zsh)的上下文中執行。當您開啟一個shell時,一般都會在您的家目錄。在macOS中,這個目錄可以在/Users/<您的名字>/
路徑中找到。
如果更改所使用的shell,這些指令不會變化,因為這些是UNIX的基本指令。在世界計算的革命發生之前(雖然那種事情確實存在,但那些服務器端的東西通常移動很慢),您往往需要使用這些指令數十年。舉個例子, 您現在將看到的 mkdir
指令引入至UNIX AT&T的第一版中,早於80年代初。
處理資料夾和檔案
mkdir
使用mkdir
指令創建資料夾:
mkdir fruit
您可以使用一個指令創建多個資料夾:
mkdir dogs cars
您也可以通過添加-p
選項創建多層資料夾:
mkdir -p fruits/apples
UNIX指令中的選項通常採取這種形式。您將它們添加在指令名之後,並通過它們來更改指令的行為。您還可以結合使用多個選項。
您可以通過輸入man <commandname>
找到指令所支援的選項。例如,現在嘗試使用man mkdir
(按下q
鍵退出man頁面)。Man頁是UNIX內置的令人驚歎的幫助文檔。
cd
一旦創建了資料夾,您可以使用cd
指令進入資料夾。cd
代表change directory(切換目錄)。您調用它指定要移動到的資料夾。您可以指定資料夾名稱或完整路徑。
例子:
mkdir fruits
cd fruits
現在您進入了fruits
資料夾。
您可以使用..
特殊路徑來指示父資料夾:
cd .. # 返回家目錄
您可以使用它來形成一個路徑:
mkdir fruits
mkdir cars
cd fruits
cd ../cars
還有另一個特殊的路徑指示器.
,表示當前資料夾。
您還可以使用絕對路徑,從根資料夾/
開始:
cd /etc
pwd
每當您在檔案系統中感到迷失時,使用pwd
指令來查看您的位置:
pwd
它將列印出當前資料夾的路徑。
rmdir
就像您可以使用mkdir
創建資料夾一樣,您可以使用rmdir
指令刪除資料夾:
mkdir fruits
rmdir fruits
您還可以一次刪除多個資料夾:
mkdir fruits cars
rmdir fruits cars
要刪除包含有檔案的資料夾,我們將使用更通用的rm
指令來刪除檔案和資料夾,使用-rf
選項:
rm -rf fruits cars
請小心,因為該指令不會請求確認,它會立即刪除您要求刪除的所有項目。
如果沒有垃圾桶可用時,删除檔案後將很難恢复丟失的檔案。
ls
在資料夾內,您可以使用ls
指令列出資料夾包含的所有檔案:
ls
如果添加檔案名或路徑,它將列印該資料夾的內容:
ls /bin
ls
接受很多選項。我最喜歡的選項組合之一是-al
。現在試試看:
ls -al /bin
與普通的ls
相比,此選項返回更多的資訊。
從左到右,您有:
- 檔案許可權(如果您的系統支持ACLs,您還會得到ACL標誌)
- 對該檔案的連結數
- 檔案的所有者
- 檔案的群組
- 檔案的字節大小
- 檔案的修改日期時間
- 檔案名稱
此數據集是由l
選項生成的。a
選項同樣會顯示隱藏的檔案。
隱藏檔案是以點(.
)開頭的檔案。
touch
您可以使用touch
指令創建一個空檔案:
touch apple
如果檔案已經存在,它會以寫入模式開啟該檔案,並更新檔案的時間戳。
mv
一旦有了檔案,您可以使用mv
指令將其移動到其他位置。指定檔案的當前路徑和其新路徑:
touch test
mv pear new_pear
現在pear
檔案被移動到new_pear
。這是如何重新命名檔案和資料夾的方式。
如果最後一個參數是一個資料夾,位於第一個參數路徑的檔案將移動到該資料夾中。在這種情況下,您可以指定一列檔案,它們將全部被移動到由最後一個參數識別的資料夾路徑中:
touch pear
touch apple
mkdir fruits
mv pear apple fruits #pear和apple移至於fruits資料夾
cp
您可以使用cp
指令複製檔案:
touch test
cp apple another_apple
要複製資料夾,您需要在後面添加-r
選項,以遞迴複製整個資料夾內容:
mkdir fruits
cp -r fruits cars
ln
現在讓我們介紹鏈結的概念。鏈結是指向其他檔案的檔案。我們在所有主要的操作系統上都有這些。
我們可以創建兩種類型的鏈結:硬鏈結和符號(軟)鏈結。我們無法創建指向資料夾的硬鏈結,但我們可以創建一個符號鏈結。因此,符號鏈結(也稱為symlinks)更為常見。
我們使用以下語法創建符號鏈結:ln -s original linkname
。例如:
mkdir fruits
ln -s fruits newfruits
請注意我使用的
ll
命令。這不是標準命令,但是ls -al
的別名。在shell中,您可以定義別名,以便快速執行常見的命令和參數組合。
權限
我之前簡單提到權限,當我介紹ls -al
指令時。
您在每個檔案行上看到的奇怪字符串,如drwxr-xr-x
,定義了檔案或資料夾的權限。
讓我們來解析它。
第一個字母表示檔案的類型:
-
表示它是一個普通檔案d
表示它是一個資料夾l
表示它是一個鏈結
接下來是3組值:
- 第一組表示檔案的擁有者的權限
- 第二組表示檔案所屬群組中的成員的權限
- 第三組表示其他人的權限
這些集合由3個數值組成。rwx
表示特定的身份有讀取、寫入和執行許可權。刪除的任何東西都將用 -
來代替,它允許您組合不同的數值和相對權限: rw-
,r--
,r-x
等.
您可以使用chmod
指令更改賦予檔案的權限。
chmod
可以使用兩種方式。首先是使用符號參數,其次是使用數字參數,我們先從比較直觀的符號參數開始。
您輸入chmod
之後加入一個空格和一個字母:
a
代表全部(all)u
代表使用者(user)g
代表群組(group)o
代表其他人(others)
接著您輸入+
或 -
來新增/刪除權限。然後輸入一個或多個權限符號(r
, w
, x
)。
最後輸入檔案或資料夾名稱。
以下是一些例子:
chmod a+r filename #所有人現在都可以讀取
chmod a+rw filename #所有人現在都可以讀取和寫入
chmod o-rwx filename #其他人(不是檔案的所有者,不在同一個群組中的人)不能讀取、寫入或執行該檔案
您可以通過在+
/-
之前添加多個字母來將相同的權限應用於多個身份:
chmod og-r filename #其他人和群組不能再讀取
如果您編輯的資料夾,可以使用-r
遞歸標誌將權限應用到該資料夾中包含的每個檔案。
數字參數比較快,但我覺得它們很難記住,除非您在日常使用它們。您使用表示身份權限的數字,這個數字的最大值為7,並且它的計算方式如下:
1
如果具有執行權限2
如果具有寫入權限4
如果具有讀取權限
這給我們4種組合:
0
沒有權限1
可以執行2
可以寫入3
可以寫入、執行4
可以讀取5
可以讀取、執行6
可以讀取、寫入7
可以讀取、寫入、執行
我們將它們成對使用以指定所有3組權限:
chmod 777 filename
chmod 755 filename
chmod 644 filename
所有者和群組
您可以使用chown
指令更改檔案的所有者:
chown <username> <filename>
您可以使用chgrp
命令更改檔案所屬的群組:
chgrp <group> <filename>
管理檔案內容
less
我絕大部分時間都在使用less
命令。它以漂亮且互動的界面顯示檔案內容。
使用方法:less <filename>
。
一旦您進入less
會話,您可以通過按q
退出。
您可以使用上
和下
鍵來瀏覽檔案內容,也可以使用空格鍵
和b
鍵進行分頁瀏覽。您可以通過按G
跳轉到文件末尾,按g
跳轉回開始。
您可以按/
搜索檔案內容,並輸入要搜索的字詞。這將向前搜索。您可以使用?
符號和輸入單詞來向後搜索。
該命令僅可視化檔案的內容。通過按 v
鍵,您可以直接打開編輯器。它將使用系統編輯器,在大多數情況下是 vim
。
按下F
鍵進入跟隨模式,或即時模式。當檔案被其他程序更改時,如使用其他程序更改檔案時,您可以實時查看更改的檔案。默認情況下,這不會發生,您只會看到您打開它時的檔案版本。您需要按 ctrl-C
退出此模式。在這種情況下,行為類似於運行tail -f <filename>
命令。
您可以打開多個檔案,並使用:n
(切換到下一個檔案)和:p
(切換到前一個檔案)進行瀏覽。
tail
我剛才在前一個指令中提到了 tail
,所以讓我們利用這個機會來解釋它是什麼。
在我看來,它最好的使用情況是使用 -f
選項時。它打開檔案在最後一行,並且監視檔案內的變化。每次檔案中有新內容時,都會將其打印到窗口中。這在監視日誌檔案時非常有用,例如:
tail -f /var/log/system.log
要退出,按ctrl-C
。
您可以打印出檔案中的最後10行:
tail -n 10 <filename>
可以使用 +
後跟行號來打印從特定行開始的整個檔案內容:
tail -n +10 <filename>
tai
創建的功能還有更多,建議您查閱 man tail
。
cat
有點類似於tail
,但cat
還可以向檔案中添加內容,這使其非常強大。
在最簡單的用法中, cat
將檔案的內容打印到標準輸出:
cat file
您可以列印多個檔案的內容:
cat file1 file2
並使用輸出重定向操作符>
將多個檔案的內容串連到一個新的檔案中:
cat file1 file2 > file3
使用>>
,您可以將多個檔案的內容附加到一個新的檔案中,如果檔案不存在,則創建該檔案:
cat file1 file2 >> file3
查看原始碼時,如果能打印行號就很好,您可以使用-n
選項讓cat
打印行號:
cat -n file1
您只能使用-b
在非空行上添加行號,或者也可以使用-s
來刪除多個空行。
cat
通常與管道操作符 |
搭配使用,將檔案的內容作為輸入傳給其他指令:cat file1 | anothercommand
。
wc
wc
代表 word count (字個數)。這是最常見的使用場景:
wc -l file1
计算行數wc -w file1
计算字數wc -c file1
计算字符數wc -m file1
用多字节支持字符,例如任务字符數(例如, 表示為一個字符而不是多個字符)
您可以在多個檔案上運行 wc
,在這種情況下它將單獨對每個檔案進行計算,然後打印總數:
find
find
指令用於根據特定的搜索模式尋找符合條件的檔案或資料夾。它遞迴搜索。
讓我們通過例子來學習它。
查找當前資料夾下樹內具有.js
副檔名的所有檔案,並打印出每個匹配檔案的相對路徑:
find . -name '*.js'
使用引號將特殊符號(*
)包圍起來,以避免shell進行解析。
查找當前樹下名稱為src
的資料夾:
find . -type d -name src
使用-type f
只搜索檔案,使用-type l
只搜索符號鏈結。
-name
是區分大小寫的。 使用-iname
進行大小寫不區分搜索。
您可以在多個根目錄下進行搜索:
find folder1 folder2 -name filename.txt
查找當前樹下名稱為node_modules
或 public
的資料夾:
find . -type d -name 'node_modules' -or -name 'public'
您還可以使用-not -path
來排除路徑:
find . -type d -name '*.md' -not -path 'node_modules/*'
您可以搜索文件中包含超過100個字符(字節)的檔案:
find . -type f -size +100c
搜索大於100KB但小於1MB的檔案:
find . -type f -size +100k -size -1M
搜索超過3天沒修改的檔案:
find . -type f -mtime +3
搜索在過去24小時內修改的檔案:
find . -type f -mtime -1
您可以通過添加-delete
選項來刪除匹配搜索條件的所有檔案。以下示例將刪除在過去24小時內編輯的所有檔案:
find . -type f -mtime -1 -delete
您可以對搜索結果中的每個項目執行一個命令。例如,我們運行cat
來打印檔案內容:
find . -type f -exec cat {} \;
注意結束的\;
。{}
會在執行時填充為檔案名稱。