主頁 > 作業系統 > Linux作業原理2常用基本命令和目錄層次結構

Linux作業原理2常用基本命令和目錄層次結構

2023-05-29 10:30:37 作業系統

本章是對本書中你將遇到的Unix命令和工具的指南,

為什么是Unix命令?這不是一本關于Linux如何作業的書嗎?當然是的,但Linux在本質上是一種Unix風格,在本章中,你會看到Unix這個詞,而不是Linux,因為你可以把你學到的東西直接帶到BSD和其他Unix風味的系統中去,我試圖避免涉及太多Linux特有的用戶界面擴展,這不僅是為了給你使用其他作業系統提供更好的背景,而且也是因為這些擴展往往是不穩定的,如果你知道核心命令,你就能更快地適應新的Linux版本,此外,了解這些命令可以促進你對內核的理解,因為許多命令直接對應于系統呼叫,

注意:如果想了解比這里更多的關于Unix初學者的細節,可以考慮閱讀《The Linux Command Line》第二版(No Starch Press, 2019),《UNIX for the Impatient》第二版(Addison-Wesley Professional, 1995),以及《Learning the UNIX Operating System,》第五版(O'Reilly, 2001),

2.1 Bourne Shell: /bin/sh

shell是Unix系統中最重要的部分之一,shell是一個運行命令的程式,就像用戶在終端視窗中輸入的命令,這些命令可以是其他程式或shell的內置功能,shell還可以作為小型的編程環境,Unix程式員經常將普通的任務分解成較小的組件,并使用shell來管理任務和拼湊事情,

系統的許多重要部分實際上是shell腳本--包含shell命令序列的文本檔案,如果你以前使用過MS-DOS,你可以把shell腳本想象成非常強大的.BAT檔案,因為它們很重要,第11章完全是關于shell腳本的,

隨著你在本書中的學習和實踐,你會增加你對使用shell操作命令的知識,shell最好的一點是,如果你犯了錯誤,你可以很容易地看到你輸入的內容,找出錯誤的原因,然后再試一次,

有許多不同的Unix shell,但所有的功能都來自Bourne shell(/bin/sh),這是貝爾實驗室為早期版本的Unix開發的標準外殼,每個Unix系統都需要一個版本的Bourne shell,以便正常運行,正如你在本書中看到的那樣,

Linux使用Bourne shell的增強版本,稱為bash或 "Bourne-again "shell,bash shell是大多數Linux發行版上的默認shell,在Linux系統中,/bin/sh通常是bash的鏈接,在運行本書中的例子時,你應該使用bash shell,

注意
如果你在一個你不是系統管理員的組織中使用本章作為Unix賬戶的指南,你可能沒有把bash作為你的默認shell,你可以用chsh改變你的shell或者向你的系統管理員尋求幫助,

2.2 使用Shell

當你安裝Linux時,你應該至少創建一個普通用戶,作為你的個人賬戶,在本章中,你應該以普通用戶的身份登錄,

2.2.1 Shell視窗

登錄后,打開shell視窗(通常被稱為終端),從Gnome或KDE這樣的GUI中這樣做的最簡單方法是打開終端程式,在新視窗中啟動shell,一旦你打開了shell,它應該在頂部顯示提示,通常以美元符號($)結尾,在Ubuntu上,這個提示符應該是name@host:path$,在Fedora上是[name@host path]$,其中name是你的用戶名,host是你機器的名字,path是你當前的作業目錄(見2.4.1節),如果你熟悉Windows,shell視窗看起來就像DOS的命令提示符;在macOS中,終端程式基本上與Linux的shell視窗相同,

本書包含許多你將在shell提示符下輸入的命令,它們都以一個$開頭,表示shell提示符,例如,輸入這個命令(只輸入粗體部分,不輸入$),然后按ENTER鍵:

andrew@andrew-HP:~$ echo Hello there.
Hello there.

注意:本書中的許多shell命令以#開頭,你應該以超級用戶(root)的身份運行這些命令,所以需要特別小心,在運行這些命令時,最好的做法是使用sudo,以便提供一些保護,并有日志,你可以在以后查找可能的錯誤,你將在第2.20節看到如何做到這一點,

現在輸入這個命令:

andrew@andrew-HP:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
...

這個命令顯示了/etc/passwd系統資訊檔案的內容,然后回傳你的shell提示,現在不要關注這個檔案的作用,你將在第7章中了解它的全部內容,

命令通常以要運行的程式開始,后面可能有引數,告訴程式要對什么進行操作以及如何操作,這里,程式是cat,有一個引數,即/etc/passwd,許多引數是修改程式默認行為的選項,通常以破折號(-)開頭,你很快就會在討論ls的時候看到這一點,然而,有一些例外情況并不遵循這種正常的命令結構,比如shell的內置引數和環境變數的臨時使用,

2.2.2 cat

cat程式是Unix中最容易理解的程式之一;它簡單地輸出一個或多個檔案的內容或另一個輸入源,cat命令的一般語法如下:

$ cat file1 file2 ...

當你運行這個命令時,cat會列印file1、file2和任何其他你指定為引數的檔案(在前面的例子中用...表示)的內容,然后退出,該程式被稱為cat,因為它在列印多個檔案的內容時執行串聯操作,有很多方法可以運行cat;讓我們用它來探索Unix的I/O,

2.2.3 標準輸入和標準輸出

Unix行程使用I/O流來讀和寫資料,行程從輸入流中讀取資料,并將資料寫到輸出流中,流是非常靈活的,例如,輸入流的源頭可以是一個檔案、一個設備、一個終端視窗,甚至是另一個行程的輸出流,

要看正在作業的輸入流,請輸入cat(沒有引數)并按下ENTER,這一次,你不會得到任何直接的輸出,你也不會得到你的shell提示符,因為cat仍然在運行,現在輸入任何內容,并在每一行的末尾按回車鍵,像這樣使用時,cat命令會重復你輸入的任何一行,一旦你覺得足夠無聊,就在一個空行上按CTRL-D來終止cat并回傳shell提示符,

cat在這里采用互動式行為的原因與流有關,當你沒有指定輸入檔案名時,cat從Linux內核提供的標準輸入流而不是連接到檔案的流中讀取,在這種情況下,標準輸入被連接到你運行cat的終端,

注意:在空行上按下CTRL-D會以EOF(檔案結束)資訊停止當前終端的標準輸入條目(通常也會終止一個程式),不要把它與CTRL-C混淆,后者通常會終止一個程式,而不管其輸入或輸出,

標準輸出是類似的,內核給每個行程一個標準輸出流,它可以在那里寫出它的輸出,cat命令總是把它的輸出寫到標準輸出,當你在終端運行cat時,標準輸出被連接到該終端,所以你在那里看到了輸出,

標準輸入和輸出通常被縮寫為stdin和stdout,許多命令的操作與cat一樣;如果你不指定輸入檔案,命令就從stdin中讀取,輸出則有些不同,一些程式(如cat)只將輸出發送到stdout,但其他程式可以選擇將輸出直接發送到檔案,

還有第三個標準I/O流,叫做標準錯誤,你會在第2.14.1節看到它,

標準流的最好的特點是,你可以很容易地操縱它們來讀寫終端以外的地方,你將在第2.14節中學習,特別是,你將學習如何將流連接到檔案和其他行程,

2.3 基本命令

現在讓我們來看看更多的Unix命令,這是基本命令的簡化串列,沒涉及到細節,

2.3.1 ls

ls命令列出了目錄的內容,默認情況下是當前目錄,但你可以添加任何目錄或檔案作為引數,而且有許多有用的選項,例如,使用ls -l來獲得詳細的(長)串列,使用ls -F來顯示檔案型別資訊,下面是一個長串列的例子;它包括檔案的所有者(第3列),組(第4列),檔案大小(第5列),以及修改日期/時間(在第5列和檔案名之間):

andrew@andrew-HP:~$ ls -l
total 119228
-rwxrwxrwx  1 andrew andrew      108 11月 10  2022  a-cov.gcda
-rwxrwxrwx  1 andrew andrew      676 11月 10  2022  a-cov.gcno
-rwxrwxrwx  1 andrew andrew    27248 11月 10  2022  a.out
-rw-rw-r--  1 andrew andrew     1949  2月 15 14:31  base.html
drwxrwxr-x  5 andrew andrew     4096  5月 27 07:20 'Calibre 書庫'
drwxrwxrwx 24 andrew andrew     4096  5月 11 15:04  code
...

你將在第2.17節中了解更多關于該輸出的第1列,你可以暫時忽略第2列;它是指向檔案的硬鏈接的數量,在第4.6節中有解釋,

2.3.2 cp

在其最簡單的形式中,cp復制檔案,例如,要將file1復制到file2,請輸入以下內容:

$ cp file1 file2

你也可以把一個檔案復制到另一個目錄,在該目錄中保持相同的檔案名:

$ cp file dir

要復制一個以上的檔案到名為dir的目錄(檔案夾)中,請嘗試像這樣的例子,復制三個檔案:

$ cp file1 file2 file3 dir

2.3.3 mv

mv(移動)命令的作業原理與cp很相似,在其最簡單的形式中,它重命名檔案,例如,要把file1重命名為file2,請輸入以下內容:

$ mv file1 file2

2.3.4 touch

touch命令可以創建檔案,如果目標檔案已經存在,touch不會改變該檔案,但會更新該檔案的修改時間戳,例如,要創建空檔案,可以這樣輸入:

$ touch file

然后在該檔案上運行ls -l,你應該看到像下面這樣的輸出,其中的日期和時間表示你運行觸摸的時間:

$ touch file
$ ls -l file
-rw-rw-r-- 1 andrew andrew 0  5月 27 11:20 file

要看到時間戳的更新,至少要等一分鐘,然后再運行同樣的touch命令,ls -l回傳的時間戳會更新,

2.3.5 rm

rm命令洗掉(移除)檔案,在你洗掉檔案后,它通常會從你的系統中消失,除非你從備份中恢復它,

$ rm file

2.3.6 echo

echo命令將其引數列印到標準輸出:

$ echo Hello again.
Hello again.

echo命令對于查找shell globs("通配符",如*)和變數(如$HOME)的擴展非常有用,你在本章后面會遇到這些情況,

2.4 瀏覽目錄

Unix的目錄層次結構從/開始,也稱為根目錄,目錄的分隔符是斜線(/),而不是反斜線(\),在根目錄下有幾個標準的子目錄,如/usr,你將在第2.19節中學習,

當你參考檔案或目錄時,你指定路徑或路徑名,當路徑以/開頭時(如/usr/lib),它是完整或絕對的路徑,

由兩個點(...)標識的路徑組件指定一個目錄的父級,例如,如果你在/usr/lib中作業,路徑..指的是/usr,同樣地,../bin指的是/usr/bin,

點(.)指的是當前目錄;例如,如果你在/usr/lib,路徑.仍然是/usr/lib,而./X11是/usr/lib/X11,你不會經常使用.,因為如果路徑不是以/開頭,大多數命令都默認為當前目錄(所以你可以在前面的例子中直接使用X11而不是./X11),

不以/開頭的路徑被稱為相對路徑,大多數時候,你會使用相對路徑名,因為你已經在你需要的目錄中或附近,

現在你已經對基本的目錄機制有了了解,下面是一些基本的目錄命令,

cd

當前作業目錄是一個行程(如shell)當前所處的目錄,除了大多數Linux發行版中默認的shell提示外,你還可以用2.5.3節中描述的pwd命令查看你的當前目錄,

每個行程都可以獨立設定自己的當前作業目錄,cd命令可以改變shell的當前作業目錄:

$ cd dir

如果你省略了dir,shell將回傳到你的主目錄,即你第一次登錄時開始的目錄,有些程式會用~符號(tilde)來簡寫你的主目錄,

注意: cd命令是shell的內置命令,它不能作為單獨的程式作業,因為如果它作為子行程運行,它不能(通常)改變其父級的當前作業目錄,

2.4.2 mkdir

mkdir命令創建新的目錄:

$ mkdir dir

2.4.3 rmdir

rmdir命令可以洗掉目錄dir:

$ rmdir dir

如果dir不是空的,這個命令就會失敗,然而,如果你沒有耐心,你可能不想先費力地洗掉dir里面的所有檔案和子目錄,你可以使用rm -r dir來洗掉目錄和它的內容,但要小心!這是少數幾個可以造成嚴重破壞的命令之一,特別是當你以超級用戶身份運行它時,-r選項指定了遞回洗掉,重復洗掉dir中的所有內容,不要將-r標志與星號(*)等globs一起使用,最重要的是,在運行你的命令之前一定要仔細檢查,

2.4.4 Shell的globbing("通配符")

shell可以將簡單的模式與檔案和目錄名相匹配,這個程序被稱為 "通配",這與其他系統中的通配符的概念相似,其中最簡單的是glob字符*,它告訴shell去匹配任何數量的任意字符,例如,下面的命令可以列印出當前目錄下的檔案串列:

$ echo *

shell將包含globs的引數與檔案名相匹配,將檔案名替換為這些引數,然后運行修改后的命令列,這種替換被稱為擴展,因為shell將所有匹配的檔案名替換為一個簡化的運算式,下面是一些使用*來擴展檔案名的方法:

  • at*擴展到所有以at開頭的檔案名,
  • *at擴展到所有以at結尾的檔案名,
  • at擴展到所有包含at的檔案名,

另一個shell glob字符,問號(?),指示shell精確匹配一個任意字符,例如,b?at匹配boat和brat,
如果你不希望shell在命令中擴展一個glob,可以用單引號('')把這個glob括起來,例如,命令echo '*'可以列印出一顆星,你會發現這對下一節中描述的一些命令很方便,例如grep和find,(你將在第11.2節中學習更多關于引號的知識),

注意:重要的是要記住,shell在運行命令前會進行擴展,而且只在這時進行,因此,如果一個 ""沒有被擴展到命令中,shell不會對它做任何事情;而是由命令來決定它要做什么,
shell的模式匹配能力還有很多,但是
和? 是你現在需要知道的,第2.7節描述了那些以點開頭的有趣檔案的glob行為,

2.5 中級命令

這一節描述了最基本的Unix中級命令,

2.5.1 grep

grep命令列印檔案或輸入流中與某個運算式相匹配的行,例如,要列印/etc/passwd檔案中包含文本root的行,請輸入以下內容:

$ grep root /etc/passwd

grep命令在同時對多個檔案進行操作時特別方便,因為它除了列印匹配的行外,還列印檔案名,例如,如果你想檢查/etc中包含root這個詞的每個檔案,你可以使用這個命令:

$ grep root /etc/*

兩個最重要的grep選項是-i(用于不區分大小寫的匹配)和-v(反轉搜索,即列印所有不匹配的行),還有一個更強大的變體,叫做egrep(它只是grep -E的一個同義詞),
grep能夠理解正則運算式,這些模式以計算機科學理論為基礎,在Unix工具中非常常見,正則運算式比通配符式的模式更強大,而且它們有不同的語法,關于正則運算式,有三件重要的事情需要記住:

  • .* 匹配任何數量的字符,包括沒有字符(像globs和通配符中的*),
  • .+ 匹配任何一個或多個字符,
  • .精確匹配一個任意字符,

注意: grep(1) 手冊頁包含了對正則運算式的詳細描述,但它可能有些難以閱讀,要了解更多資訊,你可以閱讀Jeffrey E. F. Friedl撰寫的《Mastering Regular Expressions》第三版(O'Reilly,2006年),或者參見Tom Christensen等人撰寫的《Programming Perl》第四版(O'Reilly,2012年)的正則運算式章節,如果你喜歡數學,并且對正則運算式的來源感興趣,可以看看Jeffrey Ullman和John Hopcroft的《AutomataTheory, Languages, and Computation》第三版(Prentice Hall,2006),

2.5.2 less

當檔案非常大,或者命令的輸出很長,并且滾動到螢屏上方時,less命令就會派上用場,
要翻閱像/usr/share/dict/words這樣的大檔案,你可以使用命令less /usr/share/dict/words,當運行 less 時,你會看到檔案的內容,每次都是一屏,按空格鍵可以往前看檔案,按b(小寫)可以往后跳一個螢屏,要退出,按q,

注意:less命令是一個名為more的舊程式的增強版,Linux臺式機和服務器有less,但它在許多嵌入式系統和其他Unix系統中不是標準配置,如果你遇到了不能使用less的情況,可以試試more,
你也可以在less里面搜索文本,例如,要向前搜索一個單詞,你可以輸入/word,要向后搜索,你可以使用?word,當你找到一個匹配詞時,按n繼續搜索,

正如你在第2.14節中所了解的,你可以將幾乎所有程式的標準輸出直接發送到另一個程式的標準輸入,當你有命令有大量的輸出需要篩選,而你又想用 less 這樣的東西來查看輸出時,這就特別有用,下面是將grep命令的輸出發送到less的例子:

$ grep ie /usr/share/dict/words | less

2.5.3 pwd

pwd(列印作業目錄)程式只是輸出當前作業目錄的名稱,你可能想知道為什么你需要這個,因為大多數Linux發行版都在提示符中設定了用戶賬戶的當前作業目錄,有兩個原因,
首先,不是所有的提示符都包括當前作業目錄,特別是你可能想在自己的提示符中去掉它,因為它占用了很多空間,
第二,你將在第2.17.2節中了解到的符號鏈接有時會掩蓋當前作業目錄的真正完整路徑,使用pwd -P來消除這種混淆,

2.5.4 diff

要查看兩個文本檔案之間的差異,可以使用diff:

$ diff file1 file2

有幾個選項可以控制輸出的格式,默認的輸出格式往往是人類最容易理解的,然而,大多數程式員在需要將輸出結果發送給別人時,更喜歡diff -u的輸出,因為自動化工具更容易處理這種格式,

2.5.5 file

如果你看到一個檔案,但不確定它的格式,可以嘗試使用file命令,看看系統是否能猜到它:

$ file file

你可能會對這個看起來很單純的命令的作用感到驚訝,

2.5.6 查找和定位

當你知道某個檔案在某個目錄樹下,但你不知道在哪里時,這是很令人沮喪的,運行find來查找dir中的檔案,方法如下:

$ find dir -name file -print

像本節中的大多數程式一樣,find能做一些花哨的事情,然而,在你熟知這里顯示的形式并理解為什么你需要-name和-print選項之前,不要嘗試諸如-exec之類的選項,find命令接受特殊的模式匹配字符,如,但你必須用單引號('')將它們括起來,以保護這些特殊字符不被shell自己的globbing功能所影響,(回顧一下第2.4.4節,shell在運行命令之前會展開globs),
大多數系統也有查找檔案的locate命令,locate不是實時搜索檔案,而是搜索系統定期建立的索引,用locate搜索要比find快得多,但是如果你要找的檔案比索引要新,locate就找不到它,

2.5.7 head和tail

head和tail命令允許你快速查看檔案或資料流的一部分,例如,head /etc/passwd顯示密碼檔案的前10行,tail /etc/passwd顯示最后10行,
要改變顯示的行數,使用-n選項,其中n是你想看的行數(例如,head -5 /etc/passwd),要列印從第n行開始的行,使用tail +n,

2.5.8 sort

sort命令可以快速將文本檔案的行數按字母數字順序排列,如果檔案的行以數字開頭,并且你想按數字順序排序,使用-n選項,r選項可以反轉排序的順序,

2.6 改變你的密碼和shell

使用passwd命令來改變你的密碼,你會被要求提供你的舊密碼,然后兩次提示你的新密碼,
最好的密碼往往是容易記住的長 "廢話 "句子,密碼越長(就字符長度而言)越好;嘗試16個字符或更多,(在以前,你可以使用的字符數是有限的,所以建議你增加一些奇怪的字符之類的,)
你可以用chsh命令來改變你的shell(比如zsh、ksh或tcsh),但請記住,本書假設你運行的是bash,所以如果你做了改變,一些例子可能就不能用了,

Dot檔案(隱藏檔案)

如果你還沒有進入你的主目錄,就換成ls來看看,然后運行ls -a,你看到輸出的不同了嗎?當你運行ls而不使用-a時,你不會看到被稱為點檔案的組態檔,這些檔案和目錄的名稱都是以點(.)開頭的,常見的點檔案有.bashrc和.login,還有一些點目錄,如.ssh,
點狀檔案或目錄沒有什么特別之處,一些程式默認不顯示它們,這樣你在列出你的主目錄的內容時就不會看到一個完整的混亂,例如,除非你使用-a選項,否則ls不會列出點檔案,此外,除非你明確使用模式,如.*,否則shell globs不匹配點狀檔案,

注意:你可能會遇到globs的問題,因為.匹配.和.(當前和父目錄),你可能希望使用諸如.[^.]或.??*的模式來獲取除當前和父目錄之外的所有點狀檔案,

2.8 環境和外殼變數

shell可以存盤臨時變數,稱為shell變數,包含文本字串的值,shell變數對于跟蹤腳本中的數值非常有用,而且一些shell變數可以控制shell的行為方式,(例如,bash shell在顯示提示符之前會讀取PS1變數),
要給shell變數賦值,可以使用等號(=),下面是一個簡單的例子:

$ STUFF=blah

前面的例子將名為STUFF的變數的值設定為blah,要訪問這個變數,使用$STUFF(例如,嘗試運行echo $STUFF),你將在第11章中了解到shell變數的許多用途,
注意:在分配變數時,不要在=的周圍加上任何空格,
環境變數就像shell變數一樣,但它并不是專門針對shell的,Unix系統中的所有行程都有環境變數存盤,環境變數和shell變數的主要區別是,作業系統會將shell的所有環境變數傳遞給shell運行的程式,而shell變數不能在你運行的命令中被訪問,
你用shell的匯出命令指定一個環境變數,例如,如果你想把$STUFF這個shell變數變成一個環境變數,可以用下面的方法:

$ STUFF=blah
$ export STUFF

由于子行程繼承了父行程的環境變數,許多程式會讀取它們的配置和選項,例如,你可以把你最喜歡的less命令列選項放在LESS環境變數中,當你運行less時就會使用這些選項,(許多手冊中都有一個名為 "環境 "的章節來描述這些變數),

2.9 命令路徑

PATH是一個特殊的環境變數,它包含了命令路徑(簡稱path),這是系統目錄串列,shell在試圖找到一個命令時,會搜索這個目錄,例如,當你運行ls時,shell會在PATH中列出的目錄中搜索ls程式,如果同名的程式出現在路徑中的幾個目錄中,shell會運行第一個匹配的程式,
如果你運行echo $PATH,你會看到路徑的組成部分是由冒號(:)分隔的,比如說

$ echo $PATH
/usr/local/bin:/usr/bin:/bin

要告訴shell在更多的地方尋找程式,可以改變PATH環境變數,例如,通過使用這個命令,你可以在路徑的開頭添加目錄dir,這樣shell就會在尋找其他PATH目錄之前尋找dir:

$ PATH=dir:$PATH

或者你可以在PATH變數的末尾加上目錄名,使Shell最后查找dir:

$ PATH=$PATH:dir

注意:如果你在修改路徑時錯誤地輸入了$PATH,你可能會意外地抹去整個路徑,如果發生這種情況,不要驚慌! 這種損害不是永久性的;你可以啟動一個新的shell,(為了達到持久的效果,你需要在編輯某個組態檔時輸入錯誤,即使這樣也不難糾正),恢復正常的最簡單方法是關閉當前的終端視窗并啟動另一個,

特殊字符

當與他人討論Linux時,你應該知道一些你會遇到的特殊字符的名稱,如果你對這種事情感到有趣,請看 "Jargon File"(http://www.catb.org/jargon/html/)或其印刷品,《The New Hacker’s Dictionary》,第三版,作者Eric S. Raymond(MIT Press,1996),

注意: 你經常會看到控制字符用圓點標記;例如,^C代表CTRL-C,

2.11 命令列編輯

當你使用shell的時候,注意到你可以使用左右方向鍵來編輯命令列,也可以使用上下箭頭來翻閱以前的命令,這在大多數Linux系統中是標準的,

  • CTRL-B 將游標向左移動
  • CTRL-F 將游標向右移動
  • CTRL-P 查看上一條命令(或將游標上移),
  • CTRL-N 查看下一個命令(或將游標向下移動)
  • CTRL-A 將游標移至行首
  • CTRL-E 將游標移至行尾
  • CTRL-W 擦除前面的單詞
  • CTRL-U 從游標到行首的擦除
  • CTRL-K 從游標處擦除到行尾處
  • CTRL-Y 粘貼被擦除的文字(例如,從CTRL-U),

2.12 文本編輯器

兩個事實上的標準Unix文本編輯器,即vi和Emacs,大多數Unix向導對他們選擇的編輯器很虔誠,但不要聽他們的,只要自己選擇就好,如果你選擇一個與你的作業方式相匹配的,你會發現它更容易學習,基本上,選擇歸結于此:
如果你想要一個幾乎可以做任何事情的編輯器,并且有廣泛的在線幫助,而且你不介意做一些額外的輸入來獲得這些功能,那就試試Emacs,
如果速度就是一切,那就試試vi;它 "玩 "起來有點像電子游戲,
學習vi和Vim編輯器: 阿諾德-羅賓斯、埃爾伯特-漢納和琳達-拉姆所寫的《Unix Text Processing》第七版(O'Reilly,2008),可以告訴你關于vi的一切,對于Emacs,使用在線教程:啟動Emacs,按CTRL-H,然后輸入T,或者閱讀《GNU Emacs Manual》第18版,作者是理查德-M-斯塔爾曼(自由軟體基金會,2018),

還有一些更友好的編輯器,比如nano、Pico等,

注意:編輯文本是你第一次開始看到終端和GUI之間的區別的地方,像vi這樣的編輯器在終端視窗內運行,使用標準的終端I/O介面,GUI編輯器啟動他們自己的視窗并展示他們自己的界面,獨立于終端,Emacs默認在GUI中運行,但也會在終端視窗中運行,

2.13 獲得在線幫助

Linux系統有大量的檔案,對于基本的命令,手冊頁(或稱man頁)會告訴你你需要知道的東西,例如,要查看ls命令的手冊頁,請按以下方式運行man:

$ man ls

大多數手冊頁主要集中在參考資訊上,也許有一些例子和交叉參考,但僅此而已,不要指望有什么教程,也不要指望有什么吸引人的文學風格,
當程式有許多選項時,手冊頁往往以某種系統的方式(例如,按字母順序)列出選項,但它不會告訴你哪些是重要的選項,如果你有耐心,你通常可以在手冊頁中找到你需要知道的東西,如果你沒有耐心,可以問朋友,或者花錢請人做你的朋友,這樣你就可以問他或她,
要按關鍵詞搜索手冊頁,使用-k選項:

$ man -k keyword

如果你不太清楚你想要的命令的名稱,這很有幫助,例如,如果你正在尋找一條對某物進行排序的命令,可以運行:

$ man -k sort
--snip--
comm (1) - compare two sorted files line by line
qsort (3) - sorts an array
sort (1) - sort lines of text files
sortm (1) - sort messages
tsort (1) - perform topological sort
--snip--

輸出包括手冊頁面名稱、手冊章節(見下文),以及對手冊頁面所含內容的快速描述,

注意:如果你對前面章節中描述的命令有任何疑問,你可以通過使用man命令找到答案,

手冊頁是通過編號的章節來參考的,當有人提到手冊頁面時,他們通常把章節編號放在名稱旁邊的括號里,比如ping(8),表2-3列出了這些章節和它們的編號,
image

第1、5、7和8節應該是本書的良好補充,第4節可能用處不大,第6節如果再大一點就好了,如果你不是一個程式員,你可能無法使用第3節,但是一旦你在本書中閱讀了更多關于系統呼叫的內容,你可能就能理解第2節中的一些材料,
一些常見的術語有許多匹配的手冊頁面,跨越幾個章節,默認情況下,man會顯示它找到的第一個頁面,你可以按章節選擇手冊頁面,例如,要閱讀/etc/passwd檔案描述(而不是passwd命令),你可以在頁面名稱前插入章節號,如:

$ man 5 passwd

手冊頁涵蓋了基本內容,但還有很多方法可以獲得在線幫助(除了在互聯網上搜索之外),如果你只是在尋找某個命令的某個選項,可以嘗試在命令名稱后面輸入--help或-h(不同的命令有不同的選項),你可能會得到大量的資訊(如ls --help的情況),也可能找到你要找的東西,
前段時間,GNU專案認為它不太喜歡手冊頁,于是轉而使用另一種叫做info(或texinfo)的格式,這種檔案通常比典型的手冊頁更深入,但它可能更復雜,要訪問info手冊,請使用info的命令名:

$ info command

如果你不喜歡info閱讀器,你可以把輸出發送到less(只需添加 | less),
有些軟體包將它們的可用檔案傾倒在/usr/share/doc中,而不考慮在線手冊系統,如man或info,如果你發現自己在搜索檔案,請查看你系統中的這個目錄--當然,也可以在網上搜索,

2.14 Shell的輸入和輸出

現在你已經熟悉了基本的Unix命令、檔案和目錄,你準備學習如何重定向標準輸入和輸出,讓我們從標準輸出開始,
要把命令的輸出發送到檔案而不是終端,請使用>重定向字符:

$ command > file

如果檔案不存在,shell就會創建它,如果檔案存在,shell會先洗掉(clobbers)原始檔案,(有些shell有引數可以防止clobber,例如,你可以輸入set -C來避免bash中的clobbering),
你可以用">>重定向 "的語法將輸出附加到檔案中而不是覆寫它:

$ command >> file

這是方便的方法,當執行相關的命令序列時,可以將輸出收集在一個地方,
要把一個命令的標準輸出發送到另一個命令的標準輸入,可以使用管道字符(|),要看這是如何作業的,請嘗試這兩條命令:

$ head /proc/cpuinfo
$ head /proc/cpuinfo | tr a-z A-Z

你可以通過你想要的管道命令發送輸出,只需在每個額外的命令前添加一個管道,

2.14.1 標準錯誤

偶爾,你可能會重定向標準輸出,但發現程式仍然會向終端列印一些東西,這被稱為標準錯誤(stderr);它是額外的輸出流,用于診斷和除錯,例如,這個命令產生了錯誤:

$ ls /fffffffff > f

完成后,f應該是空的,但你仍然在終端上看到以下作為標準錯誤的錯誤資訊:

ls: cannot access /fffffffff: No such file or directory

如果你愿意,你可以重定向標準錯誤,例如,要把標準輸出發送到f,把標準錯誤發送到e,使用2>語法,像這樣:

$ ls /fffffffff > f 2> e

數字2指定了shell所修改的流ID,流ID 1是標準輸出(默認),而2是標準錯誤,
你也可以用>&符號將標準錯誤發送到與stdout相同的地方,例如,要把標準輸出和標準錯誤都發送到名為f的檔案中,請嘗試這個命令:

$ ls /fffffffff > f 2>&1

2.14.2 標準輸入重定向

要將檔案引導到程式的標準輸入,請使用<運算子:

$ head < /proc/cpuinfo

你偶爾會遇到需要這種重定向的程式,但由于大多數Unix命令都接受檔案名作為引數,這種情況并不常見,例如,前面的命令可以寫成head /proc/cpuinfo,

2.15 理解錯誤資訊

當你在類似Unix的系統(如Linux)上遇到問題時,你必須閱讀錯誤資訊,與其他作業系統的資訊不同,Unix的錯誤通常準確地告訴你出了什么問題,

2.15.1 Unix錯誤資訊的剖析

大多數Unix程式產生和報告相同的基本錯誤資訊,但在任何兩個程式的輸出之間可能有細微的差別,這里有一個例子,你肯定會以某種形式遇到:

$ ls /dsafsda
ls: cannot access /dsafsda: No such file or directory

這條資訊有三個組成部分:

  • 程式名稱,ls,有些程式省略了這一識別資訊,當你撰寫shell腳本時,這可能會讓人感到厭煩,但這其實并不是什么大問題,
  • 檔案名,/dsafsda,這是一個更具體的資訊,這個路徑有一個問題,
  • 錯誤No such file or directory表明檔案名有問題,

把它們放在一起,你會得到這樣的資訊:“ls tried to open /dsafsda but couldn’t because it doesn’t exist.” ,這可能看起來很明顯,但當你運行包括不同名稱的錯誤命令的shell腳本時,這些資訊會變得有點混亂,
在排除錯誤時,總是先解決第一個錯誤,有些程式在報告一系列其他問題之前,會報告它們不能做任何事情,例如,假設你運行一個名為scumd的虛構程式,你看到了這樣的錯誤資訊:

scumd: cannot access /etc/scumd/config: No such file or directory

在這之后是一大串其他錯誤資訊,看起來就像一場完全的災難,不要讓那些其他錯誤分散你的注意力,你可能只是需要創建/etc/scumd/config,

注意:不要把錯誤資訊和警告資訊混淆,警告通常看起來像錯誤,但它們包含警告這個詞,警告通常意味著有什么問題,但程式還是會嘗試繼續運行,為了解決警告資訊中指出的問題,你可能必須找到一個行程并在做其他事情之前殺死它,(你將在第2.16節中學習列出和殺死行程的知識),

2.15.2 常見錯誤

你在Unix程式中遇到的許多錯誤是由檔案和行程出錯引起的,其中有很多錯誤直接來自于內核系統呼叫遇到的情況,因此你可以通過觀察這些錯誤了解內核是如何將問題反饋給行程的,

No such file or directory

這是頭號錯誤,你試圖訪問不存在的檔案,因為Unix的檔案I/O系統對檔案和目錄沒有什么區別,這個錯誤資訊涵蓋了兩種情況,當你試圖讀取不存在的檔案時,當你試圖改變到不存在的目錄時,當你試圖寫到不存在的目錄中的檔案時,你都會得到它,等等,這種錯誤也被稱為ENOENT,是 "Error NO ENTity "的簡稱,

注意:如果你對系統呼叫感興趣,這通常是open()回傳ENOENT的結果,關于它可能遇到的錯誤的更多資訊,請參見open(2)手冊頁,

File exists

在這種情況下,你可能試圖創建已經存在的檔案,當你試圖創建與檔案同名的目錄時,這很常見,

Not a directory, Is a directory

當你試圖把檔案作為目錄,或把目錄作為檔案時,這些資訊就會彈出來,例如:

$ touch a
$ touch a/b
touch: a/b: Not a directory

注意,這個錯誤資訊只適用于a/b的a部分,當你遇到這個問題時,你可能需要稍微挖掘一下,找到被當作目錄的路徑組件,

No space left on device

你沒有磁盤空間了,

Permission denied

當你試圖讀取或寫入不允許訪問的檔案或目錄時(你的權限不足),你會得到這個錯誤,當你試圖執行沒有設定執行位的檔案時,也會顯示這個錯誤(即使你可以讀取該檔案),你將在第2.17節中閱讀更多關于權限的內容,

Operation not permitted

這通常發生在你試圖殺死不屬于你的行程時,

Segmentation fault, Bus error

分段故障本質上意味著撰寫你剛剛運行的程式的人在某個地方搞砸了,該程式試圖訪問它不允許觸及的記憶體的某個部分,而作業系統將其殺死,同樣,總線錯誤意味著程式試圖以一種不應該的方式訪問一些記憶體,當你得到這些錯誤之一時,你可能是給了程式一些它不期望的輸入,在極少數情況下,可能是記憶體硬體出現了故障,

2.16 列出和操縱行程

回顧第一章,行程是正在運行的程式,系統中的每個行程都有一個數字的行程ID(PID),為了快速列出正在運行的行程,只需在命令列上運行ps,你應該得到一個類似這樣的串列:

$ ps
  PID TTY STAT TIME COMMAND
  520 p0  S    0:00 -bash
  545  ?  S    3:59 /usr/X11R6/bin/ctwm -W
  548  ?  S    0:10 xclock -geometry -0-0
 2159 pd  SW   0:00 /usr/bin/vi lib/addresses
31956 p3  R    0:00 ps

這些欄位如下:

  • PID 行程的ID,
  • TTY 行程所運行的終端設備,稍后會有更多關于這個的內容,
  • STAT 行程的狀態--即行程正在做什么,它的記憶體在哪里,例如,S表示睡眠,R表示運行,(參見ps(1)手冊中對所有符號的描述),
  • TIME 行程到目前為止所使用的CPU時間,以分和秒為單位,換句話說,該行程在處理器上運行指令的總時間,請記住,由于行程不是持續運行的,這與行程開始后的時間(或 "壁鐘時間")不同,
  • COMMAND 這個看起來很明顯,是用來運行程式的命令,但是要注意,行程可以改變這個欄位的原始值,此外,shell可以進行glob擴展,這個欄位將反映擴展后的命令,而不是你在提示符下輸入的命令,

注意:PID對于系統上運行的每個行程都是唯一的,然而,在行程終止后,內核最終可以為一個新的行程重新使用這個PID,

2.16.1 ps命令選項

ps命令有很多選項,為了使事情更加混亂,你可以用三種不同的方式指定選項--Unix、BSD和GNU,許多人認為BSD風格是最舒服的(也許是因為它涉及到較少的輸入),所以這就是我們在本書中要使用的風格,下面是一些最有用的選項組合:

  • ps x 顯示所有正在運行的行程,
  • ps ax 顯示系統中的所有行程,而不僅僅是你自己的行程,
  • ps u 包括更詳細的行程資訊,
  • ps w 顯示完整的命令名稱,而不僅僅是適合一行的內容,
    與其他程式一樣,你可以組合選項,如ps aux和ps auxw,
    要檢查特定的行程,可以在ps命令的引數串列中添加其PID,例如,要檢查當前的shell行程,你可以使用ps u $$($$是一個shell變數,評估為當前shell的PID),你會在第8章中找到關于管理命令top和lsof的資訊,這些命令對于定位行程是很有用的,即使你在做系統維護以外的事情時也是如此,

2.16.2 行程終止

要終止行程,你可以用kill命令向它發送信號--從內核向行程發送的資訊,在大多數情況下,你所需要做的就是這樣:

$ kill pid

有許多型別的信號,默認的(上面使用的)是TERM,即終止,你可以通過給kill增個額外的選項來發送不同的信號,例如,要凍結行程而不是終止它,可以使用STOP信號:

$ kill -STOP pid

停止的行程仍然在記憶體中,準備繼續它的作業,使用CONT信號來繼續運行該行程:

$ kill -CONT pid

注意:使用CTRL-C來終止正在當前終端運行的行程,與使用kill來結束行程的INT(中斷)信號是一樣的,

內核在接收到信號時給大多數行程一個機會來清理自己(通過信號處理機制),然而,一些行程可能會選擇非終結性的動作來回應信號,在試圖處理信號的程序中陷入困境,或者干脆忽略它,所以你可能會發現行程在你試圖終止它之后仍然運行,如果發生這種情況,而你又確實需要殺死行程,那么終止它的最粗暴的方法就是使用KILL信號,與其他信號不同,KILL不能被忽略;事實上,作業系統甚至不給行程一個機會,內核會直接終止該行程,并將其從記憶體中強行洗掉,使用這種方法只是作為最后的手段,

你可能會看到其他用戶用kill輸入數字而不是名字--例如,kill -9而不是kill -KILL,這是因為內核使用數字來表示不同的信號;如果你知道你想發送的信號的編號,你可以這樣使用kill,運行kill -l來獲得信號編號與名稱的映射,

2.16.3 作業控制

Shell支持作業控制,這是一種通過使用各種按鍵和命令向程式發送TSTP(類似于STOP)和CONT信號的方法,這允許你在你使用的程式之間暫停和切換,例如,你可以用CTRL-Z發送一個TSTP信號,然后通過輸入fg(移至前臺)或bg(移至后臺;見下一節)再次啟動程式,但是,盡管它很有用,而且許多有經驗的用戶也有這樣的習慣,作業控制并不是必須的,而且對初學者來說可能會感到困惑: 用戶經常按CTRL-Z而不是CTRL-C,忘記了他們正在運行的東西,最終導致許多行程被中止,

注意:要查看你是否不小心暫停了當前終端上的任何行程,可以運行jobs命令,
如果你想運行多個程式,在單獨的終端視窗中運行每個程式,把非互動式行程放在后臺(如下一節所述),并學會使用screen和tmux工具,

2.16.4 背景行程

通常,當你從shell中運行Unix命令時,在程式執行完畢之前,你不會再得到shell提示,然而,你可以將行程從shell中分離出來,用安培號(&)把它放在 "后臺";這樣你就會得到提示符,例如,如果你有需要用 gunzip 解壓的大檔案(你會在第 2.18 節中看到這個),并且你想在它運行時做一些其他的事情,可以運行這樣的命令:

$ gunzip file.gz &

shell應該通過列印新的后臺行程的PID來回應,并且提示應該立即回傳,這樣你就可以繼續作業了,如果該行程需要很長的時間,它甚至可以在你注銷后繼續運行,如果你必須運行進行大量數字計算的程式,這就特別方便了,如果行程在你注銷或關閉終端視窗之前完成,shell通常會通知你,這取決于你的設定,

注意如果你正在遠程訪問一臺機器,并希望在你注銷時繼續運行一個程式,你可能需要使用nohup命令;詳情請見其手冊頁,
bash shell和大多數全屏互動程式都支持CTRL-L來重繪整個螢屏,如果一個程式是從標準輸入中讀取的,CTRL-R通常會重繪當前行,但在錯誤的時間按錯誤的順序會讓你處于比以前更糟糕的情況,例如,在bash提示符下輸入CTRL-R會使你進入反向的isearch模式(按ESC退出),

2.17 檔案模式和權限

每個Unix檔案都有一組權限,決定你是否可以讀取、寫入或運行該檔案,運行ls -l可以顯示這些權限,下面是這樣顯示的例子:

-rw-r-r-1 1 juser somegroup 7041 Mar 26 19:34 endnotes.html

檔案的模式1表示該檔案的權限和一些額外的資訊,該模式有四個部分,如圖2-1所示,

圖2-1: 檔案模式的各個
模式的第一個字符是檔案型別,在這個位置上的破折號(-),如圖所示,表示一個普通的檔案,意味著這個檔案沒有什么特別之處;它只是二進制或文本資料,這是迄今為止最常見的檔案型別,目錄也很常見,在檔案型別槽中用d表示,(第3.1節列出了其余的檔案型別),
檔案模式的其余部分包含權限,分為三組:用戶、組和其他,按順序排列,例如,例子中的rw-字符是用戶權限,后面的r--字符是組的權限,最后的r--字符是其他權限,
每個權限集可以包含四種基本表示:

  • r表示檔案是可讀的,
  • w表示該檔案是可寫的,
  • x表示該檔案是可執行的(你可以把它作為一個程式運行),
  • 表示 "無"(更確切地說,這組中的那個權限沒有被授予),
    用戶權限(第一組)與擁有該檔案的用戶有關,在前面的例子中,那就是juser,第二組,組權限,是針對檔案的組(本例中的somegroup),該組中的任何用戶都可以利用這些權限,(使用groups命令查看你所在的組,更多資訊見7.3.5節),
    系統中的每個人都可以根據第三組權限,即其他權限進行訪問,這些權限有時被稱為世界權限,

注意:每個讀、寫和執行的權限槽有時被稱為一個權限位,因為作業系統中的底層表示是一系列的位,因此,你可能會聽到人們把部分權限稱為 "讀位",
一些可執行檔案在用戶權限串列中有一個s,而不是x,這表明該可執行檔案是setuid,意味著當你執行該程式時,它的運行就好像檔案所有者是用戶而不是你,許多程式利用這個setuid位,以root身份運行,以獲得他們需要的權限來改變系統檔案,比如passwd程式,它需要改變/etc/passwd檔案,

2.17.1 修改權限

要改變一個檔案或目錄的權限,可以使用chmod命令,首先,挑選你想改變的權限集,然后挑選要改變的位,例如,要給檔案增加組(g)和世界(o,代表 "其他")閱讀(r)權限,你可以運行這兩條命令:

$ chmod g+r file
$ chmod o+r file

或者你可以一次完成:

$ chmod go+r file

要洗掉這些權限,使用go-r而不是go+r,

注意:顯然,你不應該讓檔案成為世界可寫檔案,因為這樣做會使你系統中的任何人都可以改變它們,但是,這是否也允許任何連接到互聯網的人改變它們呢?可能不會,除非你的系統有一個網路安全漏洞,在這種情況下,檔案權限反正也幫不了你,

你有時可能會看到有人用數字來改變權限,例如:

$ chmod 644 file

這被稱為絕對改變,因為它一次性設定了所有權限位,要理解這一點,你需要知道如何以八進制形式表示權限位(每個數字代表以8為基數的數字,0到7,并對應權限集),參見chmod(1)手冊頁或info手冊了解更多,
如果你喜歡使用絕對模式,你其實不需要知道如何構建這些模式;只要記住你最常使用的模式即可,表2-4列出了最常見的幾種模式,
表2-4:絕對權限模式

目錄也有權限,如果目錄是可讀的,你可以列出該目錄的內容,但只有當該目錄是可執行的,你才能訪問該目錄中的檔案,在大多數情況下,你都需要這兩種權限;人們在設定目錄的權限時常犯的錯誤是,在使用絕對模式時不小心洗掉了執行權限,
最后,你可以用umask shell命令指定一組默認的權限,它對你創建的任何新檔案應用一組預定義的權限,一般來說,如果你希望每個人都能看到你創建的所有檔案和目錄,就使用umask 022,如果你不希望,就使用umask 077,如果你想使你所希望的權限掩碼適用于新的視窗和以后的會話,你需要把帶有所需模式的umask命令放在你的某個啟動檔案中,如第13章中所討論的,

2.17.2 使用符號鏈接

符號鏈接是指向另一個檔案或目錄的檔案,有效地創建了別名(像Windows中的快捷方式),符號鏈接提供了對模糊的目錄路徑的快速訪問,
在一個長的目錄串列中,符號鏈接看起來像這樣(注意檔案模式中的l是檔案型別):

lrwxrwxrwx 1 ruser users  11 Feb 27 13:52  somedir -> /home/origdir

如果你試圖訪問這個目錄中的somedir,系統會給你/home/origdir代替,符號鏈接只是指向其他名字的檔案名,它們的名字和它們所指向的路徑不需要有任何意義,在前面的例子中,/home/origdir不需要存在,
事實上,如果/home/origdir不存在,任何訪問somedir的程式都會報告somedir不存在(除了ls somedir,這個命令愚蠢地告訴你somedir就是somedir),這可能是令人困惑的,因為你可以看到名為somedir的東西就在你眼前,
這并不是符號鏈接可能令人困惑的唯一方式,另一個問題是,你不能僅僅通過查看鏈接的名稱來確定鏈接目標的特征;你必須跟蹤鏈接,看它是否指向一個檔案或目錄,你的系統也可能有指向其他鏈接的鏈接,這被稱為鏈式符號鏈接,當你試圖追蹤它們時,可能是個麻煩,
要創建一個從target到linkname的符號鏈接,使用ln -s,如下所示:

$ ln -s target linkname

linkname引數是符號鏈接的名稱,target引數是鏈接指向的檔案或目錄的路徑,而-s標志則指定了符號鏈接(見后面的警告),
當制作符號鏈接時,在運行命令前要檢查兩次,因為有幾種情況可能出錯,例如,如果你不小心顛倒了引數的順序(ln -s linkname target),如果linkname是已經存在的目錄,你就會遇到一些麻煩,如果是這種情況(經常如此),ln會在linkname內創建一個名為target的鏈接,而且這個鏈接會指向自己,除非linkname是完整的路徑,如果你在創建一個目錄的符號鏈接時出了問題,請檢查該目錄是否有錯誤的符號鏈接并洗掉它們,

當你不知道它們的存在時,符號鏈接也會引起頭疼,例如,你可以很容易地編輯你認為是檔案的副本,但實際上是原檔案的一個符號鏈接,

警告:創建符號鏈接時不要忘記-s選項,沒有它,ln會創建硬鏈接,給檔案增加真實的檔案名,新的檔案名具有舊檔案名的狀態;它直接指向(鏈接)檔案資料,而不是像符號鏈接那樣指向另一個檔案名,硬鏈接可能比符號鏈接更令人困惑,除非你了解第4.6節的內容,否則要避免使用它們,

有了所有這些關于符號鏈接的警告,你可能想知道為什么有人會想使用它們,事實證明,它們的缺陷大大超過了它們為組織檔案所提供的力量,以及它們輕松修補小問題的能力,一個常見的使用情況是,當一個程式期望找到一個特定的檔案或目錄,而這個檔案或目錄已經存在于你系統的其他地方,你不想做一個拷貝,如果你不能改變程式,你可以直接從它那里創建一個符號鏈接到實際的檔案或目錄位置,

2.18 歸檔和壓縮檔案

現在你已經了解了檔案、權限和可能的錯誤,你需要掌握gzip和tar,這兩個常用的工具用于壓縮和捆綁檔案和目錄,

2.18.1 gzip

gzip(GNU Zip)這個程式是目前標準的 Unix 壓縮程式之一,以.gz結尾的檔案是GNU Zip壓縮檔案,使用 gunzip file.gz 來解壓縮 .gz 并移除后綴;要再次壓縮該檔案,使用 gzip file,

2.18.2 tar

與其他作業系統的 ZIP 程式不同,gzip 不創建檔案的檔案;也就是說,它不把多個檔案和目錄打包成檔案,要創建歸檔檔案,用tar代替:

$ tar cvf archive.tar file1 file2 ...

用tar創建的歸檔檔案通常有.tar后綴(這是慣例,不是必須的),例如,在前面的命令中,file1、file2等是你希望歸檔在.tar中的檔案和目錄的名稱, c標志激活了創建模式,v和f標志有更具體的作用,
v 標志激活了粗略的診斷輸出,使 tar 在遇到檔案和目錄時列印它們的名字,添加另一個v會使tar列印細節,如檔案大小和權限,如果你不想讓tar告訴你它在做什么,省略v標志,
f標志表示檔案選項,命令列中f標志后的下一個引數必須是供tar創建的歸檔檔案(在前面的例子中,它是.tar),你必須在任何時候都使用這個選項,后面跟一個檔案名,除非是磁帶機,要使用標準輸入或輸出,將檔案名設為破折號(-),

要用tar解壓.tar檔案,使用x標志:

$ tar xvf archive.tar

在這個命令中,x標志使tar進入提取(解包)模式,你可以通過在命令列末尾輸入各個部分的名稱來提取檔案的各個部分,但你必須知道它們的確切名稱,(要確定這一點,請看接下來描述的內容表模式),

注意:當使用提取模式時,記住tar在提取內容后不會洗掉存檔的.tar檔案,

在解壓之前,用內容表模式檢查 .tar 檔案的內容通常是個好主意,使用 t 標志而不是 x 標志,這種模式會驗證歸檔檔案的基本完整性,并列印出里面所有檔案的名稱,如果你不在解壓前測驗歸檔檔案,你可能最侄訓把一大堆亂七八糟的檔案倒入當前目錄,這可能真的很難清理,
當你用t模式檢查歸檔檔案時,要確認所有的檔案都在合理的目錄結構中;也就是說,歸檔檔案中的所有檔案路徑名都應該以同一個目錄開始,如果你不確定,可以創建一個臨時目錄,換到這個目錄,然后再解壓,(如果歸檔檔案沒有造成混亂,你總是可以使用mv * ...),
當解壓時,考慮使用p選項來保留權限,在解壓縮模式下使用這個選項,可以覆寫你的umask,得到存檔中指定的確切權限,當你以超級用戶身份作業時,p選項是默認的,如果你在以超級用戶身份解壓歸檔檔案時遇到權限和所有權方面的問題,請確保你一直等到命令終止并得到shell提示,盡管你可能只想解壓縮檔案的一小部分,但tar必須運行整個檔案,你不能打斷這個程序,因為它只有在檢查了整個壓縮檔案后才設定權限,
把本節中所有的tar選項和模式都記在腦子里,如果你有困難,做一些閃存卡,這可能聽起來像小學生,但避免這個命令的粗心錯誤是非常重要的,

2.18.3 壓縮檔案(.tar.gz)

許多初學者發現檔案通常是壓縮的,檔案名以.tar.gz結尾,這讓他們感到困惑,要解開壓縮檔案,要從右邊到左邊;先擺脫.gz,然后再擔心.tar, 例如,這兩個命令解壓和解開.tar.gz:

$ gunzip file.tar.gz
$ tar xvf file.tar

剛開始的時候,一次做一個步驟就可以了,先運行gunzip來解壓,然后運行tar來驗證和解包,要創建一個壓縮檔案,做相反的事情:先運行tar,然后再運行gzip,經常這樣做,你很快就會記住歸檔和壓縮程序是如何進行的,但是,即使你不經常這樣做,你也可以看到所有的輸入會變得多么令人厭煩,你會開始尋找捷徑,現在讓我們來看看這些,

2.18.4 zcat

剛才的方法并不是在壓縮檔案中呼叫tar的最快或最有效的方法,它浪費了磁盤空間和內核I/O時間,更好的方法是將歸檔和壓縮功能與一個流水線結合起來,例如,這個命令流水線解壓.tar.gz:

$ zcat file.tar.gz | tar xvf -

zcat命令與gunzip -dc相同,-d選項解壓,-c選項將結果發送到標準輸出(在本例中,發送到tar命令),
因為使用zcat非常普遍,Linux中的tar版本有一個快捷方式,你可以用z作為選項,在歸檔檔案上自動呼叫gzip;這對提取歸檔檔案(用tar的x或t模式)和創建歸檔檔案(用c)都有效,例如,用下面的方法來驗證壓縮的存檔:

$ tar ztvf file.tar.gz
$ tar zxvf file.tar.gz # 解壓

然而,試著記住,在使用這個快捷方式時,你實際上是在執行兩個步驟,

注意:.tgz檔案和.tar.gz檔案是一樣的,這個后綴是為了適應FAT(基于MS-DOS)檔案系統,

2.18.5 其他壓縮工具

還有兩個壓縮程式是xz和bzip2,其壓縮檔案分別以.xz和.bz2結尾,雖然比gzip稍慢,但這些程式通常會將文本檔案壓縮得更多一些,要使用的解壓程式是unxz和bunzip2,這兩個程式的選項與它們的gzip對應程式足夠接近,你不需要學習任何新東西,
大多數Linux發行版都帶有與Windows系統上的ZIP檔案兼容的zip和unzip程式,它們適用于通常的.zip檔案,以及以.exe結尾的自解壓檔案,但是,如果你遇到一個以.Z結尾的檔案,你就發現了一個由壓縮程式創建的遺跡,它曾經是Unix的標準,gunzip程式可以解壓這些檔案,但gzip不會創建它們,

2.19 Linux目錄層次結構要點

現在你知道了如何檢查檔案、改變目錄和閱讀手冊頁,你準備開始探索你的系統檔案和目錄,Linux目錄結構的細節在檔案系統層次標準或FHS(https://refspecs.linuxfoundation.org/fhs.shtml)中作了概述,但現在簡要介紹一下就足夠了,
圖2-2提供了層次結構的簡化概覽,顯示了/、/usr和/var下的一些目錄,請注意,/usr下的目錄結構包含一些與/相同的目錄名稱,

圖2-2:Linux目錄層次結構
下面是根目錄中最重要的子目錄:

  • /bin 包含隨時可以運行的程式(也稱為可執行程式),包括大多數基本的Unix命令,如ls和cp,/bin中的大多數程式都是二進制格式,由C語言編譯器創建,但有些是現代系統中的shell腳本,
  • /dev 包含設備檔案,你將在第3章中進一步了解這些檔案,
  • /etc 這個核心系統配置目錄(發音為EHT-see)包含用戶密碼、啟動、設備、網路和其他設定檔案,
  • /home 存放普通用戶的家庭(個人)目錄,大多數Unix安裝都符合這個標準,
  • /lib 是library的縮寫,這個目錄存放包含可執行檔案可以使用的代碼的庫檔案,有兩種型別的庫:靜態和共享,/lib目錄應該只包含共享庫,但其他lib目錄,如/usr/lib,包含這兩種型別以及其他輔助檔案,(我們將在第15章詳細討論共享庫),
  • /proc 通過一個可瀏覽的目錄和檔案界面提供系統統計資料,Linux上的/proc子目錄結構大部分是獨特的,但許多其他Unix變體也有類似的功能,/proc目錄包含了關于當前運行行程的資訊以及一些內核引數,
  • /run 包含系統特有的運行資料,包括某些行程ID、套接字檔案、狀態記錄,以及在許多情況下,系統日志,這是最近才添加到根目錄中的;在舊系統中,你可以在/var/run中找到它,在較新的系統中,/var/run是指向/run的符號鏈接,
  • /sys 這個目錄與/proc類似,它提供了設備和系統介面,你將在第3章中閱讀更多關于/sys的內容,
  • /sbin 系統可執行程式的地方,/sbin目錄中的程式與系統管理有關,所以普通用戶通常不會在他們的命令路徑中設定/sbin組件,如果不以root身份運行,這里的許多實用程式就無法作業,
  • /tmp 是存放較小的、你不太關心的臨時檔案的區域,任何用戶都可以讀取和寫入/tmp,但該用戶可能沒有權限訪問其他用戶的檔案,許多程式使用這個目錄作為作業區,如果某些東西非常重要,不要把它放在/tmp里,因為大多數發行版在機器啟動時都會清除/tmp,有些甚至會定期洗掉其舊檔案,另外,不要讓/tmp被垃圾填滿,因為它的空間通常與一些重要的東西共享(例如,/的其他部分),
  • /usr 雖然讀作 "用戶",但這個子目錄沒有用戶檔案,相反,它包含大的目錄層次,包括Linux系統的大部分內容,/usr中的許多目錄名稱與根目錄中的目錄名稱相同(如/usr/bin和/usr/lib),而且它們保存著相同型別的檔案,(根目錄不包含完整的系統的原因主要是歷史原因--在過去,這是為了保持根目錄的低空間要求),
  • /var 變數子目錄,程式在這里記錄可能隨時間變化的資訊,系統日志、用戶跟蹤、快取和其他系統程式創建和管理的檔案都在這里,(你會注意到這里有一個/var/tmp目錄,但系統在啟動時并不擦除它),

2.19.1 其他根子目錄

在根目錄下還有一些其他有趣的子目錄:

  • /boot 包含內核啟動加載器檔案,這些檔案只與Linux啟動程式的第一階段有關,所以你不會在這個目錄中找到關于Linux如何啟動其服務的資訊,關于這一點,請看第5章,
  • /media 許多發行版中都有可移動媒體(如閃存驅動器)的基本連接點,
  • /opt 這可能包含額外的第三方軟體,許多系統不使用/opt,

2.19.2 /usr目錄

乍一看,/usr目錄可能看起來比較干凈,但快速瀏覽一下/usr/bin和/usr/lib就會發現這里有很多東西;/usr是大多數用戶空間程式和資料所在的地方,除了/usr/bin、/usr/sbin和/usr/lib之外,/usr還包括以下內容:

  • /include 存放C語言編譯器使用的頭檔案,
  • /local 是管理員可以安裝自己的軟體的地方,它的結構應該與/和/usr的結構相似,
  • /man 包含手冊頁面,
  • /share 包含的檔案應該可以在其他型別的Unix機器上使用而不損失功能,這些通常是程式和庫在必要時讀取的輔助資料檔案,在過去,機器網路會從檔案服務器上共享這個目錄,但今天以這種方式使用的共享目錄已經很少了,因為在當代系統上對這些型別的檔案沒有實際的空間限制,相反,在Linux發行版上,你會發現/man、/info和其他許多子目錄在這里,因為這是容易理解的慣例,

2.19.3 內核位置

在Linux系統中,內核通常是二進制檔案/vmlinuz或者/boot/vmlinuz,引導加載器將這個檔案加載到記憶體中,并在系統啟動時將其啟動,(你會在第5章中找到關于引導裝載器的細節),
一旦 Boot Loader 啟動了內核,主內核檔案就不再被運行中的系統使用,然而,你會發現在正常的系統運行程序中,內核會根據需要加載和卸載許多模塊,它們被稱為可加載的內核模塊,位于/lib/modules下,

2.20 以超級用戶身份運行命令

在進一步研究之前,你應該學習如何以超級用戶身份運行命令,你可能很想啟動root shell,但是這樣做有很多缺點:

  • 沒有改變系統的命令的記錄,
  • 沒有執行改變系統的命令的用戶的記錄,
  • 不能訪問你的正常shell環境,
  • 必須輸入root密碼(如果你有的話),

2.20.1 sudo

大多數發行版使用一個叫做sudo的軟體包,允許管理員在以自己身份登錄時以root身份運行命令,例如,在第7章中,你將學習如何使用vipw來編輯/etc/passwd檔案,你可以這樣做:

$ sudo vipw

當你運行這個命令時,sudo會在local2設施下的syslog服務中記錄這個動作,你還將在第7章中學習更多關于系統日志的知識,

2.20.2 /etc/sudoers

當然,系統不會讓任何用戶作為超級用戶運行命令;你必須在/etc/sudoers檔案中配置特權用戶,sudo軟體包有許多選項(你可能永遠不會用到),這使得/etc/sudoers中的語法有些復雜,例如,這個檔案賦予用戶1和用戶2以root身份運行任何命令的權力,而不需要輸入密碼:

User_Alias ADMINS = user1, user2

ADMINS ALL = NOPASSWD: ALL

root ALL=(ALL) ALL

第一行定義了有兩個用戶的ADMINS用戶別名,第二行授予權限,ALL = NOPASSWD: ALL部分意味著ADMINS別名中的用戶可以使用sudo來作為root執行命令,第二個ALL表示 "任何命令",第一個ALL的意思是 "任何主機",(如果你有不止一臺機器,你可以為每臺機器或每組機器設定不同的訪問權限,但我們不會介紹這個功能),
root ALL=(ALL) ALL僅僅意味著超級用戶也可以使用sudo來運行任何主機上的任何命令,額外的(ALL)意味著超級用戶也可以作為任何其他用戶運行命令,你可以通過在第二行/etc/sudoers中加入(ALL),將這個權限擴展到ADMINS用戶,如圖所示:

ADMINS ALL = (ALL) NOPASSWD: ALL

注意:使用visudo命令來編輯/etc/sudoers,該命令在你保存檔案后檢查檔案的語法錯誤,

2.20.3 sudo日志

盡管我們將在本書后面更詳細地討論日志,但你可以用這個命令在大多數系統上找到sudo日志:

$ journalctl SYSLOG_IDENTIFIER=sudo

在舊系統上,你需要在/var/log中尋找日志檔案,例如/var/log/auth.log,
這就是目前sudo的情況,如果你需要使用它更多的高級功能,請參閱sudoers(5)和sudo(8)手冊,(用戶切換的實際機制將在第7章中介紹),

2.21 展望未來

你現在應該知道如何在命令列上做以下事情:運行程式、重定向輸出、與檔案和目錄互動、查看行程串列、查看手冊頁面,以及通常在Linux系統的用戶空間中進行操作,你還應該能夠以超級用戶的身份運行命令,你可能還不太了解用戶空間組件的內部細節或內核中發生的事情,但隨著檔案和行程的基礎知識的掌握,你已經在路上了,在接下來的幾章中,你將使用剛剛學到的命令列工具來處理內核和用戶空間的系統組件,

釘釘或微信號: pythontesting 微信公眾號:pythontesting

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/553683.html

標籤:Linux

上一篇:linux服務器,nginx日志切割保存

下一篇:返回列表

標籤雲
其他(159902) Python(38178) JavaScript(25460) Java(18141) C(15232) 區塊鏈(8268) C#(7972) AI(7469) 爪哇(7425) MySQL(7214) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5344) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4578) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1977) 功能(1967) Web開發(1951) HtmlCss(1949) C++(1924) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1878) .NETCore(1862) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • Linux作業原理2常用基本命令和目錄層次結構

    本章是對本書中你將遇到的Unix命令和工具的指南。 為什么是Unix命令?這不是一本關于Linux如何作業的書嗎?當然是的,但Linux在本質上是一種Unix風格。在本章中,你會看到Unix這個詞,而不是Linux,因為你可以把你學到的東西直接帶到BSD和其他Unix風味的系統中去。我試圖避免涉及太 ......

    uj5u.com 2023-05-29 10:30:37 more
  • linux服務器,nginx日志切割保存

    我們都知道,默認情況下,nginx的專案log是一直被累計寫入的,隨著時間越久,那么這個檔案就會越大,這個時候如果我們要去做一些查找和排查就會比較困難,因為日志檔案太大,操作起來比較費勁。 因此我們為了規避這個問題,提出日志切割的方案。 那日志切割的原理是怎么樣的,我們來分析一下,我們先統計下連續1 ......

    uj5u.com 2023-05-26 15:30:38 more
  • 深度決議 slab 記憶體池回收記憶體以及銷毀全流程

    在上篇文章 [《深入理解 slab cache 記憶體分配全鏈路實作》](https://mp.weixin.qq.com/s?__biz=Mzg2MzU3Mjc3Ng==&mid=2247488152&idx=1&sn=7c65f8ee28e9cc14a86e9df92b6d2b93&chksm=c ......

    uj5u.com 2023-05-26 15:29:05 more
  • linux服務器,nginx日志切割保存

    我們都知道,默認情況下,nginx的專案log是一直被累計寫入的,隨著時間越久,那么這個檔案就會越大,這個時候如果我們要去做一些查找和排查就會比較困難,因為日志檔案太大,操作起來比較費勁。 因此我們為了規避這個問題,提出日志切割的方案。 那日志切割的原理是怎么樣的,我們來分析一下,我們先統計下連續1 ......

    uj5u.com 2023-05-26 15:26:14 more
  • 深度決議 slab 記憶體池回收記憶體以及銷毀全流程

    在上篇文章 [《深入理解 slab cache 記憶體分配全鏈路實作》](https://mp.weixin.qq.com/s?__biz=Mzg2MzU3Mjc3Ng==&mid=2247488152&idx=1&sn=7c65f8ee28e9cc14a86e9df92b6d2b93&chksm=c ......

    uj5u.com 2023-05-26 15:25:12 more
  • 容器編排器們的自我介紹

    哈嘍大家好,我是咸魚 咸魚在《[一文帶你了解容器技術的前世今生](https://mp.weixin.qq.com/s?__biz=MzkzNzI1MzE2Mw==&mid=2247484578&idx=1&sn=a8ae0d1c470351a8bbcb6891bae0ca23&chksm=c293 ......

    uj5u.com 2023-05-25 11:13:55 more
  • 容器編排器們的自我介紹

    哈嘍大家好,我是咸魚 咸魚在《[一文帶你了解容器技術的前世今生](https://mp.weixin.qq.com/s?__biz=MzkzNzI1MzE2Mw==&mid=2247484578&idx=1&sn=a8ae0d1c470351a8bbcb6891bae0ca23&chksm=c293 ......

    uj5u.com 2023-05-25 10:58:52 more
  • linux yum安裝

    目錄 一、yum安裝 二、yum安裝分類 三、yum命令 四、實驗 一、yum安裝 yum:1.基于rpm升級,彌補rpm只能一個一個安裝依賴檔案 2.yum可以自動安裝依賴檔案。 3.從倉庫中下載包 centos8:使用yum或者dhf(兩種命令格式基本一致,檔案格式.rpm) ubuntu:使用 ......

    uj5u.com 2023-05-24 07:44:05 more
  • linux nfs共享存盤服務

    目錄 一、nfs服務 二、nfs優點 三、組態檔 四、共享檔案配置程序 五、實驗 1.創建共享檔案(兩臺終端共享) 一、nfs服務 概念:網路上共享檔案系統的協議,運行多個服務器之間通過網路共享檔案和目錄 服務端:將指定目錄標記為共享目錄,服務段有訪問權限,共享目錄有全部權限 客戶端:通過nfs協 ......

    uj5u.com 2023-05-24 07:38:08 more
  • linux ssh遠程登錄

    目錄 一、ssh概念 二、組態檔 三、ssh組成結構 四、遠程控制程序 五、遠程復制 六、配置密鑰 七、wraooers防火墻 一、ssh概念 ssh:一種安全通道協議 功能:1.實作字符界面遠程登錄 2.遠程復制 3.ssh協議是對通信對方的資料傳輸進行加密出來,包括用戶口令(安全性) 4.客戶 ......

    uj5u.com 2023-05-24 07:30:21 more