
- Unix/Linux 初學者指南
- Unix/Linux - 首頁
- Unix/Linux - 什麼是Linux?
- Unix/Linux - 入門指南
- Unix/Linux - 檔案管理
- Unix/Linux - 目錄
- Unix/Linux - 檔案許可權
- Unix/Linux - 環境
- Unix/Linux - 基本實用程式
- Unix/Linux - 管道和過濾器
- Unix/Linux - 程序
- Unix/Linux - 通訊
- Unix/Linux - vi 編輯器
- Unix/Linux Shell 程式設計
- Unix/Linux - Shell 指令碼
- Unix/Linux - 什麼是 Shell?
- Unix/Linux - 使用變數
- Unix/Linux - 特殊變數
- Unix/Linux - 使用陣列
- Unix/Linux - 基本運算子
- Unix/Linux - 決策
- Unix/Linux - Shell 迴圈
- Unix/Linux - 迴圈控制
- Unix/Linux - Shell 替換
- Unix/Linux - 引號機制
- Unix/Linux - I/O 重定向
- Unix/Linux - Shell 函式
- Unix/Linux - 手冊頁幫助
- 高階 Unix/Linux
- Unix/Linux - 標準 I/O 流
- Unix/Linux - 檔案連結
- Unix/Linux - 正則表示式
- Unix/Linux - 檔案系統基礎
- Unix/Linux - 使用者管理
- Unix/Linux - 系統性能
- Unix/Linux - 系統日誌
- Unix/Linux - 訊號和陷阱
Unix/Linux 快速指南
Unix - 入門指南
什麼是 Unix?
Unix 作業系統是一組程式,充當計算機和使用者之間的橋樑。
分配系統資源並協調計算機內部所有細節的計算機程式稱為作業系統或核心。
使用者透過一個稱為shell的程式與核心通訊。Shell 是一個命令列直譯器;它翻譯使用者輸入的命令,並將它們轉換為核心能夠理解的語言。
Unix 最初由貝爾實驗室的 AT&T 員工 Ken Thompson、Dennis Ritchie、Douglas McIlroy 和 Joe Ossanna 於 1969 年開發。
市場上有各種 Unix 變體。Solaris Unix、AIX、HP Unix 和 BSD 是一些例子。Linux 也是一種免費提供的 Unix 變體。
多個人可以同時使用一臺 Unix 計算機;因此,Unix 被稱為多使用者系統。
使用者還可以同時執行多個程式;因此,Unix 是一個多工環境。
Unix 架構
以下是 Unix 系統的基本框圖:

