Linux Bash Shell 指令碼入門(3)——Linux常用命令介紹
- Linux Bash Shell 指令碼入門(3)——Linux常用命令介紹
- 透過man來了解任何命令
- 瀏覽檔案系統
- l的長列表資訊
- 過濾輸出列表
- 瀏覽檔案系統
- 複製檔案和目錄
- 刪除檔案和資料夾
- 刪除資料夾
- 連結檔案
- 符號連結(軟連線)
- 硬連結
- 軟連線和硬連線的區別
- 檢視檔案
- cat命令
- 只檢視檔案部分內容
- 檢視檔案末尾(tail命令)
- 檢視檔案頭部(head命令)
- 透過man來了解任何命令
透過man來了解任何命令
man命令可以訪問linux系統的手冊頁,尤其是當你想要弄清命令列引數的時候,就可以檢視對應的命令介紹來了解。
這對剛入門的新手是非常友好的,這裡簡單介紹一下man命令的使用以及效果,man使用格式如下:
man command-name
我們最常用的ls命令來舉例:
man ls
當使用man手冊的時候實際上是linux的pager程式來顯示的,分頁顯示是一種實用工具,能夠逐頁逐行顯示文字,只需要使用Space來進行翻頁或者Enter逐行檢視,假設你使用模擬終端支援箭頭翻閱,也可以使用箭頭向前或者向後滾動手冊頁的內容,至於什麼是模擬終端和真的終端有什麼區別,詳見上一篇。
向下翻頁我們可以看到DESCRIPTION這一小節,瀏覽手冊不是按部就班的學習而是作為快速參考來使用的,DESCRIPTION小節描述了這個命令的一般性描述。每一小節都有一定的內容,我們常用的小節有:
- SYNOPSIS:命令的語法
- DESCRIPTION :命令的一般性描述
- OPTIONS : 命令選項的描述
一般來說命令的使用遵循:
COMMAND-NAME [OPTION] ... [ARGUMENT]...
OPTION 是用於修改命令的行為選項,可新增的OPTION 通常不只有一個,[ ]
表明這內容不是必須的,...
表明可以一次指定多個OPTION, [ARGUMENT]
是傳遞給命令的引數,以指明命令的操作物件,從中括號可以看出,ARGUMENT也不是必選的,同時可以指定多個ARGUMENT來使用。
為了完整介紹命令的格式,我們再找來tar來舉個例子,tar是用來歸檔和壓縮的命令:
tar {A|c|d|r|t|u|x}[GnSkUWOmpsMBiajJzZhPlRvwo] [ARG...]
{ }
這一部分是必須的,大括號 { }
通常表示一組選項或者佔位符,用於表示替換選項或引數的選擇,所以使用的時候必須要帶上至少一個引數,後邊的[ ]
表明GnSkUWOmpsMBiajJzZhPlRvwo
是作為可選引數被加入到命令之中的,相對的A|c|d|r|t|u|x
是必選的,如果仔細看後邊的[ARG...]
也比較神奇,推測省略號是否在外面這兩種寫法沒有太大區別,在全網也沒有找到合適的解釋,這裡就暫且認為二者一致。
瀏覽檔案系統
我們使用ls的時候常常只是ls但是預設的ls顯示的內容常常具有誤導性,我們舉個例子:
Neo@Bionet:~$ ls
cudnn-local-repo-ubuntu2204-9.0.0 Downloads Public snap thinclient_drives
Desktop Music PycharmProjects 'Sunlogin Files' Videos
Documents Pictures Share_Space Templates WorkSpace
Neo@Bionet:~$ ls -aFl
total 1420
drwxr-x--- 41 Neo Neo 4096 4月 20 14:43 ./
drwxr-xr-x 45 root root 4096 4月 18 19:03 ../
drwxrwxr-x 3 Neo Neo 4096 3月 25 12:27 .anaconda/
drwxrwxr-x 3 Neo Neo 4096 3月 25 12:03 .astropy/
-rw------- 1 Neo Neo 27327 4月 20 16:09 .bash_history
............................etc
-rw-r--r-- 1 Neo Neo 24921 4月 3 15:03 .xorgxrdp.18.log.old
ls帶引數和不帶引數二者有巨大的區別,我們透過man可以看到引數的意思如下:
-a, --all
do not ignore entries starting with .
-F, --classify
append indicator (one of */=>@|) to entries
-l use a long listing format
-h, --human-readable
with -l and -s, print sizes like 1K 234M 2G etc.
- F 會在目錄名之後新增/。在可執行檔案之後新增*,以幫助使用者區分對應的內容,但是對於彩色終端不同型別的檔案有不同的顏色,所以這個可以省略
- a 會顯示隱藏檔案
- l 會以長列表的形式列出來所有檔案及其資訊。
- h 會將顯示的大小修改為人類可讀的型別
對於使用來說:
ls -alh
已經完全夠用,且方便記憶。
l的長列表資訊
讓我們來解析一下這裡面的內容:
drwxrwxr-x 3 Neo Neo 4096 3月 25 12:27 .anaconda/
- 第1字母,d代表了檔案的型別,比如目錄(d),檔案是(-)、連結檔案(l)、字元裝置(c)、塊裝置(b)。
- 第2-10的字母和數字,代表了讀寫許可權,這一部分內容會留到許可權篇章介紹,具體可先參看下圖。
- 第11位的數字,代表了檔案的硬連結數目,參看連結小節的內容。
- 後邊的一組字元,代表了檔案的屬主。
- 後邊的一組字元,代表了檔案的屬組。
- 然後是檔案的大小,以位元組的形式表示,這裡表示目錄本身的索引資訊佔據了4096個位元組,並不是代表目錄佔據了4096位元組。
- 檔案的上次修改時間。
- 檔名或者目錄名。
過濾輸出列表
ls 預設情況下會顯示所有非隱藏檔案,但是有時候檔案太多,我們就需要使用過濾器來實現過濾,過濾器是一個字串,可用作簡單的文字匹配,可將其作為命令列引數,放置在選項之後使用,舉個例子:
Neo@Bionet:~/Desktop$ ls -alh pytorch221_cuda122
-rw------- 1 root root 13G 3月 26 14:02 pytorch221_cuda122
其基本格式如下:
ls -alh Filename
當然其威力不僅僅於此,對於filename,其支援標準萬用字元(wildcard),我們可以嘗試如下例子:
ls -alh pytor*
當然效果上,我們可以看到:
也會將對應的檔案顯示出來,萬用字元也包括?、[ ]、!
,效果如下:
當然匹配符有很多,這裡就不再一一贅述。
Neo@Bionet:~/Desktop$ ls -alhi
total 13G
26083455 drwxr-xr-x 2 Neo Neo 4.0K 4月 20 22:23 .
26083329 drwxr-x--- 43 Neo Neo 4.0K 4月 20 22:28 ..
26088183 -rw-r--r-- 1 root root 7 4月 20 21:28 1.txt
26086399 -rw-r--r-- 1 root root 7 4月 20 21:33 2.txt
26083364 -rwxrwxrwx 1 root root 1.4K 4月 20 18:39 creatematlab.sh
26088522 -rwxrwxrwx 1 root root 571 4月 1 11:58 c.sh
26084449 -rwxrwxrwx 1 Neo Neo 1.7K 4月 11 17:16 devel_level.df
26083390 lrwxrwxrwx 1 Neo Neo 32 4月 20 22:23 ln_createusr -> /home/some_scripts/createuser.sh
26084386 -rw------- 1 root root 13G 3月 26 14:02 pytorch221_cuda122
ls -alhi
中的i顯示了inode編號,檔案或目錄的inode編號是核心分配給檔案系統中每一個物件的唯一標識。
複製檔案和目錄
cp命令是將檔案和目錄從檔案系統的一個位置複製到另一個位置,其最基本的用法如下:
cp --help
Usage: cp [OPTION]... [-T] SOURCE DEST
or: cp [OPTION]... SOURCE... DIRECTORY
or: cp [OPTION]... -t DIRECTORY SOURCE...
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
可以看到cp支援的表示式如下:
cp [OPTION]... [-T] SOURCE DEST
通常情況下,如果 cp
命令的目標路徑是一個目錄,則會將原始檔複製到目標目錄中。但是,如果你希望將原始檔複製到一個普通檔案中,並且目標路徑可能會被解釋為目錄,那麼你可以使用 -T
選項來強制 cp
將目標路徑視為普通檔案。
Neo@Bionet:~/Desktop$ sudo cp -T 1.txt 2.txt
需要注意的是這裡的的複製指的是將1的內容直接覆蓋到2上。如果需要強制詢問是否需要覆蓋已有檔案:
$ sudo cp -Ti 1.txt 2.txt
cp: overwrite '2.txt'? y
回答y之後就會覆蓋,任何不是y的回答都取消覆蓋。
cp -Ri Share_Space/ newshare/
會直接將Share_Space/
的內容直接複製到新的資料夾newshare/
當中,遞迴的包含所有的內容。
當然cp也支援使用萬用字元,舉個例子,我們使用cp命令將當前目錄下的所有sh指令碼複製到路徑/home/some_scripts/下中:
:~/Desktop$ sudo cp -i ./*.sh /home/some_scripts/
cp: overwrite '/home/some_scripts/creatematlab.sh'? n
cp: overwrite '/home/some_scripts/createuser.sh'? n
cp: overwrite '/home/some_scripts/c.sh'? n
此操作會將桌面的所有sh指令碼複製過去,因為我已經提前複製了,所以會一個一個詢問是否要覆蓋。
刪除檔案和資料夾
linux中最常用且最危險的命令莫過於rm了。在linux中刪除被叫做移除(removing)。bash shell 中用於刪除檔案的命令是rm。rm命令的基本格式非常簡單:
SYNOPSIS
rm [OPTION]... [FILE]...
舉個例子,我們檢視當前目錄下面的內容,並嘗試刪除一個檔案:
可以看到有一個Dockerfile.swp檔案這是一個快取的交換檔案,並沒有什麼用,我們將其刪除:
rm -i .Dockefile.swp
刪除之後我們可以看到:
此處加入i引數目的是為了提醒自己要刪除對應的檔案了,shell的刪除命令並不存在垃圾箱這種東西,如果一旦不小心刪除那麼就永遠也找不回來了,所以要養成加入i引數的好習慣。
rm的檔案引數同時也支援萬用字元,也就是說可以透過rm一次性刪除很多檔案,這是非常有用的,當你想刪除某一類檔案的時候就可以使用:
rm -i *.sh
此操作會刪除所有的sh指令碼檔案。
刪除資料夾
對於非空目錄rmdir命令足以,但是大多數情況下,目錄中都有內容,我們就必須使用rm命令來實現了。
rm -ri 目錄名或路徑
-r/R
(沒錯此處Rr效果是一樣的)引數會向下進入到目錄中將其內容全部刪除,在這個過程中會一個一個詢問你是否刪除,如果不想這樣,且確認資料真的沒有用處了,我們可以選擇-rf
引數。
效果如下,有以下資料夾:
使用命令進入刪除:
連結檔案
連結檔案可以說是linux系統的優勢,如果需要在系統中維護同一個檔案的兩個或者多個副本的時候可以使用單個物理副本+多個虛擬副本(連結)的方法代替建立多個物理副本,連結是目錄中指向檔案真實位置的佔位符,在linux中有兩種型別的檔案連結:
- 符號連結(軟連線)
- 硬連結
建立連結的命令如下:
Neo@Bionet:~/Desktop$ ln --help
Usage: ln [OPTION]... [-T] TARGET LINK_NAME
or: ln [OPTION]... TARGET
or: ln [OPTION]... TARGET... DIRECTORY
or: ln [OPTION]... -t DIRECTORY TARGET...
In the 1st form, create a link to TARGET with the name LINK_NAME.
In the 2nd form, create a link to TARGET in the current directory.
In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.
Create hard links by default, symbolic links with --symbolic
可以看到不僅可以創造針對檔案的連結,也可以創造針對目錄的連結。
符號連結(軟連線)
符號連結是一個實實在在的檔案,只不過檔案的內容是指向的是虛擬檔案系統中的另一個地方的檔案,這兩個以符號方式連線在一起的檔案彼此的內容並不相同。
舉個例子,我們將剛剛複製的指令碼在桌面刪除,然後以不同的方式連結回來看看。
Neo@Bionet:~/Desktop$ sudo rm ./createuser.sh
Neo@Bionet:~/Desktop$ ln -s /home/some_scripts/createuser.sh ./ln_createusr
# 連結完成之後,顯示當前實際上是一個連結檔案:
Neo@Bionet:~/Desktop$ ls -alh
lrwxrwxrwx 1 Neo Neo 32 4月 20 22:23 ln_createusr -> /home/some_scripts/createuser.sh
# 原始檔並沒有任何變換:
Neo@Bionet:~/Desktop$ ls -alh /home/some_scripts/createuser.sh
-rwxr-xr-x 1 root root 859 4月 20 22:07 /home/some_scripts/createuser.sh
可以看到透過命令:
ln -s /home/some_scripts/createuser.sh ./ln_createusr
我們創造了一個從對應目錄下的檔案的軟連線到桌面的一個新檔案叫ln_createusr
。
使用ls來檢視的時候其檔名部分被替換成了ln_createusr -> /home/some_scripts/createuser.sh
的內容,而不是本身的檔名,這裡的 ->
代表了該檔案是連線到檔案/home/some_scripts/createuser.sh
的一個符號連結。
我們透過上文中兩個 ls -alh
檔案看到,兩個檔案的大小並不相同,原始檔有859個位元組,而連結檔案只有32個位元組
而我們嘗試開啟連結檔案,可以看到:
Neo@Bionet:~/Desktop$ vim ./ln_createusr
顯示內容和原始檔保持一致。當我們嘗試修改的時候因為原始檔許可權的問題,無法修改:
當我們修改許可權以後:
Neo@Bionet:~/Desktop$ sudo chmod 777 /home/some_scripts/createuser.sh
檔案就可以正常修改了,這裡說明連結檔案的許可權取決於原始檔,二者的許可權保持一致。
硬連結
硬連結建立的是一個獨立的虛擬檔案,其中包含了原始檔案的資訊和位置,但是二者本質上是同一個檔案,這是和符號連結的最大區別。
我們再舉一個例子:同樣將上文中複製的檔案從桌面刪除再以硬連線的方式連線回來。
Neo@Bionet:~/Desktop$ rm ./creatematlab.sh
Neo@Bionet:~/Desktop$ sudo ln /home/some_scripts/creatematlab.sh ln_creatematlab
Neo@Bionet:~/Desktop$ ls -alhi
109051906 -rwxr-xr-x 2 root root 1.4K 4月 20 22:07 ln_creatematlab
Neo@Bionet:~/Desktop$ ls -alhi /home/some_scripts/creatematlab.sh
109051906 -rwxr-xr-x 2 root root 1.4K 4月 20 22:07 /home/some_scripts/creatematlab.sh
透過sudo ln /home/some_scripts/creatematlab.sh ln_creatematlab
建立連結之後,我們可以看到:
二者共用一個inode號碼,說明二者是一個檔案。省略引數的情況下,其意思是預設在當前目錄這裡建立一個名字一樣的硬連結,雖然下圖建立失敗了,但是其詳細展示了建立的內容:
軟連線和硬連線的區別
- 軟連線(Symbolic Link):
- 軟連線類似於Windows系統中的快捷方式(Shortcut)。
- 它是一個特殊的檔案,包含了對另一個檔案或目錄的引用路徑。
- 軟連線不依賴於原始檔案的檔名,即使原始檔案被移動或重新命名,軟連線依然有效。
- 軟連線可以跨檔案系統,即可以連結到不同檔案系統中的檔案。
- 刪除原始檔案會導致軟連線失效,因為它只是指向原始檔案的一個路徑。
- 硬連線(Hard Link):
- 硬連線直接指向檔案的物理位置,即檔案的inode節點。
- 硬連線與原始檔案共享同一個inode,因此它們實際上是同一個檔案。
- 硬連線不能跨檔案系統,只能在同一檔案系統中建立。
- 硬連線不能連結到目錄,只能連結到檔案。
- 刪除原始檔案不會影響硬連線,因為只要有一個硬連線存在,檔案內容就不會被刪除。
硬連結(Hard Link)不會佔用兩倍的空間。實際上,硬連結與原始檔案共享相同的儲存空間,它們指向同一個inode節點。這意味著,無論有多少個硬連結指向同一個檔案,它們都只佔用原始檔案所佔用的儲存空間。
在UNIX和類UNIX系統中,檔案的內容和檔案的後設資料(如檔名、許可權、所有者等)是分開儲存的。檔案的內容儲存在資料塊中,而後設資料儲存在inode節點中。硬連結和原始檔案都指向同一個inode節點,因此它們共享相同的資料塊。
舉個例子我想檢視如何使用 tar 命令進行歸檔的壓縮和解壓就可以使用:
man tar
效果如下:
這裡tar的語法描述如下:
SYNOPSIS
Traditional usage
tar {A|c|d|r|t|u|x}[GnSkUWOmpsMBiajJzZhPlRvwo] [ARG...]
UNIX-style usage
tar -A [OPTIONS] ARCHIVE ARCHIVE
.......
tar -x [-f ARCHIVE] [OPTIONS] [MEMBER...]
GNU-style usage
tar --create [--file ARCHIVE] [OPTIONS] [FILE...]
.......
tar {--extract|--get} [-f ARCHIVE] [OPTIONS] [MEMBER...]
這一部分描述了常用的方式:
Traditional usage
tar {A|c|d|r|t|u|x}[GnSkUWOmpsMBiajJzZhPlRvwo] [ARG...]
引數瞭解之後,可以看看這些引數有什麼用:
關於引數的內容linux的執行手冊有的內容非常多而且不一致,我們可以換個方式來快速檢視, 大多數命令都支援-h選項來實現,更快速的資訊獲取:
Neo@Bionet:~/Desktop$ tar --help
Usage: tar [OPTION...] [FILE]...
GNU 'tar' saves many files together into a single tape or disk archive, and can
restore individual files from the archive.
Examples:
tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.
tar -tvf archive.tar # List all files in archive.tar verbosely.
tar -xf archive.tar # Extract all files from archive.tar.
Main operation mode:
-A, --catenate, --concatenate append tar files to an archive
-c, --create create a new archive
--delete delete from the archive (not on mag tapes!)
-d, --diff, --compare find differences between archive and file system
-r, --append append files to the end of an archive
--test-label test the archive volume label and exit
-t, --list list the contents of an archive
-u, --update only append files newer than copy in archive
-x, --extract, --get extract files from an archive
Operation modifiers:
--check-device check device numbers when creating incremental
archives (default)
-g, --listed-incremental=FILE handle new GNU-format incremental backup
-G, --incremental handle old GNU-format incremental backup
--hole-detection=TYPE technique to detect holes
--ignore-failed-read do not exit with nonzero on unreadable files
--level=NUMBER dump level for created listed-incremental archive
--no-check-device do not check device numbers when creating
incremental archives
獲取的資訊,擷取了一部分,這樣就避免了翻頁程式過於正式的效果,反而看清楚該如何使用命令。
我們找到解壓的引數 -x
作為主引數,同時瀏覽一下常用的vf引數是什麼意思:
-f, --file=ARCHIVE use archive file or device ARCHIVE
檢視檔案
檢視檔案是linux最重要的特性,有了這些檢視命令的支援,相較於windows那些作業系統,在有大檔案的時候linux不僅能開啟,並且能快速檢視當中的內容。
當你手頭有一個很大的文字檔案,你可能會想看一看到底是什麼,linux有幾個經典的命令來實現這個操作,我們只介紹當中比較常用的命令。
cat命令
cat命令是最基礎的檔案探查命令,當你查詢資料的時候經常能看到,所以這裡介紹一下:
我們有一個test檔案裡面包含多行的內容:
我們使用cat來檢視一下:
cat -n test
效果如下:
neo@NeoNeuxs:~/Desktop$ cat -n test
1 123456
2 12345
3 1234
4 123
5 12
6 1
7
8
這裡就沒有什麼特別的,其顯示的內容就是對應的資訊,其中有多種變形的引數,這裡-n
代表顯示行號,同時還有-b
選項只給有文字的行加上行號,效果如下:
neo@NeoNeuxs:~/Desktop$ cat -b test
1 123456
2 12345
3 1234
4 123
5 12
6 1
neo@NeoNeuxs:~/Desktop$
對於cat來說當其應對大檔案尤其是超大檔案的時候他會不停的重新整理模擬終端的內容來顯示,我們無法檢視到底有什麼,為了解決這個問題我們可以使用less。
less命令提供了非常多的實用特性,能夠實現文字檔案中的前後翻動,還有一些高階搜尋功能。最主要的是less能夠實現在完全讀取檔案之前,顯示檔案的部分內容,cat和more是無法實現的,為了驗證這個功能我們來找一個大的檔案來進行操作,
neo@NeoNeuxs:~/Desktop/PTM/Dataset/uniprot$ less ./uniprotkb_AND_reviewed_true_AND_model_o_2024_04_25.tsv
uniprotkb是一個蛋白質庫,其中記錄了許多蛋白質序列,我們使用less來檢視裡面的內容,顯示如下:
由於資料的每一行都非長的長,當達到螢幕極限的時候就會換行,less是按頁來顯示的,我們可以透過鍵盤的pgup、pgdn,或者空格來翻頁檢視,其載入速度並不取決於檔案大小而在於每一頁的內容,這樣當你使用vcode、等編輯器無法一下開啟檢視資訊的時候就是less大發神威的時候,如下圖,此檔案達到了100多MB,算是比較小的,但是使用其他檔案閱讀器開啟還是比較慢,less在一瞬間就可以開啟,並檢視其中的內容。
只檢視檔案部分內容
你需要檢視的檔案有時候經常位於檔案的開頭或者結尾,當檔案很大的時候,你就只能乾等著cat或more來載入整個檔案,當然linux也提供了專門的命令來解決這個問題,下面就會介紹 tail、head命令。
檢視檔案末尾(tail命令)
tail命令會顯示檔案的末尾的內容,預設情況下會顯示檔案末尾的最後10行,我們還是使用剛才的檔案來檢測:
neo@NeoNeuxs:~/Desktop/PTM/Dataset/uniprot$ tail ./dbPTM_Phosphorylation
ZO3_HUMAN O95049 919 Phosphorylation 18669648 KKFMRVHDAESSDEDGYDWGP
ZO3_HUMAN O95049 920 Phosphorylation 18669648 KFMRVHDAESSDEDGYDWGPA
ZO3_HUMAN O95049 925 Phosphorylation 18669648 HDAESSDEDGYDWGPATDL--
ZRAB2_HUMAN O95218-2 9 Phosphorylation 18669648 --MSTKNFRVSDGDWICPDKK
ZRAB2_HUMAN O95218-2 114 Phosphorylation 18669648 GGFNERENVEYIEREESDGEY
ZRAB2_HUMAN O95218-2 120 Phosphorylation 18669648 ENVEYIEREESDGEYDEFGRK
ZRAB2_HUMAN O95218-2 153 Phosphorylation 18669648 SILKEVEDKESEGEEEDEDED
ZRAB2_HUMAN O95218-2 181 Phosphorylation 18669648 EDEDEDDADLSKYNLDASEEE
ZRAB2_HUMAN O95218-2 183 Phosphorylation 18669648 EDEDDADLSKYNLDASEEEDS
ZRAB2_HUMAN O95218-2 188 Phosphorylation 18669648 ADLSKYNLDASEEEDSNKKKS
-n
可以顯示指定行數,效果如下:
neo@NeoNeuxs:~/Desktop/PTM/Dataset/uniprot$ tail -n 1 ./dbPTM_Phosphorylation
ZRAB2_HUMAN O95218-2 188 Phosphorylation 18669648 ADLSKYNLDASEEEDSNKKKS
tail最重要的引數是-f
其可以實現線上重新整理的效果,當有新的資料寫到檔案的時候會自動重新整理。
檢視檔案頭部(head命令)
head命令的使用方式幾乎和tail一樣,只不過顯示的內容是頭部的,相同的命令引數-n也可以指定當前顯示的行數。