統一所有 Unix 版本的主要概念是以下四個基礎:
核心 - 核心是作業系統的核心。它與硬體互動,並執行大多數任務,例如記憶體管理、任務排程和檔案管理。
Shell - Shell 是處理您請求的實用程式。當您在終端輸入命令時,Shell 會解釋該命令並呼叫您想要的程式。Shell 對所有命令使用標準語法。C Shell、Bourne Shell 和 Korn Shell 是最著名的 Shell,大多數 Unix 變體都提供這些 Shell。
命令和實用程式 - 您可以使用各種命令和實用程式來完成日常活動。cp、mv、cat 和 grep 等是命令和實用程式的一些示例。除了 250 多個標準命令之外,第三方軟體還提供了許多其他命令。所有命令都附帶各種選項。
檔案和目錄 - Unix 的所有資料都組織成檔案。所有檔案都組織成目錄。這些目錄進一步組織成一個稱為檔案系統的樹狀結構。
系統啟動
如果您有一臺安裝了 Unix 作業系統的計算機,則只需開啟系統即可使其執行。
開啟系統後,它就開始啟動,最後提示您登入系統,這是一種登入系統並將其用於日常活動的活動。
登入 Unix
首次連線到 Unix 系統時,通常會看到如下所示的提示:
login:
登入
準備好您的使用者 ID(使用者標識)和密碼。如果您還沒有這些資訊,請聯絡您的系統管理員。
在登入提示符處鍵入您的使用者 ID,然後按ENTER。您的使用者 ID區分大小寫,因此請確保您完全按照系統管理員的指示鍵入。
在密碼提示符處鍵入您的密碼,然後按ENTER。您的密碼也區分大小寫。
如果您提供了正確的使用者 ID 和密碼,則允許您進入系統。閱讀螢幕上顯示的資訊和訊息,如下所示。
login : amrood amrood's password: Last login: Sun Jun 14 09:32:32 2009 from 62.61.164.73 $
系統將為您提供命令提示符(有時稱為$提示符),您可以在其中鍵入所有命令。例如,要檢視日曆,您需要鍵入cal命令,如下所示:
$ cal June 2009 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 $
更改密碼
所有 Unix 系統都需要密碼,以幫助確保您的檔案和資料仍然屬於您,並且系統本身免受駭客和破解者的攻擊。以下是更改密碼的步驟:
步驟 1 - 首先,在命令提示符處鍵入 password,如下所示。
步驟 2 - 輸入您的舊密碼,即您當前使用的密碼。
步驟 3 - 輸入您的新密碼。始終使您的密碼足夠複雜,以防止任何人猜測。但請確保您記住它。
步驟 4 - 您必須透過再次鍵入密碼來驗證它。
$ passwd Changing password for amrood (current) Unix password:****** New UNIX password:******* Retype new UNIX password:******* passwd: all authentication tokens updated successfully $
注意 - 我們在這裡添加了星號 (*) 只是為了顯示您需要輸入當前和新密碼的位置,否則在您的系統上,它不會顯示您鍵入的任何字元。
列出目錄和檔案
Unix 中的所有資料都組織成檔案。所有檔案都組織成目錄。這些目錄組織成一個稱為檔案系統的樹狀結構。
您可以使用ls命令列出目錄中所有可用的檔案或目錄。以下是使用ls命令和-l選項的示例。
$ ls -l total 19621 drwxrwxr-x 2 amrood amrood 4096 Dec 25 09:59 uml -rw-rw-r-- 1 amrood amrood 5341 Dec 25 08:38 uml.jpg drwxr-xr-x 2 amrood amrood 4096 Feb 15 2006 univ drwxr-xr-x 2 root root 4096 Dec 9 2007 urlspedia -rw-r--r-- 1 root root 276480 Dec 9 2007 urlspedia.tar drwxr-xr-x 8 root root 4096 Nov 25 2007 usr -rwxr-xr-x 1 root root 3192 Nov 25 2007 webthumb.php -rw-rw-r-- 1 amrood amrood 20480 Nov 25 2007 webthumb.tar -rw-rw-r-- 1 amrood amrood 5654 Aug 9 2007 yourfile.mid -rw-rw-r-- 1 amrood amrood 166255 Aug 9 2007 yourfile.swf $
此處以d.....開頭的條目表示目錄。例如,uml、univ 和 urlspedia 是目錄,其餘條目是檔案。
您是誰?
在您登入系統時,您可能想知道:我 是 誰?
查詢“您是誰”的最簡單方法是輸入whoami命令:
$ whoami amrood $
在您的系統上試一試。此命令列出與當前登入關聯的帳戶名。您也可以嘗試who am i命令來獲取有關您自己的資訊。
誰已登入?
有時您可能想知道同時誰登入到計算機。
有三個命令可用於獲取此資訊,具體取決於您希望瞭解其他使用者的資訊量:users、who 和 w。
$ users amrood bablu qadir $ who amrood ttyp0 Oct 8 14:10 (limbo) bablu ttyp2 Oct 4 09:08 (calliope) qadir ttyp4 Oct 8 12:09 (dent) $
在您的系統上嘗試w命令以檢查輸出。這將列出與登入到系統中的使用者關聯的資訊。
登出
完成會話後,您需要登出系統。這樣做是為了確保沒有人訪問您的檔案。
登出
只需在命令提示符處鍵入logout命令,系統就會清理所有內容並斷開連線。
系統關機
透過命令列正確關閉 Unix 系統最一致的方法是使用以下命令之一:
序號 | 命令和說明 |
---|---|
1 |
halt 立即關閉系統 |
2 |
init 0 使用預定義指令碼關閉系統,以在關閉之前同步和清理系統 |
3 |
init 6 透過完全關閉系統然後重新啟動系統來重新啟動系統 |
4 |
poweroff 透過關閉電源關閉系統 |
5 |
reboot 重新啟動系統 |
6 |
shutdown 關閉系統 |
您通常需要是超級使用者或 root(Unix 系統上許可權最高的帳戶)才能關閉系統。但是,在某些獨立或個人擁有的 Unix 計算機上,管理員使用者有時甚至普通使用者也可以這樣做。
Unix - 檔案管理
在本章中,我們將詳細討論 Unix 中的檔案管理。Unix 中的所有資料都組織成檔案。所有檔案都組織成目錄。這些目錄組織成一個稱為檔案系統的樹狀結構。
在使用 Unix 時,您或多或少會花費大部分時間處理檔案。本教程將幫助您瞭解如何建立和刪除檔案、複製和重新命名檔案、建立指向它們的連結等。
在 Unix 中,有三種基本型別的檔案:
普通檔案 - 普通檔案是系統上的檔案,其中包含資料、文字或程式指令。在本教程中,您將瞭解如何處理普通檔案。
目錄 - 目錄儲存特殊檔案和普通檔案。對於熟悉 Windows 或 Mac OS 的使用者,Unix 目錄等效於資料夾。
特殊檔案 - 一些特殊檔案提供對硬體的訪問,例如硬碟驅動器、CD-ROM 驅動器、調變解調器和乙太網介面卡。其他特殊檔案類似於別名或快捷方式,使您可以使用不同的名稱訪問單個檔案。
列出檔案
要列出當前目錄中儲存的檔案和目錄,請使用以下命令:
$ls
以下是上述命令的示例輸出:
$ls bin hosts lib res.03 ch07 hw1 pub test_results ch07.bak hw2 res.01 users docs hw3 res.02 work
ls命令支援-l選項,這將幫助您獲取有關已列出檔案的更多資訊:
$ls -l total 1962188 drwxrwxr-x 2 amrood amrood 4096 Dec 25 09:59 uml -rw-rw-r-- 1 amrood amrood 5341 Dec 25 08:38 uml.jpg drwxr-xr-x 2 amrood amrood 4096 Feb 15 2006 univ drwxr-xr-x 2 root root 4096 Dec 9 2007 urlspedia -rw-r--r-- 1 root root 276480 Dec 9 2007 urlspedia.tar drwxr-xr-x 8 root root 4096 Nov 25 2007 usr drwxr-xr-x 2 200 300 4096 Nov 25 2007 webthumb-1.01 -rwxr-xr-x 1 root root 3192 Nov 25 2007 webthumb.php -rw-rw-r-- 1 amrood amrood 20480 Nov 25 2007 webthumb.tar -rw-rw-r-- 1 amrood amrood 5654 Aug 9 2007 yourfile.mid -rw-rw-r-- 1 amrood amrood 166255 Aug 9 2007 yourfile.swf drwxr-xr-x 11 amrood amrood 4096 May 29 2007 zlib-1.2.3 $
以下是所有已列出列的資訊:
第一列 − 表示檔案型別和檔案賦予的許可權。以下是所有檔案型別的描述。
第二列 − 表示檔案或目錄佔用的記憶體塊數量。
第三列 − 表示檔案的擁有者。這是建立此檔案的 Unix 使用者。
第四列 − 表示擁有者的組。每個 Unix 使用者都將有一個關聯的組。
第五列 − 表示檔案大小(以位元組為單位)。
第六列 − 表示此檔案建立或最後修改的日期和時間。
第七列 − 表示檔案或目錄名稱。
在 ls -l 列表示例中,每行檔案都以 d、- 或 l 開頭。這些字元指示所列檔案型別。
序號 | 字首 & 描述 |
---|---|
1 |
- 普通檔案,例如 ASCII 文字檔案、二進位制可執行檔案或硬連結。 |
2 |
b 塊特殊檔案。塊輸入/輸出裝置檔案,例如物理硬碟。 |
3 |
c 字元特殊檔案。原始輸入/輸出裝置檔案,例如物理硬碟。 |
4 |
d 目錄檔案,包含其他檔案和目錄的列表。 |
5 |
l 符號連結檔案。任何普通檔案的連結。 |
6 |
p 命名管道。程序間通訊的機制。 |
7 |
s 用於程序間通訊的套接字。 |
元字元
元字元在 Unix 中具有特殊含義。例如,* 和 ? 是元字元。我們使用 * 匹配 0 個或多個字元,問號 (?) 匹配單個字元。
例如 −
$ls ch*.doc
顯示所有以 ch 開頭並以 .doc 結尾的檔名 −
ch01-1.doc ch010.doc ch02.doc ch03-2.doc ch04-1.doc ch040.doc ch05.doc ch06-2.doc ch01-2.doc ch02-1.doc c
這裡,* 用作元字元,匹配任何字元。如果要顯示所有以 .doc 結尾的檔案,則可以使用以下命令 −
$ls *.doc
隱藏檔案
隱藏檔案是指第一個字元為點或句點字元 (.) 的檔案。Unix 程式(包括 shell)使用大多數這些檔案來儲存配置資訊。
一些常見的隱藏檔案示例包括以下檔案 −
.profile − Bourne shell (sh) 初始化指令碼
.kshrc − Korn shell (ksh) 初始化指令碼
.cshrc − C shell (csh) 初始化指令碼
.rhosts − 遠端 shell 配置檔案
要列出隱藏檔案,請為 ls 指定 -a 選項 −
$ ls -a . .profile docs lib test_results .. .rhosts hosts pub users .emacs bin hw1 res.01 work .exrc ch07 hw2 res.02 .kshrc ch07.bak hw3 res.03 $
單點 (.) − 表示當前目錄。
雙點 (..) − 表示父目錄。
建立檔案
您可以使用 vi 編輯器在任何 Unix 系統上建立普通檔案。您只需執行以下命令 −
$ vi filename
上述命令將開啟一個具有給定檔名的檔案。現在,按 i 鍵進入編輯模式。進入編輯模式後,您可以在檔案中開始編寫內容,如下面的程式所示 −
This is unix file....I created it for the first time..... I'm going to save this content in this file.
完成程式後,請執行以下步驟 −
按 esc 鍵退出編輯模式。
同時按下 Shift + ZZ 兩個鍵以完全退出檔案。
您現在將在當前目錄中建立一個名為 filename 的檔案。
$ vi filename $
編輯檔案
您可以使用 vi 編輯器編輯現有檔案。我們將簡要討論如何開啟現有檔案 −
$ vi filename
檔案開啟後,您可以透過按 i 鍵進入編輯模式,然後繼續編輯檔案。如果要在此檔案中四處移動,則首先需要透過按 Esc 鍵退出編輯模式。之後,您可以使用以下鍵在檔案中移動 −
l 鍵向右移動。
h 鍵向左移動。
k 鍵向上移動檔案。
j 鍵向下移動檔案。
因此,使用上述鍵,您可以將游標定位在要編輯的任何位置。定位後,您可以使用 i 鍵進入編輯模式。完成檔案編輯後,按 Esc,最後同時按下 Shift + ZZ 兩個鍵以完全退出檔案。
顯示檔案內容
您可以使用 cat 命令檢視檔案的內容。以下是一個簡單的示例,用於檢視上面建立的檔案的內容 −
$ cat filename This is unix file....I created it for the first time..... I'm going to save this content in this file. $
您可以透過使用 -b 選項以及 cat 命令來顯示行號,如下所示 −
$ cat -b filename 1 This is unix file....I created it for the first time..... 2 I'm going to save this content in this file. $
計算檔案中的單詞
您可以使用 wc 命令獲取檔案中包含的行、單詞和字元的總數。以下是一個簡單的示例,用於檢視上面建立的檔案的資訊 −
$ wc filename 2 19 103 filename $
以下是所有四列的詳細資訊 −
第一列 − 表示檔案中行的總數。
第二列 − 表示檔案中單詞的總數。
第三列 − 表示檔案中位元組的總數。這是檔案的實際大小。
第四列 − 表示檔名。
您可以提供多個檔案,並一次獲取有關這些檔案的資訊。以下是一個簡單的語法 −
$ wc filename1 filename2 filename3
複製檔案
要複製檔案,請使用 cp 命令。該命令的基本語法如下 −
$ cp source_file destination_file
以下是如何建立現有檔案 filename 副本的示例。
$ cp filename copyfile $
您現在將在當前目錄中找到另一個檔案 copyfile。此檔案將與原始檔案 filename 完全相同。
重新命名檔案
要更改檔名,請使用 mv 命令。以下為基本語法 −
$ mv old_file new_file
以下程式將現有檔案 filename 重新命名為 newfile。
$ mv filename newfile $
mv 命令將完全將現有檔案移動到新檔案。在這種情況下,您將在當前目錄中僅找到 newfile。
刪除檔案
要刪除現有檔案,請使用 rm 命令。以下為基本語法 −
$ rm filename
注意 − 檔案可能包含有用的資訊。在使用此 刪除 命令時,始終建議謹慎操作。最好將 -i 選項與 rm 命令一起使用。
以下示例顯示瞭如何完全刪除現有檔案 filename。
$ rm filename $
您可以使用以下命令一次刪除多個檔案 −
$ rm filename1 filename2 filename3 $
標準 Unix 流
在正常情況下,每個 Unix 程式在啟動時都會為其開啟三個流(檔案)−
stdin − 這稱為 標準輸入,關聯的檔案描述符為 0。這也表示為 STDIN。Unix 程式將從 STDIN 讀取預設輸入。
stdout − 這稱為 標準輸出,關聯的檔案描述符為 1。這也表示為 STDOUT。Unix 程式將在 STDOUT 寫入預設輸出
stderr − 這稱為 標準錯誤,關聯的檔案描述符為 2。這也表示為 STDERR。Unix 程式將在 STDERR 寫入所有錯誤訊息。
Unix - 目錄管理
在本章中,我們將詳細討論 Unix 中的目錄管理。
目錄是一個檔案,其唯一工作是儲存檔名和相關資訊。所有檔案,無論是普通檔案、特殊檔案還是目錄檔案,都包含在目錄中。
Unix 使用分層結構來組織檔案和目錄。這種結構通常稱為目錄樹。樹有一個根節點,即斜槓字元 (/),所有其他目錄都包含在其下方。
主目錄
您第一次登入時所在的目錄稱為您的主目錄。
您將在主目錄和您將建立的子目錄中完成大部分工作,以組織您的檔案。
您可以隨時使用以下命令進入您的主目錄 −
$cd ~ $
這裡 ~ 表示主目錄。假設您必須進入任何其他使用者的主目錄,請使用以下命令 −
$cd ~username $
要進入您的上一個目錄,您可以使用以下命令 −
$cd - $
絕對/相對路徑名
目錄以根 (/) 為頂層進行分層排列。檔案在層次結構中的位置由其路徑名描述。
路徑名的元素由 / 分隔。如果路徑名相對於根進行描述,則該路徑名為絕對路徑名,因此絕對路徑名始終以 / 開頭。
以下是一些絕對檔名的示例。
/etc/passwd /users/sjones/chem/notes /dev/rdsk/Os3
路徑名也可以相對於您當前的工作目錄。相對路徑名永遠不會以 / 開頭。相對於使用者 amrood 的主目錄,一些路徑名可能如下所示 −
chem/notes personal/res
要隨時確定您在檔案系統層次結構中的位置,請輸入 pwd 命令以列印當前工作目錄 −
$pwd /user0/home/amrood $
列出目錄
要列出目錄中的檔案,您可以使用以下語法 −
$ls dirname
以下是如何列出 /usr/local 目錄中所有檔案的示例 −
$ls /usr/local X11 bin gimp jikes sbin ace doc include lib share atalk etc info man ami
建立目錄
我們現在將瞭解如何建立目錄。目錄由以下命令建立 −
$mkdir dirname
這裡,directory 是要建立的目錄的絕對或相對路徑名。例如,命令 −
$mkdir mydir $
在當前目錄中建立目錄 mydir。以下為另一個示例 −
$mkdir /tmp/test-dir $
此命令在 /tmp 目錄中建立目錄 test-dir。如果 mkdir 成功建立了請求的目錄,則不會產生任何輸出。
如果在命令列上提供多個目錄,則 mkdir 將建立每個目錄。例如,−
$mkdir docs pub $
在當前目錄下建立目錄 docs 和 pub。
建立父目錄
我們現在將瞭解如何建立父目錄。有時,當您要建立目錄時,其父目錄或目錄可能不存在。在這種情況下,mkdir 會發出以下錯誤訊息 −
$mkdir /tmp/amrood/test mkdir: Failed to make directory "/tmp/amrood/test"; No such file or directory $
在這種情況下,您可以為 mkdir 命令指定 -p 選項。它為您建立所有必要的目錄。例如 −
$mkdir -p /tmp/amrood/test $
上述命令建立所有必需的父目錄。
刪除目錄
可以使用以下 rmdir 命令刪除目錄 −
$rmdir dirname $
注意 − 要刪除目錄,請確保它為空,這意味著此目錄中不應有任何檔案或子目錄。
您可以一次刪除多個目錄,如下所示 −
$rmdir dirname1 dirname2 dirname3 $
如果上述目錄為空,則上述命令將刪除目錄 dirname1、dirname2 和 dirname3。如果 rmdir 命令成功,則不會產生任何輸出。
更改目錄
您可以使用 cd 命令執行的操作不僅僅是更改為主目錄。您可以使用它透過指定有效的絕對或相對路徑來更改到任何目錄。語法如下所示 −
$cd dirname $
這裡,dirname 是要更改到的目錄的名稱。例如,命令 −
$cd /usr/local/bin $
對目錄/usr/local/bin的更改。從此目錄,您可以使用以下相對路徑cd到目錄/usr/home/amrood:
$cd ../../home/amrood $
重新命名目錄
mv(移動)命令也可以用於重新命名目錄。語法如下:
$mv olddir newdir $
您可以將目錄mydir重新命名為yourdir,方法如下:
$mv mydir yourdir $
目錄 .(點)和 ..(點點)
檔名 .(點)表示當前工作目錄;檔名 ..(點點)表示當前工作目錄上一級目錄,通常稱為父目錄。
如果我們輸入顯示當前工作目錄/檔案的列表的命令,並使用-a 選項列出所有檔案以及-l 選項提供長列表,我們將收到以下結果。
$ls -la drwxrwxr-x 4 teacher class 2048 Jul 16 17.56 . drwxr-xr-x 60 root 1536 Jul 13 14:18 .. ---------- 1 teacher class 4210 May 1 08:27 .profile -rwxr-xr-x 1 teacher class 1948 May 12 13:42 memo $
Unix - 檔案許可權/訪問模式
在本章中,我們將詳細討論 Unix 中的檔案許可權和訪問模式。檔案所有權是 Unix 中的一個重要組成部分,它提供了一種安全的檔案儲存方法。Unix 中的每個檔案都具有以下屬性:
所有者許可權 - 所有者的許可權決定了檔案的所有者可以對檔案執行哪些操作。
組許可權 - 組的許可權決定了屬於該檔案所屬組的使用者可以對檔案執行哪些操作。
其他(世界)許可權 - 其他使用者的許可權指示所有其他使用者可以對檔案執行哪些操作。
許可權指示符
使用ls -l命令時,它會顯示與檔案許可權相關的各種資訊,如下所示:
$ls -l /home/amrood -rwxr-xr-- 1 amrood users 1024 Nov 2 00:10 myfile drwxr-xr--- 1 amrood users 1024 Nov 2 00:10 mydir
這裡,第一列表示不同的訪問模式,即與檔案或目錄關聯的許可權。
許可權被分成三組,每組中的每個位置都表示特定的許可權,順序為:讀(r)、寫(w)、執行(x) -
前三個字元(2-4)表示檔案所有者的許可權。例如,-rwxr-xr--表示所有者具有讀(r)、寫(w)和執行(x)許可權。
第二組三個字元(5-7)由檔案所屬組的許可權組成。例如,-rwxr-xr--表示該組具有讀(r)和執行(x)許可權,但沒有寫許可權。
最後一組三個字元(8-10)表示其他所有人的許可權。例如,-rwxr-xr--表示只有讀(r)許可權。
檔案訪問模式
檔案的許可權是 Unix 系統安全的第一道防線。Unix 許可權的基本構建塊是讀、寫和執行許可權,這些許可權已在下面進行了描述:
讀取
授予讀取功能,即檢視檔案內容。
寫入
授予修改或刪除檔案內容的功能。
執行
具有執行許可權的使用者可以將檔案作為程式執行。
目錄訪問模式
目錄訪問模式與任何其他檔案一樣列出和組織。需要提到一些差異:
讀取
訪問目錄意味著使用者可以讀取其內容。使用者可以檢視目錄中的檔名。
寫入
訪問意味著使用者可以向目錄新增或刪除檔案。
執行
執行目錄實際上沒有意義,因此可以將其視為遍歷許可權。
使用者必須對bin目錄具有執行許可權才能執行ls或cd命令。
更改許可權
要更改檔案或目錄許可權,可以使用chmod(更改模式)命令。使用 chmod 有兩種方法——符號模式和絕對模式。
在符號模式下使用 chmod
對於初學者來說,修改檔案或目錄許可權最簡單的方法是使用符號模式。使用符號許可權,您可以透過使用下表中的運算子來新增、刪除或指定所需的許可權集。
序號 | Chmod 運算子 & 描述 |
---|---|
1 |
+ 將指定的許可權新增到檔案或目錄。 |
2 |
- 從檔案或目錄中刪除指定的許可權。 |
3 |
= 設定指定的許可權。 |
這是一個使用testfile的示例。對 testfile 執行ls -1顯示檔案的許可權如下:
$ls -l testfile -rwxrwxr-- 1 amrood users 1024 Nov 2 00:10 testfile
然後對 testfile 執行前面表格中的每個示例chmod命令,然後執行ls –l,以便您可以看到許可權更改:
$chmod o+wx testfile $ls -l testfile -rwxrwxrwx 1 amrood users 1024 Nov 2 00:10 testfile $chmod u-x testfile $ls -l testfile -rw-rwxrwx 1 amrood users 1024 Nov 2 00:10 testfile $chmod g = rx testfile $ls -l testfile -rw-r-xrwx 1 amrood users 1024 Nov 2 00:10 testfile
以下是如何在一行中組合這些命令:
$chmod o+wx,u-x,g = rx testfile $ls -l testfile -rw-r-xrwx 1 amrood users 1024 Nov 2 00:10 testfile
使用 chmod 和絕對許可權
使用 chmod 命令修改許可權的第二種方法是使用數字來指定檔案的每個許可權集。
每個許可權都分配了一個值,如下表所示,並且每個許可權集的總和為該集提供了一個數字。
數字 | 八進位制許可權表示 | 參考 |
---|---|---|
0 | 無許可權 | --- |
1 | 執行許可權 | --x |
2 | 寫許可權 | -w- |
3 | 執行和寫許可權:1(執行)+ 2(寫)= 3 | -wx |
4 | 讀許可權 | r-- |
5 | 讀和執行許可權:4(讀)+ 1(執行)= 5 | r-x |
6 | 讀和寫許可權:4(讀)+ 2(寫)= 6 | rw- |
7 | 所有許可權:4(讀)+ 2(寫)+ 1(執行)= 7 | rwx |
這是一個使用 testfile 的示例。對 testfile 執行ls -1顯示檔案的許可權如下:
$ls -l testfile -rwxrwxr-- 1 amrood users 1024 Nov 2 00:10 testfile
然後對 testfile 執行前面表格中的每個示例chmod命令,然後執行ls –l,以便您可以看到許可權更改:
$ chmod 755 testfile $ls -l testfile -rwxr-xr-x 1 amrood users 1024 Nov 2 00:10 testfile $chmod 743 testfile $ls -l testfile -rwxr---wx 1 amrood users 1024 Nov 2 00:10 testfile $chmod 043 testfile $ls -l testfile ----r---wx 1 amrood users 1024 Nov 2 00:10 testfile
更改所有者和組
在 Unix 上建立帳戶時,它會為每個使用者分配一個所有者 ID和一個組 ID。上面提到的所有許可權也基於所有者和組分配。
有兩個命令可用於更改檔案的所有者和組:
chown - chown命令代表“更改所有者”,用於更改檔案的所有者。
chgrp - chgrp命令代表“更改組”,用於更改檔案的組。
更改所有權
chown命令更改檔案的所有權。基本語法如下:
$ chown user filelist
使用者的值可以是系統上的使用者名稱或系統上使用者的使用者 ID(uid)。
以下示例將幫助您理解該概念:
$ chown amrood testfile $
將給定檔案的所有者更改為使用者amrood。
注意 - 超級使用者 root 具有更改任何檔案所有權的無限制功能,但普通使用者只能更改他們擁有的檔案的所有權。
更改組所有權
chgrp命令更改檔案組的所有權。基本語法如下:
$ chgrp group filelist
組的值可以是系統上的組名或系統上組的組 ID(GID)。
以下示例幫助您理解該概念:
$ chgrp special testfile $
將給定檔案的組更改為special組。
SUID 和 SGID 檔案許可權
通常,當執行命令時,必須以特殊許可權執行才能完成其任務。
例如,當您使用passwd命令更改密碼時,新密碼將儲存在檔案/etc/shadow中。
出於安全原因,作為普通使用者,您沒有對該檔案的讀或寫訪問許可權,但是當您更改密碼時,您需要對該檔案具有寫許可權。這意味著passwd程式必須為您提供其他許可權,以便您可以寫入檔案/etc/shadow。
透過稱為設定使用者 ID(SUID)和設定組 ID(SGID)位的機制為程式提供其他許可權。
當您執行啟用了 SUID 位的程式時,您將繼承該程式所有者的許可權。未設定 SUID 位的程式將以啟動該程式的使用者許可權執行。
SGID 也是如此。通常,程式以您的組許可權執行,但改為將您的組僅針對此程式更改為程式的組所有者。
如果許可權可用,則 SUID 和 SGID 位將顯示為字母“s”。SUID“s”位將位於所有者執行許可權通常駐留的許可權位中。
例如,命令:
$ ls -l /usr/bin/passwd -r-sr-xr-x 1 root bin 19031 Feb 7 13:47 /usr/bin/passwd* $
顯示 SUID 位已設定,並且該命令由 root 擁有。執行位置中的大寫字母S而不是小寫字母s表示未設定執行位。
如果在目錄上啟用了粘滯位,則只有在您是以下使用者之一時才能刪除檔案:
- 粘滯目錄的所有者
- 正在刪除的檔案的所有者
- 超級使用者 root
要為任何目錄設定 SUID 和 SGID 位,請嘗試以下命令:
$ chmod ug+s dirname $ ls -l drwsr-sr-x 2 root root 4096 Jun 19 06:45 dirname $
Unix - 環境
在本章中,我們將詳細討論 Unix 環境。一個重要的 Unix 概念是環境,它由環境變數定義。有些由系統設定,有些由您設定,還有些由 shell 或任何載入其他程式的程式設定。
變數是一個字元字串,我們為其分配一個值。分配的值可以是數字、文字、檔名、裝置或任何其他型別的資料。
例如,首先我們設定一個變數 TEST,然後我們使用echo命令訪問其值:
$TEST="Unix Programming" $echo $TEST
它產生以下結果。
Unix Programming
請注意,環境變數是在不使用$符號的情況下設定的,但在訪問它們時,我們使用$符號作為字首。這些變數會保留其值,直到我們退出 shell。
當您登入到系統時,shell 會經歷一個稱為初始化的階段以設定環境。這通常是一個兩步過程,涉及 shell 讀取以下檔案:
- /etc/profile
- profile
過程如下:
shell 檢查檔案/etc/profile是否存在。
如果存在,shell 會讀取它。否則,將跳過此檔案。不會顯示錯誤訊息。
shell 檢查檔案.profile是否在您的主目錄中存在。您的主目錄是您登入後開始所在的目錄。
如果存在,shell 會讀取它;否則,shell 會跳過它。不會顯示錯誤訊息。
這兩個檔案讀取完成後,shell 會顯示一個提示:
$
這是您可以輸入命令以執行它們的提示。
注意 - 此處詳細介紹的 shell 初始化過程適用於所有Bourne型別的 shell,但bash和ksh使用一些其他檔案。
.profile 檔案
檔案/etc/profile由 Unix 機器系統管理員維護,包含系統上所有使用者所需的 shell 初始化資訊。
檔案.profile 由您控制。您可以在此檔案中新增任意數量的 Shell 自定義資訊。您需要配置的最小資訊集包括:
- 您正在使用的終端型別。
- 用於查詢命令的目錄列表。
- 影響終端外觀的一系列變數。
您可以在您的主目錄中檢查您的.profile。使用 vi 編輯器開啟它,並檢查為您的環境設定的所有變數。
設定終端型別
通常,您正在使用的終端型別會由login 或getty 程式自動配置。有時,自動配置過程會錯誤地猜測您的終端。
如果您的終端設定不正確,命令的輸出可能看起來很奇怪,或者您可能無法正確與 Shell 互動。
為了確保不會出現這種情況,大多數使用者會將其終端設定為以下最低公分母:
$TERM=vt100 $
設定 PATH
當您在命令提示符下鍵入任何命令時,Shell 必須在執行命令之前找到該命令。
PATH 變數指定 Shell 應在其中查詢命令的位置。通常,Path 變數設定為如下:
$PATH=/bin:/usr/bin $
這裡,由冒號字元(:) 分隔的每個單獨的條目都是目錄。如果您請求 Shell 執行命令,並且它在 PATH 變數中給出的任何目錄中都找不到它,則會出現類似以下的訊息:
$hello hello: not found $
還有一些變數,如 PS1 和 PS2,將在下一節中討論。
PS1 和 PS2 變數
Shell 顯示為命令提示符的字元儲存在變數 PS1 中。您可以將此變數更改為您想要的任何內容。一旦您更改它,Shell 從那時起就會使用它。
例如,如果您發出以下命令:
$PS1='=>' => => =>
您的提示符將變為=>。要設定PS1 的值,使其顯示工作目錄,請發出以下命令:
=>PS1="[\u@\h \w]\$" [root@ip-72-167-112-17 /var/www/tutorialspoint/unix]$ [root@ip-72-167-112-17 /var/www/tutorialspoint/unix]$
此命令的結果是提示符顯示使用者的使用者名稱、機器的名稱(主機名)和工作目錄。
有相當多的轉義序列可以用作 PS1 的值引數;嘗試將自己限制在最關鍵的那些,以避擴音示符用資訊淹沒您。
序號 | 轉義序列 & 描述 |
---|---|
1 |
\t 當前時間,表示為 HH:MM:SS |
2 |
\d 當前日期,表示為星期幾 月份 日期 |
3 |
\n 換行符 |
4 |
\s 當前 Shell 環境 |
5 |
\W 工作目錄 |
6 |
\w 工作目錄的完整路徑 |
7 |
\u 當前使用者的使用者名稱 |
8 |
\h 當前機器的主機名 |
9 |
\# 當前命令的命令編號。輸入新命令時遞增 |
10 |
\$ 如果有效 UID 為 0(即,如果您以 root 身份登入),則以 # 字元結束提示符;否則,使用 $ 符號 |
您可以在每次登入時自行進行更改,或者也可以透過將其新增到.profile 檔案中來自動進行更改。
當您發出一個不完整的命令時,Shell 將顯示一個輔助提示符,並等待您完成命令並再次按下Enter。
預設輔助提示符為>(大於號),但可以透過重新定義PS2 Shell 變數來更改:
以下是使用預設輔助提示符的示例:
$ echo "this is a > test" this is a test $
以下示例使用自定義提示符重新定義 PS2:
$ PS2="secondary prompt->" $ echo "this is a secondary prompt->test" this is a test $
環境變數
以下是重要環境變數的部分列表。這些變數的設定和訪問方式如下所示:
序號 | 變數 & 描述 |
---|---|
1 |
DISPLAY 包含X11 程式預設應使用的顯示的識別符號。 |
2 |
HOME 指示當前使用者的家目錄:cd內建命令的預設引數。 |
3 |
IFS 指示內部欄位分隔符,解析器在擴充套件後用於單詞分割。 |
4 |
LANG LANG 擴充套件到預設系統區域設定;LC_ALL 可用於覆蓋此設定。例如,如果其值為pt_BR,則語言設定為(巴西)葡萄牙語,區域設定為巴西。 |
5 |
LD_LIBRARY_PATH 具有動態連結器的 Unix 系統,包含一個冒號分隔的目錄列表,動態連結器在 exec 後構建程序映像時應在其中搜索共享物件,然後在搜尋任何其他目錄之前。 |
6 |
PATH 指示命令的搜尋路徑。它是一個冒號分隔的目錄列表,Shell 在其中查詢命令。 |
7 |
PWD 指示由 cd 命令設定的當前工作目錄。 |
8 |
RANDOM 每次引用時都會生成一個介於 0 和 32,767 之間的隨機整數。 |
9 |
SHLVL 每次啟動 bash 例項時遞增 1。此變數對於確定內建 exit 命令是否結束當前會話很有用。 |
10 |
TERM 指的是顯示型別。 |
11 |
TZ 指的是時區。它可以取 GMT、AST 等值。 |
12 |
UID 擴充套件到當前使用者的數字使用者 ID,在 Shell 啟動時初始化。 |
以下是一個示例,顯示了一些環境變數:
$ echo $HOME /root ]$ echo $DISPLAY $ echo $TERM xterm $ echo $PATH /usr/local/bin:/bin:/usr/bin:/home/amrood/bin:/usr/local/bin $
Unix 基本實用程式 - 列印、電子郵件
在本章中,我們將詳細討論列印和電子郵件作為 Unix 的基本實用程式。到目前為止,我們已經嘗試瞭解 Unix 作業系統及其基本命令的性質。在本章中,我們將學習一些重要的 Unix 實用程式,這些實用程式可用於我們的日常生活中。
列印檔案
在 Unix 系統上列印檔案之前,您可能希望對其進行重新格式化以調整邊距、突出顯示某些單詞等。大多數檔案也可以在不重新格式化的情況下列印,但原始列印輸出可能不太吸引人。
許多版本的 Unix 包括兩個功能強大的文字格式化程式,nroff 和troff。
pr 命令
pr 命令對終端螢幕或印表機上的檔案進行少量格式化。例如,如果檔案中有很長的姓名列表,您可以將其在螢幕上格式化為兩列或多列。
以下是pr 命令的語法:
pr option(s) filename(s)
pr 僅更改螢幕或列印副本上的檔案格式;它不會修改原始檔案。下表列出了一些pr 選項:
序號 | 選項 & 描述 |
---|---|
1 |
-k 生成k 列輸出 |
2 |
-d 雙倍行距輸出(並非所有pr 版本都支援) |
3 |
-h "header" 將下一個專案作為報表標題 |
4 |
-t 取消列印標題和頂部/底部邊距 |
5 |
-l PAGE_LENGTH 將頁面長度設定為 PAGE_LENGTH(66)行。預設文字行數為 56 |
6 |
-o MARGIN 使用 MARGIN(零)個空格縮排每一行 |
7 |
-w PAGE_WIDTH 僅針對多文字列輸出,將頁面寬度設定為 PAGE_WIDTH(72)個字元 |
在使用pr 之前,以下是名為 food 的示例檔案的內容。
$cat food Sweet Tooth Bangkok Wok Mandalay Afghani Cuisine Isle of Java Big Apple Deli Sushi and Sashimi Tio Pepe's Peppers ........ $
讓我們使用pr 命令建立一個帶有標題Restaurants 的兩列報表:
$pr -2 -h "Restaurants" food Nov 7 9:58 1997 Restaurants Page 1 Sweet Tooth Isle of Java Bangkok Wok Big Apple Deli Mandalay Sushi and Sashimi Afghani Cuisine Tio Pepe's Peppers ........ $
lp 和 lpr 命令
命令lp 或lpr 將檔案列印到紙上而不是螢幕顯示。一旦您使用pr 命令完成格式化,就可以使用這些命令中的任何一個將檔案列印到連線到計算機的印表機上。
您的系統管理員可能已在您的站點上設定了預設印表機。要將名為food 的檔案列印到預設印表機,請使用lp 或lpr 命令,如下例所示:
$lp food request id is laserp-525 (1 file) $
lp 命令顯示一個 ID,您可以使用它來取消列印作業或檢查其狀態。
如果您使用的是lp 命令,則可以使用 -nNum 選項列印 Num 個副本。與lpr 命令一起,您可以使用 -Num 實現相同的功能。
如果有多個印表機連線到共享網路,則可以使用 -dprinter 選項與 lp 命令一起選擇印表機,為了達到相同目的,您可以使用 -Pprinter 選項與 lpr 命令一起使用。這裡的 printer 是印表機名稱。
lpstat 和 lpq 命令
lpstat 命令顯示印表機佇列中的內容:請求 ID、所有者、檔案大小、傳送列印作業的時間以及請求的狀態。
如果您想檢視所有輸出請求(而不僅僅是您自己的請求),請使用lpstat -o。請求按列印順序顯示:
$lpstat -o laserp-573 john 128865 Nov 7 11:27 on laserp laserp-574 grace 82744 Nov 7 11:28 laserp-575 john 23347 Nov 7 11:35 $
lpq 提供的資訊與lpstat -o 略有不同:
$lpq laserp is ready and printing Rank Owner Job Files Total Size active john 573 report.ps 128865 bytes 1st grace 574 ch03.ps ch04.ps 82744 bytes 2nd john 575 standard input 23347 bytes $
這裡第一行顯示印表機狀態。如果印表機已停用或紙張用盡,您可能會在第一行看到不同的訊息。
cancel 和 lprm 命令
cancel 命令終止lp 命令的列印請求。lprm 命令終止所有lpr 請求。您可以指定請求的 ID(由 lp 或 lpq 顯示)或印表機的名稱。
$cancel laserp-575 request "laserp-575" cancelled $
要取消當前正在列印的任何請求(無論其 ID 如何),只需輸入 cancel 和印表機名稱即可:
$cancel laserp request "laserp-573" cancelled $
如果lprm 命令屬於您,則它將取消活動作業。否則,您可以將作業編號作為引數提供,或使用破折號 (-) 刪除所有作業:
$lprm 575 dfA575diamond dequeued cfA575diamond dequeued $
lprm 命令會告訴您從印表機佇列中刪除的實際檔名。
傳送電子郵件
您可以使用 Unix mail 命令傳送和接收郵件。以下是傳送電子郵件的語法:
$mail [-s subject] [-c cc-addr] [-b bcc-addr] to-addr
以下是與 mail 命令相關的重要的選項 -s
序號 | 選項 & 描述 |
---|---|
1 |
-s 在命令列上指定主題。 |
2 |
-c 向用戶列表傳送抄送。列表應為用逗號分隔的名稱列表。 |
3 |
-b 向列表傳送密件抄送。列表應為用逗號分隔的名稱列表。 |
以下是如何向 admin@yahoo.com 傳送測試訊息的示例。
$mail -s "Test Message" admin@yahoo.com
然後,您需要輸入您的訊息,然後在一行的開頭輸入“control-D”。要停止,只需鍵入點(.),如下所示:
Hi, This is a test . Cc:
您可以使用重定向 < 運算子傳送完整的檔案,如下所示:
$mail -s "Report 05/06/07" admin@yahoo.com < demo.txt
要在您的 Unix 系統上檢查傳入的電子郵件,只需鍵入 email,如下所示:
$mail no email
Unix - 管道和過濾器
在本章中,我們將詳細討論 Unix 中的管道和過濾器。您可以將兩個命令連線在一起,以便一個程式的輸出成為下一個程式的輸入。以這種方式連線的兩個或多個命令構成一個管道。
要建立管道,請在命令列上兩個命令之間放置一個豎線(|)。
當一個程式從另一個程式獲取輸入時,它會對該輸入執行某些操作,並將結果寫入標準輸出。它被稱為過濾器。
grep 命令
grep 命令搜尋檔案或多個檔案中包含特定模式的行。語法為:
$grep pattern file(s)
名稱“grep” 來自 ed(一個 Unix 行編輯器)命令g/re/p,意思是“全域性搜尋正則表示式並列印所有包含它的行”。
正則表示式可以是一些純文字(例如一個單詞)和/或用於模式匹配的特殊字元。
grep 最簡單的用法是查詢由單個單片語成的模式。它可以用於管道中,以便僅將輸入檔案中包含給定字串的行傳送到標準輸出。如果您沒有給 grep 提供要讀取的檔名,它將讀取其標準輸入;所有過濾器程式都是這樣工作的:
$ls -l | grep "Aug" -rw-rw-rw- 1 john doc 11008 Aug 6 14:10 ch02 -rw-rw-rw- 1 john doc 8515 Aug 6 15:30 ch07 -rw-rw-r-- 1 john doc 2488 Aug 15 10:51 intro -rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros $
您可以與grep 命令一起使用各種選項:
序號 | 選項 & 描述 |
---|---|
1 |
-v 列印所有與模式不匹配的行。 |
2 |
-n 列印匹配的行及其行號。 |
3 |
-l 僅列印包含匹配行(字母“l”)的檔名。 |
4 |
-c 僅列印匹配行的數量。 |
5 |
-i 匹配大小寫。 |
現在讓我們使用一個正則表示式,告訴 grep 查詢包含“carol”的行,後跟零個或多個字元(在正則表示式中縮寫為“.*”),然後後跟“Aug”。−
這裡,我們使用-i選項進行不區分大小寫的搜尋−
$ls -l | grep -i "carol.*aug" -rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros $
sort 命令
sort命令按字母或數字順序排列文字行。以下示例對food檔案中的行進行排序−
$sort food Afghani Cuisine Bangkok Wok Big Apple Deli Isle of Java Mandalay Sushi and Sashimi Sweet Tooth Tio Pepe's Peppers $
sort命令預設按字母順序排列文字行。有很多選項可以控制排序−
序號 | 描述 |
---|---|
1 |
-n 按數字排序(例如:10 將在 2 之後排序),忽略空格和製表符。 |
2 |
-r 反轉排序順序。 |
3 |
-f 將大小寫字母一起排序。 |
4 |
+x 在排序時忽略前x個欄位。 |
可以將兩個以上的命令連結到管道中。以之前使用grep的管道示例為例,我們可以進一步按大小順序對8月份修改的檔案進行排序。
以下管道由ls、grep和sort命令組成−
$ls -l | grep "Aug" | sort +4n -rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros -rw-rw-r-- 1 john doc 2488 Aug 15 10:51 intro -rw-rw-rw- 1 john doc 8515 Aug 6 15:30 ch07 -rw-rw-rw- 1 john doc 11008 Aug 6 14:10 ch02 $
此管道按大小順序對目錄中所有在8月份修改的檔案進行排序,並在終端螢幕上列印它們。sort選項+4n跳過四個欄位(欄位由空格分隔),然後按數字順序對行進行排序。
pg 和 more 命令
長的輸出通常可以由您在螢幕上壓縮,但是如果您透過more執行文字或使用pg命令作為過濾器;一旦螢幕上充滿了文字,顯示就會停止。
假設您有一個很長的目錄列表。為了更容易閱讀排序後的列表,請按如下方式將輸出透過管道傳遞到more−
$ls -l | grep "Aug" | sort +4n | more -rw-rw-r-- 1 carol doc 1605 Aug 23 07:35 macros -rw-rw-r-- 1 john doc 2488 Aug 15 10:51 intro -rw-rw-rw- 1 john doc 8515 Aug 6 15:30 ch07 -rw-rw-r-- 1 john doc 14827 Aug 9 12:40 ch03 . . . -rw-rw-rw- 1 john doc 16867 Aug 6 15:56 ch05 --More--(74%)
一旦螢幕上充滿了由檔案大小順序排序的行組成的文字,螢幕就會填滿。螢幕底部是more提示符,您可以在其中鍵入命令以瀏覽排序後的文字。
完成此屏幕後,您可以使用more程式討論中列出的任何命令。
Unix - 程序管理
在本章中,我們將詳細討論Unix中的程序管理。當您在Unix系統上執行程式時,系統會為該程式建立一個特殊的環境。此環境包含系統執行程式所需的一切,就像系統上沒有其他程式正在執行一樣。
每當您在Unix中發出命令時,它都會建立或啟動一個新程序。當您嘗試使用ls命令列出目錄內容時,您啟動了一個程序。簡單來說,程序是正在執行的程式的一個例項。
作業系統透過一個五位數的ID號跟蹤程序,該ID號稱為pid或程序ID。系統中的每個程序都有一個唯一的pid。
Pid 最終會重複,因為所有可能的數字都被用完了,下一個pid會滾動或重新開始。在任何時間點,系統中都不存在兩個具有相同pid的程序,因為它是Unix用於跟蹤每個程序的pid。
啟動程序
當您啟動程序(執行命令)時,您可以透過兩種方式執行它−
- 前臺程序
- 後臺程序
前臺程序
預設情況下,您啟動的每個程序都在前臺執行。它從鍵盤獲取輸入並將輸出傳送到螢幕。
您可以看到ls命令是如何做到的。如果您希望列出當前目錄中的所有檔案,可以使用以下命令−
$ls ch*.doc
這將顯示所有檔名以ch開頭並以.doc結尾的檔案−
ch01-1.doc ch010.doc ch02.doc ch03-2.doc ch04-1.doc ch040.doc ch05.doc ch06-2.doc ch01-2.doc ch02-1.doc
該程序在前臺執行,輸出被定向到我的螢幕,如果ls命令需要任何輸入(它不需要),它會等待鍵盤輸入。
當一個程式在前臺執行並且耗時時,無法執行其他命令(啟動任何其他程序),因為在程式完成處理並退出之前,提示符將不可用。
後臺程序
後臺程序在不連線到鍵盤的情況下執行。如果後臺程序需要任何鍵盤輸入,它會等待。
在後臺執行程序的優點是您可以執行其他命令;您不必等到它完成才能啟動另一個!
啟動後臺程序最簡單的方法是在命令末尾新增一個與號(&)。
$ls ch*.doc &
這將顯示所有檔名以ch開頭並以.doc結尾的檔案−
ch01-1.doc ch010.doc ch02.doc ch03-2.doc ch04-1.doc ch040.doc ch05.doc ch06-2.doc ch01-2.doc ch02-1.doc
這裡,如果ls命令需要任何輸入(它不需要),它會進入停止狀態,直到我們將其移動到前臺並從鍵盤提供資料。
第一行包含有關後臺程序的資訊 - 作業號和程序ID。您需要知道作業號才能在後臺和前臺之間對其進行操作。
按Enter鍵,您將看到以下內容−
[1] + Done ls ch*.doc & $
第一行告訴您ls命令後臺程序已成功完成。第二個是另一個命令的提示符。
列出正在執行的程序
透過執行ps(程序狀態)命令,可以輕鬆檢視您自己的程序,如下所示−
$ps PID TTY TIME CMD 18358 ttyp3 00:00:00 sh 18361 ttyp3 00:01:31 abiword 18789 ttyp3 00:00:00 ps
ps最常用的標誌之一是-f(f表示完整)選項,它提供更多資訊,如以下示例所示−
$ps -f UID PID PPID C STIME TTY TIME CMD amrood 6738 3662 0 10:23:03 pts/6 0:00 first_one amrood 6739 3662 0 10:22:54 pts/6 0:00 second_one amrood 3662 3657 0 08:10:53 pts/6 0:00 -ksh amrood 6892 3662 4 10:51:50 pts/6 0:00 ps -f
以下是ps -f命令顯示的所有欄位的描述−
序號 | 列 & 描述 |
---|---|
1 |
UID 此程序所屬的使用者ID(執行它的人) |
2 |
PID 程序ID |
3 |
PPID 父程序ID(啟動它的程序的ID) |
4 |
C 程序的CPU利用率 |
5 |
STIME 程序啟動時間 |
6 |
TTY 與程序關聯的終端型別 |
7 |
TIME 程序佔用的CPU時間 |
8 |
CMD 啟動此程序的命令 |
還有其他選項可以與ps命令一起使用−
序號 | 選項 & 描述 |
---|---|
1 |
-a 顯示所有使用者的資訊 |
2 |
-x 顯示沒有終端的程序的資訊 |
3 |
-u 顯示其他資訊,如-f選項 |
4 |
-e 顯示擴充套件資訊 |
停止程序
結束程序可以通過幾種不同的方式完成。通常,從基於控制檯的命令中,傳送CTRL + C鍵擊(預設中斷字元)將退出命令。當程序在前景模式下執行時,這適用。
如果程序在後臺執行,則應使用ps命令獲取其作業ID。之後,您可以使用kill命令殺死程序,如下所示−
$ps -f UID PID PPID C STIME TTY TIME CMD amrood 6738 3662 0 10:23:03 pts/6 0:00 first_one amrood 6739 3662 0 10:22:54 pts/6 0:00 second_one amrood 3662 3657 0 08:10:53 pts/6 0:00 -ksh amrood 6892 3662 4 10:51:50 pts/6 0:00 ps -f $kill 6738 Terminated
這裡,kill命令終止first_one程序。如果程序忽略常規kill命令,您可以使用kill -9後跟程序ID,如下所示−
$kill -9 6738 Terminated
父程序和子程序
每個unix程序都有兩個分配給它的ID號:程序ID(pid)和父程序ID(ppid)。系統中的每個使用者程序都有一個父程序。
您執行的大多數命令都以shell作為其父程序。檢查ps -f示例,其中此命令列出了程序ID和父程序ID。
殭屍程序和孤兒程序
通常,當子程序被殺死時,父程序會透過SIGCHLD訊號更新。然後父程序可以執行其他任務或根據需要重新啟動一個新的子程序。但是,有時父程序會在其子程序被殺死之前被殺死。在這種情況下,“所有程序的父程序”,init程序,成為新的PPID(父程序ID)。在某些情況下,這些程序稱為孤兒程序。
當程序被殺死時,ps列表可能仍然顯示該程序處於Z狀態。這是一個殭屍或失效的程序。該程序已死且未使用。這些程序與孤兒程序不同。它們已完成執行,但仍在程序表中找到條目。
守護程序
守護程序是與系統相關的後臺程序,通常以root許可權執行併為其他程序提供服務請求。
守護程序沒有控制終端。它無法開啟/dev/tty。如果您執行"ps -ef"並檢視tty欄位,所有守護程序的tty都將為?。
準確地說,守護程序是在後臺執行的程序,通常等待某些事情發生,它能夠處理這些事情。例如,等待列印命令的印表機守護程序。
如果您有一個需要長時間處理的程式,那麼將其設為守護程序並在後臺執行是值得的。
top 命令
top命令是一個非常有用的工具,可以快速顯示按各種標準排序的程序。
它是一個互動式診斷工具,可以頻繁更新並顯示有關物理和虛擬記憶體、CPU使用率、負載平均值和繁忙程序的資訊。
以下是執行top命令並檢視不同程序的CPU利用率統計資訊的簡單語法−
$top
作業ID與程序ID
後臺和掛起程序通常透過作業號(作業ID)進行操作。此編號與程序ID不同,並且使用的原因是它更短。
此外,一個作業可以由多個程序組成,這些程序可以序列或並行執行。使用作業ID比跟蹤單個程序更容易。
Unix - 網路通訊實用程式
在本章中,我們將詳細討論Unix中的網路通訊實用程式。當您在分散式環境中工作時,您需要與遠端使用者通訊,並且還需要訪問遠端Unix機器。
有幾個Unix實用程式可以幫助使用者在網路化、分散式環境中進行計算。本章列出了一些實用程式。
ping 實用程式
ping命令向網路上可用的主機發送回顯請求。使用此命令,您可以檢查遠端主機是否響應良好。
ping命令對以下方面很有用−
- 跟蹤和隔離硬體和軟體問題。
- 確定網路和各種外部主機的狀態。
- 測試、測量和管理網路。
語法
以下是使用 ftp 命令的簡單語法:
$ping hostname or ip-address
上述命令每秒列印一次響應。要退出命令,您可以按 **Ctrl + C** 鍵終止它。
示例
以下是一個檢查網路上主機可用性的示例:
$ping google.com PING google.com (74.125.67.100) 56(84) bytes of data. 64 bytes from 74.125.67.100: icmp_seq = 1 ttl = 54 time = 39.4 ms 64 bytes from 74.125.67.100: icmp_seq = 2 ttl = 54 time = 39.9 ms 64 bytes from 74.125.67.100: icmp_seq = 3 ttl = 54 time = 39.3 ms 64 bytes from 74.125.67.100: icmp_seq = 4 ttl = 54 time = 39.1 ms 64 bytes from 74.125.67.100: icmp_seq = 5 ttl = 54 time = 38.8 ms --- google.com ping statistics --- 22 packets transmitted, 22 received, 0% packet loss, time 21017ms rtt min/avg/max/mdev = 38.867/39.334/39.900/0.396 ms $
如果主機不存在,您將收到以下輸出:
$ping giiiiiigle.com ping: unknown host giiiiigle.com $
ftp 實用程式
這裡,**ftp** 代表 **F**ile **T**ransfer **P**rotocol。此實用程式可幫助您將檔案從一臺計算機上傳和下載到另一臺計算機。
ftp 實用程式有自己的一套類 Unix 命令。這些命令可幫助您執行以下任務:
連線並登入到遠端主機。
導航目錄。
列出目錄內容。
上傳和下載檔案。
以 **ascii**、**ebcdic** 或 **binary** 格式傳輸檔案。
語法
以下是使用 ftp 命令的簡單語法:
$ftp hostname or ip-address
上述命令將提示您輸入登入 ID 和密碼。身份驗證後,您可以訪問登入帳戶的主目錄,並且可以執行各種命令。
下表列出了一些重要的命令:
序號 | 命令和說明 |
---|---|
1 |
put filename 將本地機器上的 filename 上傳到遠端機器。 |
2 |
get filename 將遠端機器上的 filename 下載到本地機器。 |
3 |
mput file list 將本地機器上的多個檔案上傳到遠端機器。 |
4 |
mget file list 將遠端機器上的多個檔案下載到本地機器。 |
5 |
prompt off 關閉提示。預設情況下,您將收到一個提示,提示您使用 **mput** 或 **mget** 命令上傳或下載檔案。 |
6 |
prompt on 開啟提示。 |
7 |
dir 列出遠端機器當前目錄中所有可用的檔案。 |
8 |
cd dirname 將遠端機器上的目錄更改為 dirname。 |
9 |
lcd dirname 將本地機器上的目錄更改為 dirname。 |
10 |
quit 幫助登出當前登入。 |
需要注意的是,所有檔案都將下載或上傳到或從當前目錄。如果您想將檔案上傳到特定目錄,則需要先更改到該目錄,然後上傳所需檔案。
示例
以下示例顯示了一些命令的工作原理:
$ftp amrood.com Connected to amrood.com. 220 amrood.com FTP server (Ver 4.9 Thu Sep 2 20:35:07 CDT 2009) Name (amrood.com:amrood): amrood 331 Password required for amrood. Password: 230 User amrood logged in. ftp> dir 200 PORT command successful. 150 Opening data connection for /bin/ls. total 1464 drwxr-sr-x 3 amrood group 1024 Mar 11 20:04 Mail drwxr-sr-x 2 amrood group 1536 Mar 3 18:07 Misc drwxr-sr-x 5 amrood group 512 Dec 7 10:59 OldStuff drwxr-sr-x 2 amrood group 1024 Mar 11 15:24 bin drwxr-sr-x 5 amrood group 3072 Mar 13 16:10 mpl -rw-r--r-- 1 amrood group 209671 Mar 15 10:57 myfile.out drwxr-sr-x 3 amrood group 512 Jan 5 13:32 public drwxr-sr-x 3 amrood group 512 Feb 10 10:17 pvm3 226 Transfer complete. ftp> cd mpl 250 CWD command successful. ftp> dir 200 PORT command successful. 150 Opening data connection for /bin/ls. total 7320 -rw-r--r-- 1 amrood group 1630 Aug 8 1994 dboard.f -rw-r----- 1 amrood group 4340 Jul 17 1994 vttest.c -rwxr-xr-x 1 amrood group 525574 Feb 15 11:52 wave_shift -rw-r--r-- 1 amrood group 1648 Aug 5 1994 wide.list -rwxr-xr-x 1 amrood group 4019 Feb 14 16:26 fix.c 226 Transfer complete. ftp> get wave_shift 200 PORT command successful. 150 Opening data connection for wave_shift (525574 bytes). 226 Transfer complete. 528454 bytes received in 1.296 seconds (398.1 Kbytes/s) ftp> quit 221 Goodbye. $
telnet 實用程式
有時我們需要連線到遠端 Unix 機器並在該機器上遠端工作。**Telnet** 是一種實用程式,允許一個站點的一位計算機使用者建立連線,登入,然後在另一個站點的計算機上進行工作。
使用 Telnet 登入後,您可以在遠端連線的機器上執行所有活動。以下是 Telnet 會話的示例:
C:>telnet amrood.com Trying... Connected to amrood.com. Escape character is '^]'. login: amrood amrood's Password: ***************************************************** * * * * * WELCOME TO AMROOD.COM * * * * * ***************************************************** Last unsuccessful login: Fri Mar 3 12:01:09 IST 2009 Last login: Wed Mar 8 18:33:27 IST 2009 on pts/10 { do your work } $ logout Connection closed. C:>
finger 實用程式
**finger** 命令顯示給定主機上使用者的資訊。主機可以是本地或遠端的。
出於安全原因,其他系統上的 Finger 可能已被停用。
以下是使用 finger 命令的簡單語法:
檢查本地機器上所有已登入的使用者:
$ finger Login Name Tty Idle Login Time Office amrood pts/0 Jun 25 08:03 (62.61.164.115)
獲取本地機器上特定使用者資訊:
$ finger amrood Login: amrood Name: (null) Directory: /home/amrood Shell: /bin/bash On since Thu Jun 25 08:03 (MST) on pts/0 from 62.61.164.115 No mail. No Plan.
檢查遠端機器上所有已登入的使用者:
$ finger @avtar.com Login Name Tty Idle Login Time Office amrood pts/0 Jun 25 08:03 (62.61.164.115)
獲取遠端機器上特定使用者資訊:
$ finger amrood@avtar.com Login: amrood Name: (null) Directory: /home/amrood Shell: /bin/bash On since Thu Jun 25 08:03 (MST) on pts/0 from 62.61.164.115 No mail. No Plan.
Unix - vi 編輯器教程
在本章中,我們將瞭解 vi 編輯器在 Unix 中的工作原理。在 Unix 中,有多種方法可以編輯檔案。使用螢幕導向文字編輯器 **vi** 編輯檔案是最佳方法之一。此編輯器使您能夠在檔案中的其他行上下文中編輯行。
vi 編輯器的改進版本,稱為 **VIM**,現已可用。這裡,VIM 代表 **Vi IM**proved。
vi 通常被認為是 Unix 編輯器的實際標準,因為:
它通常可在所有 Unix 系統版本上使用。
它的實現跨平臺非常相似。
它需要的資源很少。
它比其他編輯器(如 **ed** 或 **ex**)更友好。
您可以使用 **vi** 編輯器編輯現有檔案或從頭建立一個新檔案。您還可以使用此編輯器僅讀取文字檔案。
啟動 vi 編輯器
下表列出了使用 vi 編輯器的基本命令:
序號 | 命令和說明 |
---|---|
1 |
vi filename 如果檔案不存在,則建立一個新檔案,否則開啟現有檔案。 |
2 |
vi -R filename 以只讀模式開啟現有檔案。 |
3 |
view filename 以只讀模式開啟現有檔案。 |
以下是如何在當前工作目錄中建立新檔案 **testfile** 的示例(如果該檔案不存在):
$vi testfile
上述命令將生成以下輸出:
| ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ "testfile" [New File]
您會注意到游標後面每一行都有一個 **波浪線** (~)。波浪線表示未使用的行。如果一行不是以波浪線開頭並且看起來是空白的,則表示存在空格、製表符、換行符或其他不可見的字元。
您現在有一個開啟的檔案可以開始工作。在繼續之前,讓我們瞭解一些重要的概念。
操作模式
在使用 vi 編輯器時,我們通常會遇到以下兩種模式:
**命令模式** - 此模式使您能夠執行管理任務,例如儲存檔案、執行命令、移動游標、剪下(複製)和貼上行或單詞,以及查詢和替換。在此模式下,您鍵入的任何內容都將被解釋為命令。
**插入模式** - 此模式使您能夠將文字插入檔案。在此模式下鍵入的所有內容都將被解釋為輸入並放置在檔案中。
vi 始終以 **命令模式** 啟動。要輸入文字,您必須處於插入模式,只需鍵入 **i** 即可。要退出插入模式,請按 **Esc** 鍵,這將帶您返回命令模式。
**提示** - 如果您不確定自己處於哪種模式,請按兩次 Esc 鍵;這將帶您進入命令模式。您可以使用 vi 編輯器開啟檔案。開始鍵入一些字元,然後進入命令模式以瞭解區別。
退出 vi
退出 vi 的命令是 **:q**。在命令模式下,鍵入冒號和“q”,然後按回車鍵。如果您的檔案以任何方式被修改,編輯器將警告您這一點,並且不允許您退出。要忽略此訊息,退出 vi 而不儲存的命令是 **:q!**。這允許您退出 vi 而不儲存任何更改。
儲存編輯器內容的命令是 **:w**。您可以將上述命令與退出命令結合使用,或使用 **:wq** 並按回車鍵。
**儲存更改並退出 vi** 的最簡單方法是使用 ZZ 命令。當您處於命令模式時,鍵入 **ZZ**。**ZZ** 命令的工作方式與 **:wq** 命令相同。
如果要為檔案指定/說明任何特定名稱,則可以在 **:w** 後指定它。例如,如果您想將正在處理的檔案另存為名為 **filename2** 的其他檔名,則鍵入 **:w filename2** 並按回車鍵。
在檔案中移動
要在檔案中移動而不影響您的文字,您必須處於命令模式(按兩次 Esc)。下表列出了一些可用於一次移動一個字元的命令:
序號 | 命令和說明 |
---|---|
1 |
k 將游標向上移動一行 |
2 |
j 將游標向下移動一行 |
3 |
h 將游標向左移動一個字元位置 |
4 |
l l |
將游標向右移動一個字元位置
在檔案中移動時,需要注意以下幾點:
vi 區分大小寫。使用命令時,請注意大小寫。
大多數 vi 命令都可以以您希望操作發生的次數為字首。例如,**2j** 將游標向下移動兩個游標位置。
序號 | 命令和說明 |
---|---|
1 |
以下是用於在檔案中移動的命令列表。 0 或 | |
2 |
$ 將游標定位在行首 |
3 |
$ 將游標定位在行尾 |
4 |
b w |
5 |
( 將游標定位到下一個單詞 |
6 |
) b |
7 |
將游標定位到上一個單詞 1 |
8 |
{ 將游標定位到當前句子的開頭 |
9 |
} ) |
10 |
[[ 將游標定位到下一句的開頭 |
11 |
]] E |
12 |
移動到空白分隔單詞的末尾 [[ |
13 |
向後移動一段 ]] |
14 |
向前移動一段 [{ |
15 |
向後移動一個節 }] |
16 |
向前移動一個節 }] |
17 |
n| 移動到當前行的第 **n** 列 |
18 |
1G 移動到檔案的首行 |
19 |
G 移動到檔案的最後一行 |
20 |
nG 移動到檔案的第 **n** 行 |
21 |
:n fc |
22 |
向前移動到 **c** Fc |
23 |
向後移動到 **c** H |
24 |
移動到螢幕頂部 nH |
移動到螢幕頂部的第 **n** 行
M
序號 | 命令和說明 |
---|---|
1 |
L 移動到螢幕底部 |
2 |
nL 移動到螢幕底部的第 **n** 行 |
3 |
:x 冒號後跟一個數字將把游標定位在 **x** 表示的行號上 |
4 |
控制命令 以下命令可以與 Control 鍵一起使用,以執行下表中給出的功能: |
5 |
以下是控制命令列表。 Ctrl+d |
6 |
向前移動 1/2 螢幕 Ctrl+f |
7 |
:x 將螢幕向上移動半頁 |
8 |
L 將螢幕向下移動半頁 |
9 |
控制命令 將螢幕向上移動一頁 |
10 |
nL 將螢幕向下移動一頁 |
11 |
CTRL+I 重繪螢幕 |
編輯檔案
要編輯檔案,您需要處於插入模式。從命令模式進入插入模式有很多方法:
序號 | 命令和說明 |
---|---|
1 |
i 在當前游標位置之前插入文字 |
2 |
I 在當前行的開頭插入文字 |
3 |
a 在當前游標位置之後插入文字 |
4 |
A 在當前行的末尾插入文字 |
5 |
o 在游標位置下方建立新行以輸入文字 |
6 |
O 在游標位置上方建立新行以輸入文字 |
刪除字元
以下是重要命令列表,可用於刪除開啟檔案中的字元和行:
序號 | 命令和說明 |
---|---|
1 |
x 刪除游標所在位置的字元 |
2 |
X 刪除游標之前位置的字元 |
3 |
dw 從當前游標位置刪除到下一個單詞 |
4 |
d^ 從當前游標位置刪除到行首 |
5 |
d$ 從當前游標位置刪除到行尾 |
6 |
D 從游標位置刪除到當前行尾 |
7 |
dd 刪除游標所在的行 |
如上所述,vi 中的大多數命令都可以加上要執行操作的次數作為字首。例如,**2x** 刪除游標所在位置的兩個字元,**2dd** 刪除游標所在的兩行。
建議在繼續操作之前練習這些命令。
更改命令
您還可以更改 vi 中的字元、單詞或行,而無需刪除它們。以下是相關的命令:
序號 | 命令和說明 |
---|---|
1 |
cc 刪除該行的內容,並使您進入插入模式。 |
2 |
cw 更改游標所在的單詞,從游標到單詞末尾的小寫 **w**。 |
3 |
r 替換游標下的字元。輸入替換內容後,vi 返回到命令模式。 |
4 |
R 從當前游標下的字元開始覆蓋多個字元。您必須使用 **Esc** 停止覆蓋。 |
5 |
s 用您鍵入的字元替換當前字元。之後,您將處於插入模式。 |
6 |
S 刪除游標所在的行,並用新文字替換它。輸入新文字後,vi 保持在插入模式。 |
複製和貼上命令
您可以使用以下命令將行或單詞從一個位置複製到另一個位置:
序號 | 命令和說明 |
---|---|
1 |
yy 複製當前行。 |
2 |
yw 從游標所在的小寫 w 字元複製到單詞末尾的當前單詞。 |
3 |
p p |
4 |
將複製的文字放在游標之後。 P |
將複製的文字放在游標之前。
高階命令
序號 | 命令和說明 |
---|---|
1 |
以下是高階命令列表。 J |
2 |
<< 將當前行與下一行連線。j 命令的計數連線多行。 |
3 |
>> 將當前行向左移動一個縮排寬度。 |
4 |
~ 將當前行向右移動一個縮排寬度。 |
5 |
切換游標下字元的大小寫。 ^G |
6 |
同時按下 Ctrl 和 G 鍵以顯示當前檔名和狀態。 U |
7 |
將當前行恢復到游標進入該行之前的狀態。 u |
8 |
以下是高階命令列表。 這有助於撤消對檔案中所做的最後一次更改。再次鍵入“u”將重做更改。 |
9 |
將當前行與下一行連線。計數連線指定行數。 :f |
10 |
顯示檔案中當前位置的百分比和檔名,以及檔案的總數。 :f filename |
11 |
將當前檔案重新命名為 filename。 :w filename |
12 |
寫入檔案 filename。 :e filename |
13 |
開啟另一個名為 filename 的檔案。 :cd dirname |
14 |
將當前工作目錄更改為 dirname。 :e # |
15 |
向前移動一個節 在兩個開啟的檔案之間切換。 |
16 |
如果您使用 vi 開啟多個檔案,請使用 **:n** 轉到系列中的下一個檔案。 :p |
17 |
如果您使用 vi 開啟多個檔案,請使用 **:p** 轉到系列中的上一個檔案。 :N |
18 |
如果您使用 vi 開啟多個檔案,請使用 **:N** 轉到系列中的上一個檔案。 :r file |
19 |
讀取檔案並將其插入到當前行的後面。 :nr file |
讀取檔案並將其插入到第 n 行的後面。
單詞和字元搜尋
vi 編輯器有兩種搜尋:**字串**和**字元**。對於字串搜尋,使用 **/** 和 **?** 命令。當您開始這些命令時,剛剛鍵入的命令將顯示在螢幕的最後一行,您可以在其中鍵入要查詢的特定字串。
這兩個命令僅在搜尋發生的方向上有所不同:
**/** 命令在檔案中向前(向下)搜尋。
**?** 命令在檔案中向後(向上)搜尋。
序號 | **n** 和 **N** 命令分別重複上一個搜尋命令,方向相同或相反。某些字元具有特殊含義。這些字元必須以反斜槓(**\**)作為字首才能作為搜尋表示式的一部分包含在內。 |
---|---|
1 |
^ 字元和描述 |
2 |
. 在行首搜尋(在搜尋表示式的開頭使用)。 |
3 |
* 匹配單個字元。 |
4 |
$ 匹配前一個字元零次或多次。 |
5 |
[ 行尾(在搜尋表示式的末尾使用)。 |
6 |
< 開始一組匹配或不匹配的表示式。 |
7 |
> 這放在用反斜槓轉義的表示式中,以查詢單詞的結尾或開頭。 |
這有助於檢視上面“**<**”字元的描述。
字元搜尋在同一行內搜尋輸入命令後輸入的字元。**f** 和 **F** 命令僅在當前行中搜索字元。**f** 向前搜尋,**F** 向後搜尋,游標移動到找到的字元的位置。
**t** 和 **T** 命令僅在當前行中搜索字元,但對於 **t**,游標移動到字元之前的位置,**T** 向後搜尋該行到字元之後的位置。
設定命令
序號 | 命令和說明 |
---|---|
1 |
您可以使用以下 **:set** 命令更改 vi 螢幕的外觀。一旦您處於命令模式,鍵入 **:set** 後跟以下任何命令。 :set ic |
2 |
搜尋時忽略大小寫 :set ai |
3 |
設定自動縮排 :set noai |
4 |
取消設定自動縮排 :set nu |
5 |
在左側顯示帶行號的行 :set sw |
6 |
設定軟體製表符的寬度。例如,您可以使用此命令將縮排寬度設定為 4 — **:set sw = 4** :set ws |
7 |
如果設定了 *wrapscan*,並且在檔案底部找不到該單詞,它將嘗試在開頭搜尋該單詞 :set wm |
8 |
如果此選項的值大於零,則編輯器將自動“換行”。例如,要將換行邊距設定為兩個字元,您可以鍵入以下內容:**:set wm = 2** :set ro |
9 |
將檔案型別更改為“只讀” :set term |
10 |
列印終端型別 :set bf |
丟棄輸入中的控制字元
執行命令
vi 能夠在編輯器內部執行命令。要執行命令,您只需進入命令模式並鍵入 **:!** 命令。
例如,如果您想在嘗試使用該檔名儲存檔案之前檢查檔案是否存在,您可以鍵入 **:! ls**,您將在螢幕上看到 **ls** 的輸出。
您可以按任意鍵(或命令的轉義序列)返回到您的 vi 會話。
替換文字
:s/search/replace/g
替換命令(**:s/**)使您能夠快速替換檔案中的單詞或單片語。以下是替換文字的語法:
**g** 代表全域性。此命令的結果是游標所在行上的所有出現都被更改。
需要注意的重要事項
以下幾點將有助於您成功使用 vi:
您必須處於命令模式才能使用命令。(隨時按兩次 Esc 以確保您處於命令模式。)
您必須小心使用命令。這些命令區分大小寫。
您必須處於插入模式才能輸入文字。
Unix - 什麼是 Shell?
**Shell** 為您提供了一個與 Unix 系統互動的介面。它收集您的輸入並根據該輸入執行程式。當程式執行完畢後,它會顯示該程式的輸出。
Shell 是一個我們可以執行命令、程式和 Shell 指令碼的環境。Shell 有不同的種類,就像作業系統有不同的種類一樣。每種 Shell 都有自己的一套可識別的命令和函式。
Shell 提示符
提示符 **$**,稱為 **命令提示符**,由 Shell 發出。當提示符顯示時,您可以鍵入命令。
下面是一個date命令的簡單示例,它顯示當前日期和時間:
$date Thu Jun 25 08:30:19 MST 2009
您可以使用環境變數 PS1 自定義命令提示符,這在環境教程中有所解釋。
Shell 型別
在 Unix 中,主要有兩種型別的 Shell:
Bourne Shell - 如果你使用的是 Bourne 型 Shell,則$字元是預設提示符。
C Shell - 如果你使用的是 C 型 Shell,則 % 字元是預設提示符。
Bourne Shell 有以下子類別:
- Bourne Shell (sh)
- Korn Shell (ksh)
- Bourne Again Shell (bash)
- POSIX Shell (sh)
不同的 C 型 Shell 如下:
- C Shell (csh)
- TENEX/TOPS C Shell (tcsh)
最初的 Unix Shell 由 Stephen R. Bourne 於 20 世紀 70 年代中期編寫,當時他在新澤西州的 AT&T Bell Labs 工作。
Bourne Shell 是第一個出現在 Unix 系統上的 Shell,因此被稱為“Shell”。
Bourne Shell 通常安裝在大多數 Unix 版本的/bin/sh中。因此,它是編寫可在不同 Unix 版本上使用的指令碼的首選 Shell。
在本章中,我們將涵蓋大多數基於 Borne Shell 的 Shell 概念。
Shell 指令碼
Shell 指令碼的基本概念是一系列命令,這些命令按執行順序排列。一個好的 Shell 指令碼將包含註釋(以#符號開頭),描述每個步驟。
它包含條件測試(例如,值 A 大於值 B),迴圈允許我們遍歷大量資料,檔案用於讀取和儲存資料,變數用於讀取和儲存資料,並且指令碼可能包含函式。
我們將在接下來的章節中編寫許多指令碼。它將是一個簡單的文字檔案,我們在其中放置所有命令以及其他一些必要的結構,這些結構告訴 Shell 環境做什麼以及何時做。
Shell 指令碼和函式都是解釋執行的。這意味著它們不會被編譯。
指令碼示例
假設我們建立一個test.sh指令碼。請注意,所有指令碼都將具有.sh副檔名。在向指令碼新增任何其他內容之前,您需要提醒系統正在啟動一個 Shell 指令碼。這是使用shebang結構完成的。例如:
#!/bin/sh
這告訴系統後續的命令將由 Bourne Shell 執行。它被稱為 shebang,因為#符號稱為雜湊,而!符號稱為感嘆號。
要建立包含這些命令的指令碼,請先放置 shebang 行,然後新增命令:
#!/bin/bash pwd ls
Shell 註釋
您可以按如下方式在指令碼中添加註釋:
#!/bin/bash # Author : Zara Ali # Copyright (c) Tutorialspoint.com # Script follows here: pwd ls
儲存以上內容並使指令碼可執行:
$chmod +x test.sh
Shell 指令碼現在已準備好執行:
$./test.sh
執行後,您將收到以下結果:
/home/amrood index.htm unix-basic_utilities.htm unix-directories.htm test.sh unix-communication.htm unix-environment.htm
注意 - 要執行當前目錄中可用的程式,請使用./program_name
擴充套件的 Shell 指令碼
Shell 指令碼有幾個必要的結構,這些結構告訴 Shell 環境做什麼以及何時做。當然,大多數指令碼都比上面的複雜。
畢竟,Shell 是一種真正的程式語言,包含變數、控制結構等等。無論指令碼變得多麼複雜,它仍然只是一系列按順序執行的命令。
以下指令碼使用read命令,該命令從鍵盤獲取輸入並將其分配為變數 PERSON 的值,最後將其列印到標準輸出。
#!/bin/sh # Author : Zara Ali # Copyright (c) Tutorialspoint.com # Script follows here: echo "What is your name?" read PERSON echo "Hello, $PERSON"
以下是指令碼的示例執行:
$./test.sh What is your name? Zara Ali Hello, Zara Ali $
Unix - 使用 Shell 變數
在本章中,我們將學習如何在 Unix 中使用 Shell 變數。變數是一個字元字串,我們為其分配一個值。分配的值可以是數字、文字、檔名、裝置或任何其他型別的資料。
變數只不過是指向實際資料的指標。Shell 使您能夠建立、分配和刪除變數。
變數名稱
變數名只能包含字母(a 到 z 或 A 到 Z)、數字(0 到 9)或下劃線字元(_)。
按照慣例,Unix Shell 變數的名稱將使用大寫字母。
以下示例是有效的變數名:
_ALI TOKEN_A VAR_1 VAR_2
以下是無效變數名的示例:
2_VAR -VARIABLE VAR1-VAR2 VAR_A!
您不能使用!、*或-等其他字元的原因是這些字元對 Shell 具有特殊含義。
定義變數
變數定義如下:
variable_name=variable_value
例如:
NAME="Zara Ali"
以上示例定義了變數 NAME 並將其值設定為“Zara Ali”。此型別的變數稱為標量變數。標量變數一次只能儲存一個值。
Shell 使您能夠在變數中儲存任何所需的值。例如:
VAR1="Zara Ali" VAR2=100
訪問值
要訪問儲存在變數中的值,請在其名稱前加上美元符號 ($):
例如,以下指令碼將訪問已定義變數 NAME 的值並將其列印到標準輸出:
#!/bin/sh NAME="Zara Ali" echo $NAME
以上指令碼將產生以下值:
Zara Ali
只讀變數
Shell 提供了一種使用只讀命令將變數標記為只讀的方法。變數被標記為只讀後,其值將無法更改。
例如,以下指令碼在嘗試更改 NAME 的值時會生成錯誤:
#!/bin/sh NAME="Zara Ali" readonly NAME NAME="Qadiri"
以上指令碼將生成以下結果:
/bin/sh: NAME: This variable is read only.
取消設定變數
取消設定或刪除變數會指示 Shell 從其跟蹤的變數列表中刪除該變數。一旦取消設定變數,您將無法訪問變數中儲存的值。
以下是使用unset命令取消設定已定義變數的語法:
unset variable_name
以上命令取消設定已定義變數的值。這是一個簡單的示例,演示了該命令的工作原理:
#!/bin/sh NAME="Zara Ali" unset NAME echo $NAME
以上示例未列印任何內容。您不能使用 unset 命令來取消設定標記為只讀的變數。
變數型別
當 Shell 執行時,存在三種主要的變數型別:
區域性變數 - 區域性變數是在 Shell 的當前例項中存在的變數。它對 Shell 啟動的程式不可用。它們是在命令提示符處設定的。
環境變數 - 環境變數可用於 Shell 的任何子程序。某些程式需要環境變數才能正常執行。通常,Shell 指令碼僅定義其執行的程式所需的那些環境變數。
Shell 變數 - Shell 變數是一種特殊的變數,由 Shell 設定,並且 Shell 為了正常執行而需要它。其中一些變數是環境變數,而另一些是區域性變數。
Unix - 特殊變數
在本章中,我們將詳細討論 Unix 中的特殊變數。在我們之前的章節之一中,我們瞭解了在使用變數名中的某些非字母數字字元時需要謹慎。這是因為這些字元用於特殊 Unix 變數的名稱。這些變數保留用於特定功能。
例如,$字元表示當前 Shell 的程序 ID 號或 PID:
$echo $$
以上命令寫入當前 Shell 的 PID:
29949
下表顯示了您可以在 Shell 指令碼中使用的一些特殊變數:
序號 | 變數 & 描述 |
---|---|
1 |
$0 當前指令碼的檔名。 |
2 |
$n 這些變數對應於呼叫指令碼的引數。這裡n是一個正十進位制數,對應於引數的位置(第一個引數是 $1,第二個引數是 $2,依此類推)。 |
3 |
$# 提供給指令碼的引數數量。 |
4 |
$* 所有引數都用雙引號括起來。如果指令碼接收兩個引數,則 $* 等效於 $1 $2。 |
5 |
$@ 所有引數都分別用雙引號括起來。如果指令碼接收兩個引數,則 $@ 等效於 $1 $2。 |
6 |
$? 最後執行的命令的退出狀態。 |
7 |
$$ 當前 Shell 的程序號。對於 Shell 指令碼,這是它們正在執行的程序 ID。 |
8 |
$! 最後一個後臺命令的程序號。 |
命令列引數
命令列引數 $1、$2、$3、...$9 是位置引數,其中 $0 指向實際的命令、程式、Shell 指令碼或函式,而 $1、$2、$3、...$9 作為該命令的引數。
以下指令碼使用與命令列相關的各種特殊變數:
#!/bin/sh echo "File Name: $0" echo "First Parameter : $1" echo "Second Parameter : $2" echo "Quoted Values: $@" echo "Quoted Values: $*" echo "Total Number of Parameters : $#"
以下是以上指令碼的示例執行:
$./test.sh Zara Ali File Name : ./test.sh First Parameter : Zara Second Parameter : Ali Quoted Values: Zara Ali Quoted Values: Zara Ali Total Number of Parameters : 2
特殊引數 $* 和 $@
有一些特殊引數允許一次訪問所有命令列引數。$*和$@都將具有相同的作用,除非它們用雙引號""括起來。
這兩個引數都指定命令列引數。但是,"$*" 特殊引數將整個列表作為帶空格的一個引數,而 "$@" 特殊引數將整個列表作為單獨的引數。
我們可以按如下所示編寫 Shell 指令碼,以使用 $* 或 $@ 特殊引數處理未知數量的命令列引數:
#!/bin/sh for TOKEN in $* do echo $TOKEN done
以下是以上指令碼的示例執行:
$./test.sh Zara Ali 10 Years Old Zara Ali 10 Years Old
注意 - 這裡do...done是一種迴圈,將在後續教程中介紹。
退出狀態
$?變量表示前一個命令的退出狀態。
退出狀態是每個命令在完成時返回的一個數值。通常,大多數命令在成功時返回退出狀態 0,在失敗時返回 1。
某些命令出於特定原因會返回額外的退出狀態。例如,某些命令會區分錯誤型別,並根據特定故障型別返回不同的退出值。
以下是成功命令的示例 -
$./test.sh Zara Ali File Name : ./test.sh First Parameter : Zara Second Parameter : Ali Quoted Values: Zara Ali Quoted Values: Zara Ali Total Number of Parameters : 2 $echo $? 0 $
Unix - 使用 Shell 陣列
在本章中,我們將討論如何在 Unix 中使用 Shell 陣列。Shell 變數能夠儲存單個值。這些變數稱為標量變數。
Shell 支援一種稱為陣列變數的不同型別的變數。它可以同時儲存多個值。陣列提供了一種對一組變數進行分組的方法。您可以使用儲存所有其他變數的單個數組變數,而不是為每個所需的變數建立新的名稱。
為 Shell 變數討論的所有命名規則在命名陣列時都適用。
定義陣列值
陣列變數和標量變數之間的區別可以解釋如下。
假設您嘗試將各種學生的姓名錶示為一組變數。每個單獨的變數都是一個標量變數,如下所示 -
NAME01="Zara" NAME02="Qadir" NAME03="Mahnaz" NAME04="Ayan" NAME05="Daisy"
我們可以使用單個數組來儲存上面提到的所有名稱。以下是建立陣列變數的最簡單方法。這有助於為其索引之一賦值。
array_name[index]=value
這裡array_name是陣列的名稱,index是您要設定的陣列中專案的索引,而value是要為該專案設定的值。
例如,以下命令 -
NAME[0]="Zara" NAME[1]="Qadir" NAME[2]="Mahnaz" NAME[3]="Ayan" NAME[4]="Daisy"
如果您使用的是ksh shell,則以下是陣列初始化的語法 -
set -A array_name value1 value2 ... valuen
如果您使用的是bash shell,則以下是陣列初始化的語法 -
array_name=(value1 ... valuen)
訪問陣列值
設定任何陣列變數後,您可以按如下方式訪問它 -
${array_name[index]}
這裡array_name是陣列的名稱,index是要訪問的值的索引。以下是一個示例,用於理解這個概念 -
#!/bin/sh NAME[0]="Zara" NAME[1]="Qadir" NAME[2]="Mahnaz" NAME[3]="Ayan" NAME[4]="Daisy" echo "First Index: ${NAME[0]}" echo "Second Index: ${NAME[1]}"
以上示例將生成以下結果 -
$./test.sh First Index: Zara Second Index: Qadir
您可以透過以下方式之一訪問陣列中的所有專案 -
${array_name[*]} ${array_name[@]}
這裡array_name是您感興趣的陣列的名稱。以下示例將幫助您理解這個概念 -
#!/bin/sh NAME[0]="Zara" NAME[1]="Qadir" NAME[2]="Mahnaz" NAME[3]="Ayan" NAME[4]="Daisy" echo "First Method: ${NAME[*]}" echo "Second Method: ${NAME[@]}"
以上示例將生成以下結果 -
$./test.sh First Method: Zara Qadir Mahnaz Ayan Daisy Second Method: Zara Qadir Mahnaz Ayan Daisy
Unix - Shell 基本運算子
每個 Shell 都支援各種運算子。我們將在本章中詳細討論 Bourne Shell(預設 Shell)。
我們現在將討論以下運算子 -
- 算術運算子
- 關係運算符
- 布林運算子
- 字串運算子
- 檔案測試運算子
Bourne Shell 最初沒有執行簡單算術運算的機制,但它使用外部程式,即awk或expr。
以下示例顯示如何新增兩個數字 -
#!/bin/sh val=`expr 2 + 2` echo "Total value : $val"
以上指令碼將生成以下結果:
Total value : 4
新增時需要考慮以下幾點 -
運算子和表示式之間必須有空格。例如,2+2 不正確;應寫成 2 + 2。
整個表示式應包含在‘ ‘之間,稱為反引號。
算術運算子
Bourne Shell 支援以下算術運算子。
假設變數a儲存 10,變數b儲存 20,則 -
運算子 | 描述 | 示例 |
---|---|---|
+(加法) | 將運算子兩側的值相加 | `expr $a + $b` 將給出 30 |
-(減法) | 從左運算元中減去右運算元 | `expr $a - $b` 將給出 -10 |
*(乘法) | 將運算子兩側的值相乘 | `expr $a \* $b` 將給出 200 |
/(除法) | 將左運算元除以右運算元 | `expr $b / $a` 將給出 2 |
%(模數) | 將左運算元除以右運算元並返回餘數 | `expr $b % $a` 將給出 0 |
=(賦值) | 將右運算元賦值給左運算元 | a = $b 會將 b 的值賦值給 a |
==(相等) | 比較兩個數字,如果兩者相同則返回真。 | [ $a == $b ] 將返回假。 |
!=(不相等) | 比較兩個數字,如果兩者不同則返回真。 | [ $a != $b ] 將返回真。 |
務必理解所有條件表示式都應放在方括號內,並在其周圍留有空格,例如[ $a == $b ]是正確的,而[$a==$b]是不正確的。
所有算術計算均使用長整數完成。
關係運算符
Bourne Shell 支援以下特定於數值的關係運算符。除非其值為數字,否則這些運算子不適用於字串值。
例如,以下運算子將用於檢查 10 和 20 之間的關係,以及“10”和“20”之間,但不適用於“ten”和“twenty”之間。
假設變數a儲存 10,變數b儲存 20,則 -
運算子 | 描述 | 示例 |
---|---|---|
-eq | 檢查兩個運算元的值是否相等;如果是,則條件變為真。 | [ $a -eq $b ] 不是真。 |
-ne | 檢查兩個運算元的值是否相等;如果值不相等,則條件變為真。 | [ $a -ne $b ] 是真。 |
-gt | 檢查左運算元的值是否大於右運算元的值;如果是,則條件變為真。 | [ $a -gt $b ] 不是真。 |
-lt | 檢查左運算元的值是否小於右運算元的值;如果是,則條件變為真。 | [ $a -lt $b ] 是真。 |
-ge | 檢查左運算元的值是否大於或等於右運算元的值;如果是,則條件變為真。 | [ $a -ge $b ] 不是真。 |
-le | 檢查左運算元的值是否小於或等於右運算元的值;如果是,則條件變為真。 | [ $a -le $b ] 是真。 |
務必理解所有條件表示式都應放在方括號內,並在其周圍留有空格。例如,[ $a <= $b ]是正確的,而[$a <= $b]是不正確的。
布林運算子
Bourne Shell 支援以下布林運算子。
假設變數a儲存 10,變數b儲存 20,則 -
運算子 | 描述 | 示例 |
---|---|---|
! | 這是邏輯否定。它將真條件反轉為假,反之亦然。 | [ ! false ] 是真。 |
-o | 這是邏輯OR。如果其中一個運算元為真,則條件變為真。 | [ $a -lt 20 -o $b -gt 100 ] 是真。 |
-a | 這是邏輯AND。如果兩個運算元都為真,則條件變為真,否則為假。 | [ $a -lt 20 -a $b -gt 100 ] 是假。 |
字串運算子
Bourne Shell 支援以下字串運算子。
假設變數a儲存“abc”,變數b儲存“efg”,則 -
運算子 | 描述 | 示例 |
---|---|---|
= | 檢查兩個運算元的值是否相等;如果是,則條件變為真。 | [ $a = $b ] 不是真。 |
!= | 檢查兩個運算元的值是否相等;如果值不相等,則條件變為真。 | [ $a != $b ] 是真。 |
-z | 檢查給定字串運算元的大小是否為零;如果長度為零,則返回真。 | [ -z $a ] 不是真。 |
-n | 檢查給定字串運算元的大小是否不為零;如果長度不為零,則返回真。 | [ -n $a ] 不是假。 |
str | 檢查str是否不是空字串;如果為空,則返回假。 | [ $a ] 不是假。 |
檔案測試運算子
我們有一些運算子可用於測試與 Unix 檔案關聯的各種屬性。
假設變數file儲存一個現有的檔名“test”,其大小為 100 位元組,並且具有以下許可權:read、write和execute -
運算子 | 描述 | 示例 |
---|---|---|
-b file | 檢查檔案是否是塊特殊檔案;如果是,則條件變為真。 | [ -b $file ] 是假。 |
-c file | 檢查檔案是否是字元特殊檔案;如果是,則條件變為真。 | [ -c $file ] 是假。 |
-d file | 檢查檔案是否是目錄;如果是,則條件變為真。 | [ -d $file ] 不是真。 |
-f file | 檢查檔案是否為普通檔案,而不是目錄或特殊檔案;如果是,則條件變為真。 | [ -f $file ] 是真。 |
-g file | 檢查檔案是否設定了其 set group ID (SGID) 位;如果是,則條件變為真。 | [ -g $file ] 是假。 |
-k file | 檢查檔案是否設定了其粘滯位;如果是,則條件變為真。 | [ -k $file ] 是假。 |
-p file | 檢查檔案是否為命名管道;如果是,則條件變為真。 | [ -p $file ] 是假。 |
-t file | 檢查檔案描述符是否已開啟並與終端關聯;如果是,則條件變為真。 | [ -t $file ] 是假。 |
-u file | 檢查檔案是否設定了其 Set User ID (SUID) 位;如果是,則條件變為真。 | [ -u $file ] 是假。 |
-r file | 檢查檔案是否可讀;如果是,則條件變為真。 | [ -r $file ] 是真。 |
-w file | 檢查檔案是否可寫;如果是,則條件變為真。 | [ -w $file ] 是真。 |
-x file | 檢查檔案是否可執行;如果是,則條件變為真。 | [ -x $file ] 是真。 |
-s file | 檢查檔案大小是否大於 0;如果是,則條件變為真。 | [ -s $file ] 是真。 |
-e file | 檢查檔案是否存在;即使檔案是目錄但存在,也為真。 | [ -e $file ] 是真。 |
C Shell 運算子
以下連結將為您提供有關 C Shell 運算子的簡要說明 -
Korn Shell 運算子
以下連結可幫助您瞭解 Korn Shell 運算子 -
Unix - Shell 決策
在本章中,我們將瞭解 Unix 中的 Shell 決策。在編寫 Shell 指令碼時,可能需要在給定的兩條路徑中選擇一條路徑。因此,您需要使用條件語句,使程式能夠做出正確的決策並執行正確的操作。
Unix Shell 支援條件語句,用於根據不同條件執行不同的操作。我們現在將瞭解這裡兩種決策語句 -
if...else語句
case...esac語句
if...else 語句
If else 語句是有用的決策語句,可用於從給定的一組選項中選擇一個選項。
Unix Shell 支援以下形式的if…else語句 -
大多數if語句使用上一章討論的關係運算符來檢查關係。
case...esac語句
您可以使用多個if...elif語句來執行多路分支。但是,這並不總是最佳解決方案,尤其是在所有分支都依賴於單個變數的值時。
Unix Shell支援case...esac語句,該語句恰好處理這種情況,並且它比重複使用if...elif語句效率更高。
這裡只有一種case...esac語句形式,此處已對其進行了詳細描述 -
Unix shell中的case...esac語句與我們在其他程式語言(如C或C++和PERL等)中使用的switch...case語句非常相似。
Unix - Shell迴圈型別
在本章中,我們將討論Unix中的shell迴圈。迴圈是一種強大的程式設計工具,使您能夠重複執行一組命令。在本章中,我們將檢查shell程式設計師可用的以下型別的迴圈 -
您將根據情況使用不同的迴圈。例如,while迴圈執行給定的命令,直到給定的條件保持為真;until迴圈執行直到給定的條件變為真。
一旦您擁有良好的程式設計實踐,您將獲得專業知識,從而開始根據情況使用合適的迴圈。這裡,while和for迴圈在大多數其他程式語言(如C、C++和PERL等)中都可用。
巢狀迴圈
所有迴圈都支援巢狀概念,這意味著您可以將一個迴圈放在另一個類似的迴圈或不同的迴圈內。此巢狀可以根據您的需求無限次進行。
以下是一個巢狀while迴圈的示例。其他迴圈可以根據程式設計需求以類似的方式巢狀 -
巢狀while迴圈
可以使用while迴圈作為另一個while迴圈主體的一部分。
語法
while command1 ; # this is loop1, the outer loop do Statement(s) to be executed if command1 is true while command2 ; # this is loop2, the inner loop do Statement(s) to be executed if command2 is true done Statement(s) to be executed if command1 is true done
示例
以下是一個簡單的迴圈巢狀示例。讓我們在用於計數到九的迴圈內新增另一個倒計時迴圈 -
#!/bin/sh a=0 while [ "$a" -lt 10 ] # this is loop1 do b="$a" while [ "$b" -ge 0 ] # this is loop2 do echo -n "$b " b=`expr $b - 1` done echo a=`expr $a + 1` done
這將產生以下結果。重要的是要注意echo -n在這裡是如何工作的。這裡-n選項允許echo避免列印換行符。
0 1 0 2 1 0 3 2 1 0 4 3 2 1 0 5 4 3 2 1 0 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
Unix - Shell迴圈控制
在本章中,我們將討論Unix中的shell迴圈控制。到目前為止,您已經瞭解了建立迴圈以及使用迴圈來完成不同任務。有時您需要停止迴圈或跳過迴圈的迭代。
在本章中,我們將學習以下兩個用於控制shell迴圈的語句 -
break語句
continue語句
無限迴圈
所有迴圈都有有限的生命週期,一旦條件為假或真,它們就會退出,具體取決於迴圈。
如果未滿足所需條件,迴圈可能會永遠繼續。永遠執行而不終止的迴圈會執行無限次。因此,此類迴圈稱為無限迴圈。
示例
以下是一個簡單的示例,它使用while迴圈顯示數字零到九 -
#!/bin/sh a=10 until [ $a -lt 10 ] do echo $a a=`expr $a + 1` done
此迴圈永遠繼續,因為a始終大於或等於10,並且永遠小於10。
break語句
break語句用於終止整個迴圈的執行,在完成執行直到break語句的所有程式碼行後。然後它向下轉到迴圈結束後的程式碼。
語法
以下break語句用於退出迴圈 -
break
break命令也可以使用此格式退出巢狀迴圈 -
break n
這裡n指定要退出的第n個封閉迴圈。
示例
以下是一個簡單的示例,它顯示迴圈一旦a變為5就會終止 -
#!/bin/sh a=0 while [ $a -lt 10 ] do echo $a if [ $a -eq 5 ] then break fi a=`expr $a + 1` done
執行後,您將收到以下結果:
0 1 2 3 4 5
以下是一個巢狀for迴圈的簡單示例。如果var1等於2並且var2等於0,則此指令碼將退出這兩個迴圈 -
#!/bin/sh for var1 in 1 2 3 do for var2 in 0 5 do if [ $var1 -eq 2 -a $var2 -eq 0 ] then break 2 else echo "$var1 $var2" fi done done
執行後,您將收到以下結果。在內部迴圈中,您有一個帶引數2的break命令。這表示如果滿足條件,您應該退出外部迴圈,最終也退出內部迴圈。
1 0 1 5
continue語句
continue語句類似於break命令,不同之處在於它會導致當前迴圈迭代退出,而不是整個迴圈。
當發生錯誤但您想嘗試執行迴圈的下一迭代時,此語句很有用。
語法
continue
與break語句一樣,可以向continue命令提供一個整數引數以跳過巢狀迴圈中的命令。
continue n
這裡n指定要繼續執行的第n個封閉迴圈。
示例
以下迴圈使用了continue語句,該語句從continue語句返回並開始處理下一條語句 -
#!/bin/sh NUMS="1 2 3 4 5 6 7" for NUM in $NUMS do Q=`expr $NUM % 2` if [ $Q -eq 0 ] then echo "Number is an even number!!" continue fi echo "Found odd number" done
執行後,您將收到以下結果:
Found odd number Number is an even number!! Found odd number Number is an even number!! Found odd number Number is an even number!! Found odd number
Unix - Shell替換
什麼是替換?
當shell遇到包含一個或多個特殊字元的表示式時,它會執行替換。
示例
這裡,變數的列印值被其值替換。同時,"\n"被換行符替換 -
#!/bin/sh a=10 echo -e "Value of a is $a \n"
您將收到以下結果。這裡-e選項啟用反斜槓轉義的解釋。
Value of a is 10
以下是不使用-e選項的結果 -
Value of a is 10\n
以下是可在echo命令中使用的轉義序列 -
序號 | 轉義符 & 描述 |
---|---|
1 |
\\ 反斜槓 |
2 |
\a 警報 (BEL) |
3 |
\b 退格鍵 |
4 |
\c 抑制尾隨換行符 |
5 |
\f 換頁符 |
6 |
\n 換行符 |
7 |
\r 回車符 |
8 |
\t 水平製表符 |
9 |
\v 垂直製表符 |
您可以使用-E選項停用反斜槓轉義的解釋(預設值)。
您可以使用-n選項停用插入換行符。
命令替換
命令替換是shell執行給定命令集然後將其輸出替換為命令位置的機制。
語法
當給出以下命令時,會執行命令替換 -
`command`
執行命令替換時,請確保使用反引號,而不是單引號字元。
示例
命令替換通常用於將命令的輸出分配給變數。以下每個示例都演示了命令替換 -
#!/bin/sh DATE=`date` echo "Date is $DATE" USERS=`who | wc -l` echo "Logged in user are $USERS" UP=`date ; uptime` echo "Uptime is $UP"
執行後,您將收到以下結果:
Date is Thu Jul 2 03:59:57 MST 2009 Logged in user are 1 Uptime is Thu Jul 2 03:59:57 MST 2009 03:59:57 up 20 days, 14:03, 1 user, load avg: 0.13, 0.07, 0.15
變數替換
變數替換使shell程式設計師能夠根據變數的狀態來操作變數的值。
以下是所有可能替換的表格 -
序號 | 形式 & 描述 |
---|---|
1 |
${var} 替換var的值。 |
2 |
${var:-word} 如果var為空或未設定,則將word替換為var。var的值不會改變。 |
3 |
${var:=word} 如果var為空或未設定,則var將設定為word的值。 |
4 |
${var:?message} 如果var為空或未設定,則將message列印到標準錯誤。這檢查變數是否正確設定。 |
5 |
${var:+word} 如果var已設定,則將word替換為var。var的值不會改變。 |
示例
以下示例顯示了上述替換的各種狀態 -
#!/bin/sh echo ${var:-"Variable is not set"} echo "1 - Value of var is ${var}" echo ${var:="Variable is not set"} echo "2 - Value of var is ${var}" unset var echo ${var:+"This is default value"} echo "3 - Value of var is $var" var="Prefix" echo ${var:+"This is default value"} echo "4 - Value of var is $var" echo ${var:?"Print this message"} echo "5 - Value of var is ${var}"
執行後,您將收到以下結果:
Variable is not set 1 - Value of var is Variable is not set 2 - Value of var is Variable is not set 3 - Value of var is This is default value 4 - Value of var is Prefix Prefix 5 - Value of var is Prefix
Unix - Shell引用機制
在本章中,我們將詳細討論Shell引用機制。我們將從討論元字元開始。
元字元
Unix Shell提供各種元字元,這些字元在任何Shell指令碼中使用時都具有特殊含義,並導致單詞終止,除非被引用。
例如,?在列出目錄中的檔案時與單個字元匹配,而*與多個字元匹配。以下是大多數shell特殊字元(也稱為元字元)的列表 -
* ? [ ] ' " \ $ ; & ( ) | ^ < > new-line space tab
可以透過在其前面加上\來引用字元(即使其代表自身)。
示例
以下示例顯示瞭如何列印*或? -
#!/bin/sh echo Hello; Word
執行後,您將收到以下結果:
Hello ./test.sh: line 2: Word: command not found shell returned 127
現在讓我們嘗試使用引用的字元 -
#!/bin/sh echo Hello\; Word
執行後,您將收到以下結果:
Hello; Word
$符號是元字元之一,因此必須對其進行引用以避免shell的特殊處理 -
#!/bin/sh echo "I have \$1200"
執行後,您將收到以下結果:
I have $1200
下表列出了四種引用形式 -
序號 | 引用 & 描述 |
---|---|
1 |
單引號 這些引號之間的所有特殊字元都將失去其特殊含義。 |
2 |
雙引號 這些引號之間的大多數特殊字元都將失去其特殊含義,但以下例外 -
|
3 |
反斜槓 反斜槓後面的任何字元都將失去其特殊含義。 |
4 |
反引號 反引號之間的任何內容都將被視為命令並執行。 |
單引號
考慮一個包含許多特殊shell字元的echo命令 -
echo <-$1500.**>; (update?) [y|n]
在每個特殊字元前面加上反斜槓既繁瑣又使行難以閱讀 -
echo \<-\$1500.\*\*\>\; \(update\?\) \[y\|n\]
有一種簡單的方法可以引用大量字元。在字串的開頭和結尾處加上單引號(') -
echo '<-$1500.**>; (update?) [y|n]'
單引號內的字元就像每個字元前面都有反斜槓一樣被引用。這樣,echo命令就可以以正確的方式顯示。
如果單引號出現在要輸出的字串中,則不應將整個字串放在單引號中,而應使用反斜槓(\)在其前面,如下所示 -
echo 'It\'s Shell Programming
雙引號
嘗試執行以下shell指令碼。此shell指令碼使用了單引號 -
VAR=ZARA echo '$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]'
執行後,您將收到以下結果:
$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]
這不是必須顯示的內容。很明顯,單引號阻止了變數替換。如果要替換變數值並使倒引號按預期工作,則需要將命令放在雙引號中,如下所示 -
VAR=ZARA echo "$VAR owes <-\$1500.**>; [ as of (`date +%m/%d`) ]"
執行後,您將收到以下結果:
ZARA owes <-$1500.**>; [ as of (07/02) ]
雙引號消除了除以下字元之外的所有字元的特殊含義 -
$ 用於引數替換
反引號用於命令替換
\$ 用於啟用文字美元符號
\` 用於啟用文字反引號
\" 用於啟用嵌入式雙引號
\\ 用於啟用嵌入式反斜槓
所有其他\字元都是文字(不是特殊字元)
單引號內的字元就像每個字元前面都有反斜槓一樣被引用。這有助於echo命令正確顯示。
如果單引號出現在要輸出的字串中,則不應將整個字串放在單引號中,而應使用反斜槓(\)在其前面,如下所示 -
echo 'It\'s Shell Programming'
反引號
將任何Shell命令放在反引號之間會執行該命令。
語法
下面是將任何 Shell **命令**放在反引號之間的簡單語法。
var=`command`
示例
在下面的示例中,執行了**date**命令,並將產生的結果儲存在 DATA 變數中。
DATE=`date` echo "Current Date: $DATE"
執行後,您將收到以下結果:
Current Date: Thu Jul 2 05:28:45 MST 2009
Unix - Shell 輸入/輸出重定向
在本章中,我們將詳細討論 Shell 輸入/輸出重定向。大多數 Unix 系統命令從您的終端獲取輸入,並將結果輸出傳送回您的終端。命令通常從標準輸入讀取其輸入,預設情況下標準輸入恰好是您的終端。類似地,命令通常將其輸出寫入標準輸出,預設情況下標準輸出也是您的終端。
輸出重定向
通常用於標準輸出的命令輸出可以輕鬆地改為重定向到檔案。此功能稱為輸出重定向。
如果符號 > file 附加到任何通常將其輸出寫入標準輸出的命令,則該命令的輸出將寫入檔案而不是您的終端。
檢查以下**who**命令,該命令將命令的完整輸出重定向到 users 檔案中。
$ who > users
請注意,終端上沒有顯示任何輸出。這是因為輸出已從預設標準輸出裝置(終端)重定向到指定的檔案。您可以檢查 users 檔案以獲取完整內容 -
$ cat users oko tty01 Sep 12 07:30 ai tty15 Sep 12 13:32 ruth tty21 Sep 12 10:10 pat tty24 Sep 12 13:07 steve tty25 Sep 12 13:03 $
如果命令的輸出重定向到檔案,並且該檔案已包含某些資料,則這些資料將丟失。請考慮以下示例 -
$ echo line 1 > users $ cat users line 1 $
您可以使用 >> 運算子將輸出追加到現有檔案中,如下所示 -
$ echo line 2 >> users $ cat users line 1 line 2 $
輸入重定向
就像命令的輸出可以重定向到檔案一樣,命令的輸入也可以重定向到檔案。由於**大於號 >**用於輸出重定向,因此**小於號 <**用於重定向命令的輸入。
通常從標準輸入獲取輸入的命令可以以這種方式從檔案重定向其輸入。例如,要計算上面生成的 users 檔案中的行數,您可以執行以下命令 -
$ wc -l users 2 users $
執行後,您將收到以下輸出。您可以透過將**wc**命令的標準輸入從 users 檔案重定向來計算檔案中的行數 -
$ wc -l < users 2 $
請注意,wc 命令的兩種形式產生的輸出存在差異。在第一種情況下,檔案 users 的名稱與行數一起列出;在第二種情況下,則沒有。
在第一種情況下,wc 知道它正在從檔案 users 讀取其輸入。在第二種情況下,它只知道它正在從標準輸入讀取其輸入,因此它不會顯示檔名。
此處文件
**此處文件**用於將輸入重定向到互動式 shell 指令碼或程式。
我們可以透過為互動式程式或互動式 shell 指令碼提供所需的輸入,在 shell 指令碼中執行互動式程式,而無需使用者操作。
**此處**文件的通用形式如下 -
command << delimiter document delimiter
此處,shell 將**<<**運算子解釋為讀取輸入的指令,直到找到包含指定分隔符的行。然後,所有直到包含分隔符的行之前的輸入行都將饋送到命令的標準輸入。
分隔符告訴 shell **此處**文件已完成。如果沒有它,shell 將永遠繼續讀取輸入。分隔符必須是一個不包含空格或製表符的單個單詞。
以下是 **wc -l** 命令的輸入,用於計算總行數 -
$wc -l << EOF This is a simple lookup program for good (and bad) restaurants in Cape Town. EOF 3 $
您可以使用**此處文件**透過您的指令碼列印多行,如下所示 -
#!/bin/sh cat << EOF This is a simple lookup program for good (and bad) restaurants in Cape Town. EOF
執行後,您將收到以下結果:
This is a simple lookup program for good (and bad) restaurants in Cape Town.
以下指令碼執行與**vi**文字編輯器的會話並將輸入儲存到檔案**test.txt**中。
#!/bin/sh filename=test.txt vi $filename <<EndOfCommands i This file was created automatically from a shell script ^[ ZZ EndOfCommands
如果您執行此指令碼,其中 vim 充當 vi,那麼您可能會看到如下輸出 -
$ sh test.sh Vim: Warning: Input is not from a terminal $
執行指令碼後,您應該會看到以下內容新增到檔案**test.txt**中 -
$ cat test.txt This file was created automatically from a shell script $
丟棄輸出
有時您需要執行命令,但不想在螢幕上顯示輸出。在這種情況下,您可以透過將其重定向到檔案** /dev/null**來丟棄輸出 -
$ command > /dev/null
此處 command 是您要執行的命令的名稱。檔案** /dev/null**是一個特殊檔案,會自動丟棄其所有輸入。
要丟棄命令的輸出及其錯誤輸出,請使用標準重定向將**STDERR**重定向到**STDOUT** -
$ command > /dev/null 2>&1
這裡**2**代表**STDERR**,**1**代表**STDOUT**。您可以透過將 STDOUT 重定向到 STDERR 來在 STDERR 上顯示訊息,如下所示 -
$ echo message 1>&2
重定向命令
以下是您可以用於重定向的完整命令列表 -
序號 | 命令和說明 |
---|---|
1 |
pgm > file pgm 的輸出重定向到 file |
2 |
pgm < file 程式 pgm 從 file 讀取其輸入 |
3 |
pgm >> file pgm 的輸出追加到 file |
4 |
n > file 具有描述符**n**的流的輸出重定向到 file |
5 |
n >> file 具有描述符**n**的流的輸出追加到 file |
6 |
n >& m 將流**n**的輸出與流**m**合併 |
7 |
n <& m 將流**n**的輸入與流**m**合併 |
8 |
<< tag 標準輸入從此處透過下一行開頭的 tag 傳入 |
9 |
| 獲取一個程式或程序的輸出,並將其傳送到另一個程式或程序 |
請注意,檔案描述符**0**通常是標準輸入 (STDIN),**1**是標準輸出 (STDOUT),**2**是標準錯誤輸出 (STDERR)。
Unix - Shell 函式
在本章中,我們將詳細討論 shell 函式。函式使您能夠將指令碼的整體功能分解成更小、更邏輯的子部分,然後可以在需要時呼叫這些子部分來執行其各自的任務。
使用函式執行重複性任務是建立**程式碼重用**的絕佳方法。這是現代面向物件程式設計原則的重要組成部分。
Shell 函式類似於其他程式語言中的子例程、過程和函式。
建立函式
要宣告函式,只需使用以下語法 -
function_name () { list of commands }
您的函式的名稱是**function_name**,這就是您將在指令碼的其他地方使用它來呼叫它的方式。函式名稱後面必須跟括號,然後是括在大括號中的命令列表。
示例
以下示例顯示了函式的使用 -
#!/bin/sh # Define your function here Hello () { echo "Hello World" } # Invoke your function Hello
執行後,您將收到以下輸出 -
$./test.sh Hello World
向函式傳遞引數
您可以定義一個函式,該函式將在呼叫函式時接受引數。這些引數將由**$1**、**$2**等表示。
以下是一個示例,我們傳遞兩個引數 Zara 和 Ali,然後我們在函式中捕獲並列印這些引數。
#!/bin/sh # Define your function here Hello () { echo "Hello World $1 $2" } # Invoke your function Hello Zara Ali
執行後,您將收到以下結果:
$./test.sh Hello World Zara Ali
從函式返回值
如果您從函式內部執行**exit**命令,其效果不僅是終止函式的執行,還會終止呼叫該函式的 shell 程式的執行。
如果您只想終止函式的執行,則有一種方法可以退出已定義的函式。
根據情況,您可以使用**return**命令從您的函式返回任何值,其語法如下 -
return code
此處**code**可以是您選擇的任何內容,但顯然您應該選擇在整個指令碼的上下文中具有意義或有用的內容。
示例
以下函式返回一個值 10 -
#!/bin/sh # Define your function here Hello () { echo "Hello World $1 $2" return 10 } # Invoke your function Hello Zara Ali # Capture value returnd by last command ret=$? echo "Return value is $ret"
執行後,您將收到以下結果:
$./test.sh Hello World Zara Ali Return value is 10
巢狀函式
函式更有趣的特性之一是它們可以呼叫自身以及其他函式。呼叫自身的函式稱為**遞迴函式**。
以下示例演示了兩個函式的巢狀 -
#!/bin/sh # Calling one function from another number_one () { echo "This is the first function speaking..." number_two } number_two () { echo "This is now the second function speaking..." } # Calling function one. number_one
執行後,您將收到以下結果:
This is the first function speaking... This is now the second function speaking...
從提示符呼叫函式
您可以將常用函式的定義放在您的**.profile**中。這些定義將在您登入時可用,您可以在命令提示符下使用它們。
或者,您可以將定義分組到一個檔案中,例如**test.sh**,然後透過鍵入以下內容在當前 shell 中執行該檔案 -
$. test.sh
這將導致在**test.sh**中定義的函式被讀取並定義到當前 shell 中,如下所示 -
$ number_one This is the first function speaking... This is now the second function speaking... $
要從 shell 中刪除函式的定義,請使用帶**.f**選項的 unset 命令。此命令也用於從 shell 中刪除變數的定義。
$ unset -f function_name
Unix - Shell 手冊頁幫助
所有 Unix 命令都帶有一些可選和必需的選項。忘記這些命令的完整語法非常常見。
因為沒有人能記住每個 Unix 命令及其所有選項,所以我們提供了線上幫助來緩解這種情況,從 Unix 開發階段開始就提供了。
Unix 的**幫助檔案**版本稱為**手冊頁**。如果有一個命令名稱,您不確定如何使用它,則手冊頁可以幫助您完成每個步驟。
語法
以下是在使用系統時幫助您獲取任何 Unix 命令詳細資訊的簡單命令 -
$man command
示例
假設有一個命令需要您獲取幫助;假設您想知道有關**pwd**的資訊,那麼您只需使用以下命令 -
$man pwd
以上命令幫助您瞭解有關**pwd**命令的完整資訊。在您的命令提示符下親自嘗試一下以獲取更多詳細資訊。
您可以使用以下命令獲取有關**man**命令本身的完整詳細資訊 -
$man man
手冊頁部分
手冊頁通常分為幾個部分,這些部分通常因手冊頁作者的偏好而異。下表列出了一些常見的部分 -
序號 | 部分 & 描述 |
---|---|
1 |
NAME 命令的名稱 |
2 |
SYNOPSIS 命令的一般用法引數 |
3 |
DESCRIPTION 描述命令的作用 |
4 |
OPTIONS 描述命令的所有引數或選項 |
5 |
SEE ALSO 列出與手冊頁中的命令直接相關或與其功能非常相似的其他命令 |
6 |
BUGS 解釋命令或其輸出存在的任何已知問題或錯誤 |
7 |
EXAMPLES 常見的用法示例,讓讀者瞭解如何使用該命令 |
8 |
AUTHORS 手冊頁/命令的作者 |
總而言之,手冊頁是重要的資源,也是在您需要有關 Unix 系統中的命令或檔案的資訊時進行研究的第一途徑。
有用的 Shell 命令
以下連結為您提供最重要的和最常用的 Unix Shell 命令列表。
如果您不知道如何使用任何命令,請使用手冊頁獲取有關該命令的完整詳細資訊。
以下是Unix Shell - 有用命令的列表
Unix - 使用 SED 的正則表示式
在本章中,我們將詳細討論 Unix 中使用 SED 的正則表示式。
正則表示式是可以用來描述多個字元序列的字串。正則表示式被幾個不同的 Unix 命令使用,包括**ed**、**sed**、**awk**、**grep**,以及在更有限的程度上,**vi**。
這裡SED代表stream editor(流編輯器)。這個面向流的編輯器是專門為執行指令碼而建立的。因此,您輸入的所有內容都會透過它傳遞到STDOUT,並且它不會更改輸入檔案。
呼叫sed
在開始之前,讓我們確保我們有一個/etc/passwd文字檔案的本地副本,以便與sed一起使用。
如前所述,sed可以透過將資料透過管道傳送到它來呼叫,如下所示:
$ cat /etc/passwd | sed Usage: sed [OPTION]... {script-other-script} [input-file]... -n, --quiet, --silent suppress automatic printing of pattern space -e script, --expression = script ...............................
cat命令將/etc/passwd的內容透過管道轉儲到sed,進入sed的模式空間。模式空間是sed在其操作中使用的內部工作緩衝區。
sed通用語法
以下是sed的通用語法:
/pattern/action
這裡,pattern是正則表示式,action是下表中給出的命令之一。如果省略pattern,則對每一行執行action,就像我們上面看到的那樣。
包圍模式的斜槓字元(/)是必需的,因為它們用作分隔符。
序號 | 範圍和描述 |
---|---|
1 |
p 列印該行 |
2 |
d 刪除該行 |
3 |
s/pattern1/pattern2/ 將pattern1的第一次出現替換為pattern2 |
使用sed刪除所有行
現在我們將瞭解如何使用sed刪除所有行。再次呼叫sed;但現在sed應該使用編輯命令刪除行,用單個字母d表示:
$ cat /etc/passwd | sed 'd' $
sed可以透過從檔案讀取資料來代替透過管道傳送檔案的方式呼叫,如下例所示。
以下命令與前面的示例完全相同,無需cat命令:
$ sed -e 'd' /etc/passwd $
sed地址
sed也支援地址。地址要麼是檔案中的特定位置,要麼是應應用特定編輯命令的範圍。當sed遇到沒有地址時,它會對檔案中的每一行執行其操作。
以下命令向您一直在使用的sed命令添加了一個基本地址:
$ cat /etc/passwd | sed '1d' |more daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh $
請注意,數字1是在刪除編輯命令之前新增的。這指示sed對檔案的第1行執行編輯命令。在此示例中,sed將刪除/etc/password的第一行並列印檔案的其餘部分。
sed地址範圍
現在我們將瞭解如何使用sed地址範圍。那麼,如果您想從檔案中刪除多行怎麼辦?您可以使用sed指定地址範圍,如下所示:
$ cat /etc/passwd | sed '1, 5d' |more games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh $
以上命令將應用於從1到5的所有行。這將刪除前五行。
嘗試以下地址範圍:
序號 | 範圍和描述 |
---|---|
1 |
'4,10d' 從第4行到第10行都被刪除 |
2 |
'10,4d' 僅刪除第10行,因為sed不反向工作 |
3 |
'4,+5d' 這匹配檔案中的第4行,刪除該行,繼續刪除接下來的五行,然後停止刪除並列印其餘部分 |
4 |
'2,5!d' 這將刪除除第2行到第5行之外的所有內容 |
5 |
'1~3d' 這將刪除第一行,跳過接下來的三行,然後刪除第四行。sed繼續應用此模式,直到檔案結束。 |
6 |
'2~2d' 這告訴sed刪除第二行,跳過下一行,刪除下一行,並重復直到檔案結束 |
7 |
'4,10p' 從第4行到第10行都被列印 |
8 |
'4,d' 這會生成語法錯誤 |
9 |
',10d' 這也會生成語法錯誤 |
注意 - 使用p操作時,應使用-n選項避免重複列印行。檢查以下兩個命令之間的區別:
$ cat /etc/passwd | sed -n '1,3p' Check the above command without -n as follows − $ cat /etc/passwd | sed '1,3p'
替換命令
替換命令(用s表示)將替換您指定的任何字串為任何其他您指定的字串。
要將一個字串替換為另一個字串,sed需要知道第一個字串在哪裡結束以及替換字串在哪裡開始的資訊。為此,我們繼續用正斜槓(/)字元將這兩個字串括起來。
以下命令將該行上root字串的第一次出現替換為amrood字串。
$ cat /etc/passwd | sed 's/root/amrood/' amrood:x:0:0:root user:/root:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh ..........................
務必注意,sed僅替換一行上的第一次出現。如果字串root在一行上出現多次,則只替換第一個匹配項。
為了使sed執行全域性替換,請在命令末尾新增字母g,如下所示:
$ cat /etc/passwd | sed 's/root/amrood/g' amrood:x:0:0:amrood user:/amrood:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh ...........................
替換標誌
除了g標誌之外,還可以傳遞許多其他有用的標誌,並且您可以同時指定多個標誌。
序號 | 標誌和描述 |
---|---|
1 |
g 替換所有匹配項,而不僅僅是第一個匹配項 |
2 |
NUMBER 僅替換第NUMBER個匹配項 |
3 |
p 如果進行了替換,則列印模式空間 |
4 |
w FILENAME 如果進行了替換,則將結果寫入FILENAME |
5 |
I或i 以不區分大小寫的方式匹配 |
6 |
M或m 除了特殊正則表示式字元^和$的正常行為之外,此標誌還會導致^匹配換行符後的空字串,$匹配換行符前的空字串 |
使用替代字串分隔符
假設您必須對包含正斜槓字元的字串進行替換。在這種情況下,您可以透過在s之後提供指定的字元來指定不同的分隔符。
$ cat /etc/passwd | sed 's:/root:/amrood:g' amrood:x:0:0:amrood user:/amrood:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh
在上面的示例中,我們使用了:作為分隔符而不是斜槓/,因為我們試圖搜尋/root而不是簡單的root。
替換為空格
使用空替換字串將/etc/passwd檔案中的root字串完全刪除:
$ cat /etc/passwd | sed 's/root//g' :x:0:0::/:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh
地址替換
如果您只想在第10行上將字串sh替換為字串quiet,您可以按如下方式指定:
$ cat /etc/passwd | sed '10s/sh/quiet/g' root:x:0:0:root user:/root:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/quiet
類似地,要進行地址範圍替換,您可以執行以下操作:
$ cat /etc/passwd | sed '1,5s/sh/quiet/g' root:x:0:0:root user:/root:/bin/quiet daemon:x:1:1:daemon:/usr/sbin:/bin/quiet bin:x:2:2:bin:/bin:/bin/quiet sys:x:3:3:sys:/dev:/bin/quiet sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh
從輸出中可以看到,前五行將字串sh更改為quiet,但其餘行保持不變。
匹配命令
您將使用p選項和-n選項來列印所有匹配的行,如下所示:
$ cat testing | sed -n '/root/p' root:x:0:0:root user:/root:/bin/sh [root@ip-72-167-112-17 amrood]# vi testing root:x:0:0:root user:/root:/bin/sh daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh
使用正則表示式
在匹配模式時,您可以使用正則表示式,它提供了更大的靈活性。
檢查以下示例,該示例匹配所有以daemon開頭的行,然後刪除它們:
$ cat testing | sed '/^daemon/d' root:x:0:0:root user:/root:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh backup:x:34:34:backup:/var/backups:/bin/sh
以下示例刪除所有以sh結尾的行:
$ cat testing | sed '/sh$/d' sync:x:4:65534:sync:/bin:/bin/sync
下表列出了正則表示式中非常有用的四個特殊字元。
序號 | 字元和描述 |
---|---|
1 |
^ 匹配行的開頭 |
2 |
$ 匹配行的結尾 |
3 |
. 匹配任何單個字元 |
4 |
* 匹配前一個字元的零個或多個出現 |
5 |
[chars] 匹配chars中給出的任何一個字元,其中chars是字元序列。您可以使用-字元表示字元範圍。 |
匹配字元
檢視更多表達式以演示元字元的使用。例如,以下模式:
序號 | 表示式和描述 |
---|---|
1 |
/a.c/ 匹配包含a+c、a-c、abc、match和a3c等字串的行 |
2 |
/a*c/ 匹配相同的字串以及ace、yacc和arctic等字串 |
3 |
/[tT]he/ 匹配字串The和the |
4 |
/^$/ 匹配空行 |
5 |
/^.*$/ 匹配任何整行 |
6 |
/ */ 匹配一個或多個空格 |
7 |
/^$/ 匹配空行 |
下表顯示了一些常用的字元集:
序號 | 集和描述 |
---|---|
1 |
[a-z] 匹配單個小寫字母 |
2 |
[A-Z] 匹配單個大寫字母 |
3 |
[a-zA-Z] 匹配單個字母 |
4 |
[0-9] 匹配單個數字 |
5 |
[a-zA-Z0-9] 匹配單個字母或數字 |
字元類關鍵字
一些特殊關鍵字通常可用於regexps,尤其是使用regexps的GNU實用程式。它們對sed正則表示式非常有用,因為它們簡化了操作並提高了可讀性。
例如,字元a到z和字元A到Z構成一類具有關鍵字[[:alpha:]]的字元。
使用字母字元類關鍵字,此命令僅列印/etc/syslog.conf檔案中以字母開頭的那些行:
$ cat /etc/syslog.conf | sed -n '/^[[:alpha:]]/p' authpriv.* /var/log/secure mail.* -/var/log/maillog cron.* /var/log/cron uucp,news.crit /var/log/spooler local7.* /var/log/boot.log
下表是GNU sed中可用字元類關鍵字的完整列表。
序號 | 字元類和描述 |
---|---|
1 |
[[:alnum:]] 字母數字 [a-z A-Z 0-9] |
2 |
[[:alpha:]] 字母 [a-z A-Z] |
3 |
[[:blank:]] 空白字元(空格或製表符) |
4 |
[[:cntrl:]] 控制字元 |
5 |
[[:digit:]] 數字 [0-9] |
6 |
[[:graph:]] 任何可見字元(不包括空格) |
7 |
[[:lower:]] 小寫字母 [a-z] |
8 |
[[:print:]] 可列印字元(非控制字元) |
9 |
[[:punct:]] 標點符號 |
10 |
[[:space:]] 空白字元 |
11 |
[[:upper:]] 大寫字母 [A-Z] |
12 |
[[:xdigit:]] 十六進位制數字 [0-9 a-f A-F] |
&符號引用
sed元字元&表示匹配的模式的內容。例如,假設您有一個名為phone.txt的檔案,其中包含以下電話號碼:
5555551212 5555551213 5555551214 6665551215 6665551216 7775551217
您希望將區號(前三位數字)用括號括起來,以便於閱讀。為此,您可以使用&替換字元:
$ sed -e 's/^[[:digit:]][[:digit:]][[:digit:]]/(&)/g' phone.txt (555)5551212 (555)5551213 (555)5551214 (666)5551215 (666)5551216 (777)5551217
這裡在模式部分,您匹配前三位數字,然後使用&將這三位數字替換為周圍的括號。
使用多個sed命令
您可以在單個sed命令中使用多個sed命令,如下所示:
$ sed -e 'command1' -e 'command2' ... -e 'commandN' files
這裡command1到commandN是前面討論過的型別的sed命令。這些命令應用於files給出的檔案列表中的每一行。
使用相同的機制,我們可以將上述電話號碼示例編寫如下:
$ sed -e 's/^[[:digit:]]\{3\}/(&)/g' \ -e 's/)[[:digit:]]\{3\}/&-/g' phone.txt (555)555-1212 (555)555-1213 (555)555-1214 (666)555-1215 (666)555-1216 (777)555-1217
注意 - 在上面的示例中,我們沒有重複三次字元類關鍵字[[:digit:]],而是用\{3\}替換它,這意味著前面的正則表示式匹配三次。我們還使用了\來換行,在執行命令之前必須將其刪除。
反向引用
&符號元字元很有用,但更實用的是能夠在正則表示式中定義特定區域。這些特殊區域可以在替換字串中用作參考。透過定義正則表示式的特定部分,您可以使用特殊的引用字元來引用這些部分。
要進行反向引用,您必須首先定義一個區域,然後引用該區域。要定義一個區域,您需要在每個感興趣的區域周圍插入反斜槓括號。您用反斜槓括起來的第一個區域由\1引用,第二個區域由\2引用,以此類推。
假設phone.txt包含以下文字:
(555)555-1212 (555)555-1213 (555)555-1214 (666)555-1215 (666)555-1216 (777)555-1217
嘗試以下命令:
$ cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area \ code: \1 Second: \2 Third: \3/' Area code: (555) Second: 555- Third: 1212 Area code: (555) Second: 555- Third: 1213 Area code: (555) Second: 555- Third: 1214 Area code: (666) Second: 555- Third: 1215 Area code: (666) Second: 555- Third: 1216 Area code: (777) Second: 555- Third: 1217
注意 - 在上面的示例中,括號內的每個正則表示式將分別由\1、\2等進行反向引用。我們在這裡使用了\來換行。在執行命令之前應將其刪除。
Unix - 檔案系統基礎
檔案系統是分割槽或磁碟上檔案的邏輯集合。分割槽是資訊的容器,如果需要,可以跨越整個硬碟驅動器。
您的硬碟驅動器可以有多個分割槽,這些分割槽通常只包含一個檔案系統,例如一個檔案系統容納/檔案系統,另一個檔案系統容納/home檔案系統。
每個分割槽一個檔案系統允許對不同的檔案系統進行邏輯維護和管理。
在Unix中,所有內容都被視為檔案,包括物理裝置,例如DVD-ROM、USB裝置和軟盤驅動器。
目錄結構
Unix使用分層檔案系統結構,很像一棵倒置的樹,根目錄(/)位於檔案系統的底部,所有其他目錄都從那裡擴充套件。
Unix檔案系統是檔案的集合和目錄,具有以下屬性:
它有一個根目錄(/),其中包含其他檔案和目錄。
每個檔案或目錄都由其名稱、所在的目錄和唯一的識別符號(通常稱為inode)唯一標識。
按照慣例,根目錄的inode編號為2,lost+found目錄的inode編號為3。inode編號0和1未使用。可以透過為ls命令指定-i選項檢視檔案inode編號。
它是自包含的。一個檔案系統與另一個檔案系統之間沒有依賴關係。
這些目錄具有特定的用途,並且通常儲存相同型別的資訊,以便於查詢檔案。以下是主要版本的Unix上存在的目錄:
序號 | 目錄&描述 |
---|---|
1 |
/ 這是根目錄,它應該只包含檔案結構頂層所需的目錄 |
2 |
/bin 這是可執行檔案所在的目錄。所有使用者都可以使用這些檔案 |
3 |
/dev 這些是裝置驅動程式 |
4 |
/etc 主管目錄命令、配置檔案、磁碟配置檔案、有效使用者列表、組、乙太網、主機、將關鍵訊息傳送到哪裡 |
5 |
/lib 包含共享庫檔案,有時還包含其他與核心相關的檔案 |
6 |
/boot 包含用於啟動系統的檔案 |
7 |
/home 包含使用者和其他帳戶的主目錄 |
8 |
/mnt 用於掛載其他臨時檔案系統,例如cdrom和floppy,分別用於CD-ROM驅動器和軟盤驅動器 |
9 |
/proc 包含所有程序,這些程序由程序號或其他對系統動態的資訊標記為檔案 |
10 |
/tmp 儲存系統啟動之間使用的臨時檔案 |
11 |
/usr 用於各種用途,並且可以被許多使用者使用。包括管理命令、共享檔案、庫檔案等 |
12 |
/var 通常包含可變長度的檔案,例如日誌和列印檔案,以及可能包含可變數量資料的任何其他型別的檔案 |
13 |
/sbin 包含二進位制(可執行)檔案,通常用於系統管理。例如,fdisk和ifconfig實用程式 |
14 |
/kernel 包含核心檔案 |
導航檔案系統
現在您已經瞭解了檔案系統的基礎知識,您可以開始導航到您需要的檔案。以下命令用於導航系統:
序號 | 命令和說明 |
---|---|
1 |
cat filename 顯示檔名 |
2 |
cd dirname 將您移動到指定的目錄 |
3 |
cp file1 file2 將一個檔案/目錄複製到指定位置 |
4 |
file filename 識別檔案型別(二進位制、文字等) |
5 |
find filename dir 查詢檔案/目錄 |
6 |
head filename 顯示檔案的開頭 |
7 |
less filename 從檔案末尾或開頭瀏覽檔案 |
8 |
ls dirname 顯示指定目錄的內容 |
9 |
mkdir dirname 建立指定的目錄 |
10 |
more filename 從頭到尾瀏覽檔案 |
11 |
mv file1 file2 移動檔案/目錄的位置或重新命名檔案/目錄 |
12 |
pwd 顯示使用者所在的當前目錄 |
13 |
rm filename 刪除檔案 |
14 |
rmdir dirname 刪除目錄 |
15 |
tail filename 顯示檔案的末尾 |
16 |
touch filename 建立一個空白檔案或修改現有檔案或其屬性 |
17 |
whereis filename 顯示檔案的位置 |
18 |
which filename 如果檔案在您的PATH中,則顯示檔案的位置 |
您可以使用手冊頁幫助檢查此處提到的每個命令的完整語法。
df命令
管理分割槽空間的第一種方法是使用df(磁碟空閒)命令。命令df -k(磁碟空閒)顯示以千位元組為單位的磁碟空間使用情況,如下所示:
$df -k Filesystem 1K-blocks Used Available Use% Mounted on /dev/vzfs 10485760 7836644 2649116 75% / /devices 0 0 0 0% /devices $
某些目錄,例如/devices,在kbytes、used和avail列中顯示0,容量為0%。這些是特殊的(或虛擬的)檔案系統,儘管它們駐留在/下的磁碟上,但它們本身不會佔用磁碟空間。
df -k輸出在所有Unix系統上通常相同。以下是它通常包含的內容:
序號 | 列 & 描述 |
---|---|
1 |
檔案系統 物理檔案系統名稱 |
2 |
kbytes 儲存介質上可用的總千位元組數 |
3 |
used 已使用的總千位元組數(由檔案佔用) |
4 |
avail 可用於使用的總千位元組數 |
5 |
capacity 檔案使用的總空間百分比 |
6 |
掛載點 檔案系統掛載到的位置 |
您可以使用-h(人類可讀)選項以更容易理解的表示法顯示輸出。
du命令
du(磁碟使用情況)命令使您能夠指定目錄以顯示特定目錄上的磁碟空間使用情況。
如果您想確定特定目錄佔用了多少空間,此命令很有用。以下命令顯示每個目錄消耗的塊數。單個塊可能佔用512位元組或1千位元組,具體取決於您的系統。
$du /etc 10 /etc/cron.d 126 /etc/default 6 /etc/dfs ... $
-h選項使輸出更容易理解:
$du -h /etc 5k /etc/cron.d 63k /etc/default 3k /etc/dfs ... $
掛載檔案系統
必須掛載檔案系統才能被系統使用。要檢視當前掛載到系統上的內容(可用),請使用以下命令:
$ mount /dev/vzfs on / type reiserfs (rw,usrquota,grpquota) proc on /proc type proc (rw,nodiratime) devpts on /dev/pts type devpts (rw) $
根據Unix約定,/mnt目錄是臨時掛載點(例如CDROM驅動器、遠端網路驅動器和軟盤驅動器)所在的位置。如果您需要掛載檔案系統,可以使用mount命令,其語法如下:
mount -t file_system_type device_to_mount directory_to_mount_to
例如,如果您想將CD-ROM掛載到目錄/mnt/cdrom,您可以鍵入:
$ mount -t iso9660 /dev/cdrom /mnt/cdrom
這假設您的CD-ROM裝置稱為/dev/cdrom,並且您希望將其掛載到/mnt/cdrom。有關更具體的資訊,請參閱mount手冊頁,或在命令列鍵入mount -h以獲取幫助資訊。
掛載後,您可以使用cd命令透過剛剛建立的掛載點導航新可用的檔案系統。
解除安裝檔案系統
要從系統中解除安裝(刪除)檔案系統,請使用umount命令並識別掛載點或裝置。
例如,要解除安裝cdrom,請使用以下命令:
$ umount /dev/cdrom
mount命令使您能夠訪問檔案系統,但在大多數現代Unix系統上,自動掛載功能使此過程對使用者不可見,並且不需要任何干預。
使用者和組配額
使用者和組配額提供了機制,透過這些機制,單個使用者或特定組內所有使用者使用的空間量可以限制為管理員定義的值。
配額圍繞兩個限制進行操作,如果空間量或磁碟塊數量開始超過管理員定義的限制,則允許使用者採取一些措施:
軟限制 - 如果使用者超過定義的限制,則會有一個寬限期,允許使用者釋放一些空間。
硬限制 - 當達到硬限制時,無論寬限期如何,都無法再分配任何檔案或塊。
有一些命令可以管理配額:
序號 | 命令和說明 |
---|---|
1 |
quota 顯示使用者或組的磁碟使用情況和限制 |
2 |
edquota 這是一個配額編輯器。可以使用此命令編輯使用者或組配額 |
3 |
quotacheck 掃描檔案系統以獲取磁碟使用情況,建立、檢查和修復配額檔案 |
4 |
setquota 這是一個命令列配額編輯器 |
5 |
quotaon 這會通知系統在一個或多個檔案系統上啟用磁碟配額 |
6 |
quotaoff 這會通知系統在一個或多個檔案系統上停用磁碟配額 |
7 |
repquota 這將列印指定檔案系統的磁碟使用情況和配額的摘要 |
您可以使用手冊頁幫助檢查此處提到的每個命令的完整語法。
Unix - 使用者管理
本章將詳細討論 Unix 中的使用者管理。
Unix 系統上有三種類型的賬戶:
根賬戶
這也被稱為**超級使用者**,擁有對系統的完全和不受限制的控制權。超級使用者可以執行任何命令而沒有任何限制。此使用者應被視為系統管理員。
系統賬戶
系統賬戶是系統特定元件操作所需的賬戶,例如郵件賬戶和**sshd**賬戶。這些賬戶通常是系統上某些特定功能所必需的,對其進行任何修改都可能對系統產生不利影響。
使用者賬戶
使用者賬戶為使用者和使用者組提供對系統的互動式訪問。普通使用者通常被分配到這些賬戶,並且通常對關鍵系統檔案和目錄的訪問許可權有限。
Unix 支援組賬戶的概念,它在邏輯上將多個賬戶分組。每個賬戶都將是另一個組賬戶的一部分。Unix 組在處理檔案許可權和程序管理方面發揮著重要作用。
管理使用者和組
主要有四個使用者管理檔案:
/etc/passwd - 儲存使用者賬戶和密碼資訊。此檔案儲存了 Unix 系統上大部分賬戶資訊。
/etc/shadow - 儲存對應賬戶的加密密碼。並非所有系統都支援此檔案。
/etc/group - 此檔案包含每個賬戶的組資訊。
/etc/gshadow - 此檔案包含安全的組賬戶資訊。
使用cat命令檢查所有上述檔案。
下表列出了大多數 Unix 系統上可用於建立和管理賬戶和組的命令:
序號 | 命令和說明 |
---|---|
1 |
useradd 向系統新增賬戶 |
2 |
usermod 修改賬戶屬性 |
3 |
userdel 從系統刪除賬戶 |
4 |
groupadd 向系統新增組 |
5 |
groupmod 修改組屬性 |
6 |
groupdel 從系統刪除組 |
您可以使用手冊頁幫助檢查此處提到的每個命令的完整語法。
建立組
現在我們將瞭解如何建立一個組。為此,我們需要在建立任何賬戶之前先建立組,否則,我們可以使用系統中現有的組。我們在/etc/groups檔案中列出了所有組。
所有預設組都是特定於系統賬戶的組,不建議將其用於普通賬戶。因此,以下是建立新組賬戶的語法:
groupadd [-g gid [-o]] [-r] [-f] groupname
下表列出了引數:
序號 | 選項 & 描述 |
---|---|
1 |
-g GID 組ID的數值 |
2 |
-o 此選項允許新增具有非唯一GID的組 |
3 |
-r 此標誌指示groupadd新增系統賬戶 |
4 |
-f 如果指定的組已存在,此選項會導致僅以成功狀態退出。使用 -g,如果指定的 GID 已存在,則選擇其他(唯一)GID |
5 |
groupname 要建立的實際組名 |
如果不指定任何引數,則系統使用預設值。
以下示例使用預設值建立了一個名為developers的組,這對於大多數管理員來說都是可以接受的。
$ groupadd developers
修改組
要修改組,請使用groupmod語法:
$ groupmod -n new_modified_group_name old_group_name
要將developers_2組名更改為developer,請鍵入:
$ groupmod -n developer developer_2
以下是將financial的GID更改為545的方法:
$ groupmod -g 545 developer
刪除組
現在我們將瞭解如何刪除組。要刪除現有組,您只需要groupdel命令和組名。要刪除financial組,命令為:
$ groupdel developer
這僅刪除組,不刪除與該組關聯的檔案。檔案仍然可以被其所有者訪問。
建立賬戶
讓我們看看如何在您的 Unix 系統上建立一個新賬戶。以下是建立使用者賬戶的語法:
useradd -d homedir -g groupname -m -s shell -u userid accountname
下表列出了引數:
序號 | 選項 & 描述 |
---|---|
1 |
-d homedir 指定賬戶的主目錄 |
2 |
-g groupname 為該賬戶指定一個組賬戶 |
3 |
-m 如果不存在,則建立主目錄 |
4 |
-s shell 指定此賬戶的預設shell |
5 |
-u userid 您可以為該賬戶指定使用者ID |
6 |
accountname 要建立的實際賬戶名 |
如果不指定任何引數,則系統使用預設值。useradd命令修改/etc/passwd、/etc/shadow和/etc/group檔案,並建立一個主目錄。
以下示例建立了一個名為mcmohd的賬戶,將其主目錄設定為/home/mcmohd,並將組設定為developers。此使用者將被分配Korn Shell。
$ useradd -d /home/mcmohd -g developers -s /bin/ksh mcmohd
在發出上述命令之前,請確保您已使用groupadd命令建立了developers組。
建立賬戶後,您可以使用passwd命令設定其密碼,如下所示:
$ passwd mcmohd20 Changing password for user mcmohd20. New UNIX password: Retype new UNIX password: passwd: all authentication tokens updated successfully.
當您鍵入passwd accountname時,它會為您提供更改密碼的選項,前提是您是超級使用者。否則,您可以使用相同的命令更改您的密碼,但無需指定您的賬戶名。
修改賬戶
usermod命令允許您從命令列對現有賬戶進行更改。它使用與useradd命令相同的引數,以及-l引數,該引數允許您更改賬戶名。
例如,要將賬戶名mcmohd更改為mcmohd20並相應地更改主目錄,您需要發出以下命令:
$ usermod -d /home/mcmohd20 -m -l mcmohd mcmohd20
刪除賬戶
userdel命令可用於刪除現有使用者。如果使用不當,這是一個非常危險的命令。
該命令只有一個引數或選項.r,用於刪除賬戶的主目錄和郵件檔案。
例如,要刪除賬戶mcmohd20,請發出以下命令:
$ userdel -r mcmohd20
如果您想保留主目錄以備備份,請省略-r選項。您可以根據需要在以後刪除主目錄。
Unix - 系統性能
本章將詳細討論 Unix 中的系統性能。
我們將向您介紹一些可用於監控和管理 Unix 系統性能的免費工具。這些工具還提供了有關如何在 Unix 環境中診斷和解決效能問題的指南。
Unix 有以下主要資源型別需要監控和調整:
CPU
記憶體
磁碟空間
通訊線路
I/O時間
網路時間
應用程式
效能元件
下表列出了佔用系統時間的五個主要元件:
序號 | 元件和描述 |
---|---|
1 |
使用者態CPU CPU實際花費在使用者態執行使用者程式的時間。它包括花費在執行庫呼叫上的時間,但不包括代表其在核心中花費的時間。 |
2 |
系統態CPU 這是CPU代表此程式在系統態花費的時間。所有I/O例程都需要核心服務。程式設計師可以透過阻塞I/O傳輸來影響此值。 |
3 |
I/O時間和網路時間 這是花費在移動資料和服務I/O請求上的時間。 |
4 |
虛擬記憶體效能 這包括上下文切換和交換。 |
5 |
應用程式 花費在執行其他程式上的時間 - 當系統未服務此應用程式,因為另一個應用程式當前擁有CPU時。 |
效能工具
Unix 提供以下重要工具來衡量和微調 Unix 系統性能:
序號 | 命令和說明 |
---|---|
1 |
nice/renice 以修改後的排程優先順序執行程式 |
2 |
netstat 列印網路連線、路由表、介面統計資訊、偽裝連線和多播成員資格 |
3 |
time 幫助計時簡單的命令或提供資源使用情況 |
4 |
uptime 這是系統負載平均值 |
5 |
ps 報告當前程序的快照 |
6 |
vmstat 報告虛擬記憶體統計資訊 |
7 |
gprof 顯示呼叫圖配置檔案資料 |
8 |
prof 促進程序分析 |
9 |
top 顯示系統任務 |
您可以使用手冊頁幫助檢查此處提到的每個命令的完整語法。
Unix - 系統日誌記錄
本章將詳細討論 Unix 中的系統日誌記錄。
Unix 系統具有非常靈活且強大的日誌記錄系統,它使您能夠記錄幾乎所有您可以想象的內容,然後操縱日誌以檢索您所需的資訊。
許多版本的 Unix 提供了一個名為syslog的通用日誌記錄工具。需要記錄資訊的各個程式將資訊傳送到 syslog。
Unix syslog 是一個可由主機配置的統一系統日誌記錄工具。系統使用一個集中的系統日誌記錄程序,該程序執行程式/etc/syslogd或/etc/syslog。
系統記錄器的操作非常簡單。程式將其日誌條目傳送到syslogd,syslogd會查閱配置檔案/etc/syslogd.conf或/etc/syslog,並在找到匹配項時將日誌訊息寫入所需的日誌檔案。
有四個基本的 syslog 術語您應該瞭解:
序號 | 術語和描述 |
---|---|
1 |
工具 用於描述提交日誌訊息的應用程式或程序的識別符號。例如,郵件、核心和 ftp。 |
2 |
優先順序 訊息重要性的指示器。級別在 syslog 中定義為指南,從除錯資訊到關鍵事件。 |
3 |
選擇器 一個或多個工具和級別的組合。當傳入事件與選擇器匹配時,將執行一個操作。 |
4 |
操作 對與選擇器匹配的傳入訊息執行的操作 - 操作可以將訊息寫入日誌檔案、將訊息回顯到控制檯或其他裝置、將訊息寫入已登入的使用者或將訊息傳送到另一個 syslog 伺服器。 |
Syslog 工具
現在我們將瞭解 syslog 工具。以下是選擇器可用的工具。並非所有工具都存在於所有版本的 Unix 上。
工具 | 描述 |
---|---|
1 |
auth 與請求名稱和密碼相關的活動(getty、su、login) |
2 |
authpriv 與auth相同,但記錄到只能由選定使用者讀取的檔案中 |
3 |
console 用於捕獲通常定向到系統控制檯的訊息 |
4 |
cron 來自 cron 系統排程程式的訊息 |
5 |
daemon 系統守護程序通用 |
6 |
ftp 與 ftp 守護程序相關的訊息 |
7 |
kern 核心訊息 |
8 |
local0.local7 每個站點定義的本地工具 |
9 |
lpr 來自行列印系統的訊息 |
10 |
與郵件系統相關的訊息 |
11 |
mark 用於在日誌檔案中生成時間戳的偽事件 |
12 |
新聞 與網路新聞協議 (nntp) 相關的訊息 |
13 |
ntp 與網路時間協議相關的訊息 |
14 |
使用者 常規使用者程序 |
15 |
uucp UUCP 子系統 |
Syslog 優先順序
syslog 優先順序在以下表格中進行了總結:
序號 | 優先順序 & 描述 |
---|---|
1 |
emerg 緊急情況,例如即將發生的系統崩潰,通常廣播給所有使用者 |
2 |
alert 應該立即糾正的情況,例如損壞的系統資料庫 |
3 |
crit 嚴重情況,例如硬體錯誤 |
4 |
err 普通錯誤 |
5 |
警告 警告 |
6 |
notice 不是錯誤的情況,但可能應該以特殊方式處理 |
7 |
info 資訊訊息 |
8 |
debug 除錯程式時使用的訊息 |
9 |
none 用於指定不記錄訊息的偽級別 |
設施和級別的組合使您能夠明智地選擇要記錄的內容以及資訊儲存的位置。
每個程式都盡職地將其訊息傳送到系統日誌記錄器,日誌記錄器根據選擇器中定義的級別決定要跟蹤哪些內容以及要丟棄哪些內容。
指定級別後,系統將跟蹤該級別及其以上的所有內容。
/etc/syslog.conf 檔案
/etc/syslog.conf 檔案控制訊息記錄的位置。一個典型的 syslog.conf 檔案可能如下所示:
*.err;kern.debug;auth.notice /dev/console daemon,auth.notice /var/log/messages lpr.info /var/log/lpr.log mail.* /var/log/mail.log ftp.* /var/log/ftp.log auth.* @prep.ai.mit.edu auth.* root,amrood netinfo.err /var/log/netinfo.log install.* /var/log/install.log *.emerg * *.alert |program_name mark.* /dev/console
該檔案的每一行包含兩部分:
一個訊息選擇器,用於指定要記錄的訊息型別。例如,核心的所有錯誤訊息或所有除錯訊息。
一個操作欄位,用於說明如何處理該訊息。例如,將其放入檔案中或將訊息傳送到使用者的終端。
以下是上述配置的要點:
訊息選擇器有兩部分:設施和優先順序。例如,kern.debug 選擇核心(設施)生成的所有除錯訊息(優先順序)。
訊息選擇器 kern.debug 選擇所有大於除錯的優先順序。
設施或優先順序位置的星號表示“全部”。例如,*.debug 表示所有除錯訊息,而 kern.* 表示核心生成的所有訊息。
您還可以使用逗號指定多個設施。可以使用分號將兩個或多個選擇器組合在一起。
日誌記錄操作
操作欄位指定以下五種操作之一:
將訊息記錄到檔案或裝置。例如,/var/log/lpr.log 或 /dev/console。
將訊息傳送給使用者。您可以透過逗號分隔多個使用者名稱來指定它們;例如,root, amrood。
將訊息傳送給所有使用者。在這種情況下,操作欄位由星號組成;例如,*。
將訊息傳遞給程式。在這種情況下,程式在 Unix 管道符號(|)之後指定。
將訊息傳送到另一臺主機上的 syslog。在這種情況下,操作欄位由一個主機名組成,前面帶有 at 符號;例如,@tutorialspoint.com。
logger 命令
Unix 提供了 logger 命令,這是一個處理系統日誌記錄的極其有用的命令。logger 命令將日誌訊息傳送到 syslogd 守護程序,從而引發系統日誌記錄。
這意味著我們可以在任何時候從命令列檢查 syslogd 守護程序及其配置。logger 命令提供了一種方法,可以從命令列將單行條目新增到系統日誌檔案中。
命令格式如下:
logger [-i] [-f file] [-p priority] [-t tag] [message]...
以下是引數的詳細資訊:
序號 | 選項 & 描述 |
---|---|
1 |
-f filename 使用檔案 filename 的內容作為要記錄的訊息。 |
2 |
-i 將 logger 程序的程序 ID 與每一行一起記錄。 |
3 |
-p priority 以指定的優先順序(指定的選取器條目)輸入訊息;訊息優先順序可以以數字形式指定,也可以以 facility.priority 對的形式指定。預設優先順序為 user.notice。 |
4 |
-t tag 使用指定的標籤標記新增到日誌中的每一行。 |
5 |
message 其內容按指定的順序連線在一起的字串引數,並用空格分隔。 |
您可以使用手冊頁幫助來檢查此命令的完整語法。
日誌輪換
日誌檔案具有增長非常快並消耗大量磁碟空間的傾向。為了啟用日誌輪換,大多數發行版都使用 newsyslog 或 logrotate 等工具。
應使用 cron 守護程序在頻繁的時間間隔內呼叫這些工具。有關更多詳細資訊,請檢視 newsyslog 或 logrotate 的手冊頁。
重要的日誌位置
所有系統應用程式都在 /var/log 及其子目錄中建立其日誌檔案。以下是幾個重要的應用程式及其相應的日誌目錄:
應用程式 | 目錄 |
---|---|
httpd | /var/log/httpd |
samba | /var/log/samba |
cron | /var/log/ |
/var/log/ | |
mysql | /var/log/ |
Unix - 訊號和陷阱
在本章中,我們將詳細討論 Unix 中的訊號和陷阱。
訊號是傳送到程式的軟體中斷,用於指示發生了重要事件。事件可以從使用者請求到非法記憶體訪問錯誤不等。某些訊號(例如中斷訊號)指示使用者已要求程式執行不屬於正常控制流的操作。
下表列出了您可能遇到並希望在程式中使用的常見訊號:
訊號名稱 | 訊號編號 | 描述 |
---|---|---|
SIGHUP | 1 | 在控制終端上檢測到結束通話或控制程序死亡 |
SIGINT | 2 | 如果使用者傳送中斷訊號 (Ctrl + C),則發出此訊號 |
SIGQUIT | 3 | 如果使用者傳送退出訊號 (Ctrl + D),則發出此訊號 |
SIGFPE | 8 | 如果嘗試進行非法數學運算,則發出此訊號 |
SIGKILL | 9 | 如果程序收到此訊號,則必須立即退出,並且不會執行任何清理操作 |
SIGALRM | 14 | 鬧鐘訊號(用於計時器) |
SIGTERM | 15 | 軟體終止訊號(預設情況下由 kill 傳送) |
訊號列表
有一種簡單的方法可以列出系統支援的所有訊號。只需發出 kill -l 命令,它就會顯示所有支援的訊號:
$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
訊號的實際列表在 Solaris、HP-UX 和 Linux 之間有所不同。
預設操作
每個訊號都與其關聯的預設操作。訊號的預設操作是指令碼或程式在收到訊號時執行的操作。
一些可能的預設操作包括:
終止程序。
忽略訊號。
轉儲核心。這會建立一個名為 core 的檔案,其中包含程序在收到訊號時的記憶體映像。
停止程序。
繼續停止的程序。
傳送訊號
有多種方法可以將訊號傳遞到程式或指令碼。最常見的一種方法是使用者在指令碼執行期間鍵入 CONTROL-C 或 INTERRUPT 鍵。
當您按下 Ctrl+C 鍵時,會將 SIGINT 傳送到指令碼,並且根據定義的預設操作,指令碼將終止。
傳遞訊號的另一種常見方法是使用 kill 命令,其語法如下:
$ kill -signal pid
此處 signal 是要傳遞的訊號的編號或名稱,pid 是要傳送訊號到的程序 ID。例如:
$ kill -1 1001
上述命令將 HUP 或結束通話訊號傳送到以 程序 ID 1001 執行的程式。要向同一程序傳送 kill 訊號,請使用以下命令:
$ kill -9 1001
這將殺死以 程序 ID 1001 執行的程序。
捕獲訊號
當您在 shell 程式執行期間在終端上按下 Ctrl+C 或 Break 鍵時,通常該程式會立即終止,並且您的命令提示符會返回。這可能並不總是理想的。例如,您最終可能會留下一些不會被清理的臨時檔案。
捕獲這些訊號非常容易,並且 trap 命令具有以下語法:
$ trap commands signals
此處 command 可以是任何有效的 Unix 命令,甚至可以是使用者定義的函式,而 signal 可以是您要捕獲的任意數量的訊號的列表。
shell 指令碼中 trap 有兩種常見用途:
- 清理臨時檔案
- 忽略訊號
清理臨時檔案
以下示例顯示瞭如何刪除一些檔案,然後在有人嘗試從終端中止程式時退出,以此作為 trap 命令的示例:
$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2
從執行此 trap 的 shell 程式中的這一點開始,如果程式收到訊號編號 2,則會自動刪除 work1$$ 和 dataout$$ 這兩個檔案。
因此,如果使用者在此 trap 執行後中斷程式的執行,則可以確保這兩個檔案將被清理。rm 之後的 exit 命令是必要的,因為如果沒有它,執行將在程式中從收到訊號時中斷的點繼續。
訊號編號 1 是為 結束通話 生成的。要麼有人故意結束通話線路,要麼線路意外斷開連線。
您可以修改前面的 trap,以便在這種情況下也刪除這兩個指定的的,方法是將訊號編號 1 新增到訊號列表中:
$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2
現在,如果線路結束通話或按下 Ctrl+C 鍵,則會刪除這些檔案。
指定要捕獲的命令必須用引號括起來,如果它們包含多個命令。另請注意,shell 在執行 trap 命令時以及收到列出的訊號之一時都會掃描命令列。
因此,在前面的示例中,WORKDIR 和 $$ 的值將在執行 trap 命令時替換。如果您希望此替換在收到訊號 1 或 2 時發生,則可以將命令放在單引號中:
$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
忽略訊號
如果為 trap 命令列出的命令為空,則在接收到指定訊號時將忽略該訊號。例如,命令 −
$ trap '' 2
這指定要忽略中斷訊號。在執行不想被打斷的操作時,您可能希望忽略某些訊號。您可以按如下方式指定要忽略的多個訊號 −
$ trap '' 1 2 3 15
請注意,必須指定第一個引數才能忽略訊號,並且它與編寫以下內容不相同,後者具有其自身的單獨含義 −
$ trap 2
如果您忽略了一個訊號,所有子 shell 也都會忽略該訊號。但是,如果您指定在收到訊號時要採取的操作,所有子 shell 在收到該訊號時仍將採取預設操作。
重置陷阱
在您將收到訊號時要採取的預設操作更改為其他操作後,您可以使用 trap 再次將其更改回,如果您只是省略第一個引數;所以 −
$ trap 1 2
這將收到訊號 1 或 2 時要採取的操作重置為預設值。