第三章 UNIX 系統入門

3.1 第一次登入系統

安裝完 FreeBSD 後,重新開機,要知道的第一件事就是要怎麼使用嘛。我第一次使用 FreeBSD 時,一開機看到 login: 時我當場呆在那裡,完全不知如何下手。所以我一定要說一下這個,如何登入並更改密碼。說了一堆好像很難的樣子,其實不會啦,開機後看到 login: 時,打 root 就可以登入系統了,如圖 3-1。

圖 3-1

這裡的 root 就是所謂的超級使用者,這個使用者是 UNIX 系統中的預設管理者名稱。root 擁有系統所有權限,我們可以使用這個帳號登入系統進行管理。root 這個使用者擁有許多一般使用者所沒有的權限,建議您平常使用時最好不要以 root 登入。例如收發 email,程式開發、瀏覽網頁、練習 UNIX 指令等,應該以一般使用者的身份來進行。因為您可能不小心打了某個指令而刪除不該被刪除的檔案、或因為不良的操作而影響系統的穩定。因此,在我們設定完系統後,您應該新增一個一般使用者以減少錯誤的發生。
由於這是剛裝好的系統,所以當我們以 root 登入時,系統不會問我們密碼。一個沒有密碼保護的系統是十分危險的事,所以我們第一件要做的事就是設定 root 的密碼。請執行指令 passwd 來設定您的密碼,系統會問您二次新密碼,以確認二次輸入的密碼相同。請不要使用太簡單的密碼,以免造成安全的漏洞。

3.2 基本指令介紹

在開始使用之前,我們先說明一些簡單的指令用法,以利後續的設定,更詳情的指令介紹請參考本書第二十章「指令應用」,或使用指令 man 來查詢指令的用法。如果您是 UNIX 初學者,先閱讀「指令應用」可以讓您對 UNIX 指令及系統管理有更多的了解。

指令 說明
cd 改變所在位置,和 DOS 中的用法類似,如果要到 /etc 下,就打 cd /etc
pwd 直接打就會顯示目前所在目錄的名稱。
ls 看目錄中的檔案清單。打 lsls /etc,就像 DOS 中的 dir。
w 查詢目前在線上的使用者。
ee 文書編輯軟體。
date 看目前的日期及時間。
mkdir 建立一個目錄,mkdir abc 就可以建立一個目錄叫 abc 。
rm 刪除檔案或目錄。刪除檔案時 rm file.txt,刪除目錄時要加參數 -rf , 如 rm -rf abc
cp 複製檔案,就像 DOS 中的 copy。cp file newfile。
man 查詢線上使用手冊,如 man cp 就可以看到 cp 這個指令的詳細說明。
su 從一般使用者變成超級使用者即 root。

還有一個您一定要知道的小秘訣,當您要 cd 到一個目錄時,您可以只打檔名的一部份,再按 [Tab] 鍵,tcsh 會自動幫您補上剩餘的部份。例如,我們要切換工作目錄 (使用 cd 這個指令) 到 /usr/local,當你打了 cd /usr/lo 時,即可按 [Tab] 鍵,只要在 /usr 中,除了 local 外沒有其它開頭為 lo 的檔案或目錄,tcsh 便會自動補齊成 cd /usr/local。除了 cd 外,其他的指令也是一樣,只要按 [Tab] 即可自動補齊。而且除了檔案及目錄外,指令也可以自動補齊喔。例如,你要下指令 ifconfig,您可以只打 ifc 再按 Tab 鍵,tcsh 會自動補成 ifconfig。如果您只打 if 即按 Tab 鍵,您會發現並沒有任何動作,因為在系統中,除了 ifconfig 外,還有指令開頭也是 if,如 ifmcstat。

3.3 文書編輯器

因為許多系統設定都必須修改設定檔,而修改設定檔必須使用文書編輯軟體,所以在開始所有設定之前,讓我們先來了解文書編輯器的用法。

我們將介紹 FreeBSD 內附的二套文書編輯軟體 ee 及 vi。這二套軟體都是在命令列模式下使用的軟體,ee 是一套比較適合初學者的編輯器,它的使用方式和我們一般的使用習慣較接近,操作簡單又容易上手。不過 ee 是 FreeBSD 特有的編輯軟體,在其它的 UNIX 系統中無法使用。因此,我們也將介紹另一套所有 UNIX 系統都內附的編輯器 vi。

vi 是一套威力強大的工具,操作熟練的人會覺得如有神助,而對於初學者而言卻是望之卻步。是否要將 vi 練到出神入化見人見智,但對於一個 UNIX 系統管理者而言,我們至少要知道一些基本的操作方式。

3.3.1 ee

ee 是 FreeBSD 系統內附較適合初學者的文書編輯軟體,它是 Easy Editor 的簡稱,顧名思義 ee 使用上十分容易。當您要編輯檔案 example.txt 時,只要在命令列上打 ee example.txt 即可。執行 ee 之後將會出現下列畫面:

圖 3-2

在畫面最上方有使用說明,幾乎我們所有的會使用到的功能都在最上方的說明中。您可以使用上下左右鍵來移動遊標,並直接輸入內容,以下為 ee 的指令說明,請注意我們將鍵盤上獨立的按鍵以小於及大於的符號括起來,例如 <Ctrl> 表示鍵盤上 Ctrl 這個鍵:

按鍵 意義
<Ctrl> + [ 或 <ESC> 鍵 顯示主選單。
<Ctrl> + o 輸入 ASCII code,例如輸入 65 就會顯示 A。
<Ctrl> + u 跳到檔案結尾。
<Ctrl> + t 跳到檔案開頭。
<Ctrl> + c 輸入指令。在按了 Ctrl+c 後,上方選單會出現命令說明,例如您可以直接輸入數字,表示將游標移到某一行。
<Ctrl> + y 搜尋。按了 Ctrl+y 之後,你可以輸入欲搜尋的字串。如果要搜尋下一個該字串,只要再按 Ctrl+x 即可。預設的搜尋是不分大小寫的,如果要區分大小寫,您可以按 Ctrl+c 並輸入 case 即可。如果要取消只要再按 Ctrl+c 並輸入 nocase。
<Ctrl> + a 跳到行首。
<Ctrl> + e 跳到行尾。
<Ctrl> + d 刪除游標所在位置的字元。
<Ctrl> + j 貼上上一次所刪除的字元。
<Ctrl> + k 刪除游標所在位置的一整行。
<Ctrl> + l 貼上上一次刪除的一整行內容。
<Ctrl> + w 刪除一個字。
<Ctrl> + r 貼上上一次所刪除的字。
<Ctrl> + p 將游標移到上一行。
<Ctrl> + n 將游標移到下一行。
<Ctrl> + b 將游標移到上一個字,和方向鍵左鍵一樣。
<Ctrl> + f 將游標移到下一個字,和方向鍵右鍵一樣。
<Ctrl> + g 下一頁。
<Ctrl> + v 上一頁。
<Ctrl> + z 移到下一個字。
<Esc> + <Enter> 離開 ee。如果檔案有修改過,它會問您是否要儲存檔案。

當我們按了 <Esc> 鍵時,會出現一個主選單,在選單中我們可以進行一些設定,如果您儲存這些設定,它會被存在您的 home 目錄下的 .init.ee,以 root 為例,設定檔會存放在 /root/.init.ee。如果您要還原預設值,只需將該檔刪除即可。

3.3.2 vi

Vi 是一個歷史悠久且功能強大的 UNIX 文書編輯器。在古早的年代,許多鍵盤都只有一些基本按鍵,連上下左右鍵都沒有,所以 vi 大多數的功能都必須使用一些特殊的按鍵。

Vi 在使用時可以分成二種模式,一種是「編輯模式」,另一種則為「命令模式」。在編輯模式時,我們可以使用上下左右鍵來移動游標並編輯輸入我們所要編輯的文字內容。而命令模式時,我們可以進行檔案操作 (開檔、存檔等)、搜尋等功能。使用 vi 時,我們會很常按 <Esc> 鍵,<Esc> 鍵可以讓我們離開編輯模式並進入命令模式。請執行 vi example.txt 來編輯 example.txt 這個檔案,一進入 vi 時,預設會處於命令模式,我們必需先輸入 "o"、"i"、或"a"才能進入編輯模式。

以下即為進入編輯模式的指令:

按鍵 意義
i Insert (插入),在目前游標前開始輸入。
a Append (附加),在目前游標後開始輸入。
o 在游標下方新增一空白行並開始編輯。
O 在游標上方新增一空白行並開始編輯。

如果您輸入錯誤,您無法使用 <Delete> 或 <Backspace> 來刪除,我們必須使用 vi 的其它命令來進行。請先按 <Esc> 來進入命令模式,接著您就可以使用下列指令來進行進階編輯:

按鍵 意義
x 刪除游標所在位置的字元。
dw 刪除游標所在到字尾,即刪除一個字。
dd 刪除游標所在一整行。
d + 數字 + <Enter> 刪除從游標所在位置到其下方 n 行。例如輸入 d5 <Enter>,將刪除游標所在位置起 6 行。
yw 複製游標開始到字尾。
yy 複製游標所在一整行。
y + 數字 + <Enter> 複製從游標所在位置到其下方 n 行。例如輸入 y4 <Enter>,將複製游標所在位置起 5 行。
p 貼上上一次複製的內容。
:w <Enter> 存檔。
:w 檔案名稱 <Enter> 另存新檔。您必輸在 w 後輸入新的檔名。
:q <Enter> 離開 vi。如果檔案有修改過會無法離開。
:wq <Enter> 存檔並離開。
:q! <Enter> 不存檔並離開。

接下來我們說明一下如何在檔案中穿梭移動:

按鍵 意義
h 游標向左移。
j 游標向下移。
k 游標向上移。
l 游標向右移。
^ 跳到行首。
$ 跳到行尾。
w 游標跳到下個字的開頭。
e 游標跳到下個字的結尾。
b 游標跳到上個字的開頭
<Ctrl> + d 游標往下移動半個螢幕。
<Ctrl> + u 游標往上移動半個螢幕。
<Ctrl> + f 游標往上移動一個螢幕。
<Ctrl> + b 游標往下移動一個螢幕。
:數字 <Enter> 跳到 n 行,例如輸入 :100 即可將游標移到第 100 行。
/欲搜尋的字串 <Enter> 輸入 / 後,您可以在 / 後輸入所要搜尋的字串,如果要找下一個,則直接按 / <Enter> 即可。

只要您熟悉了上列指令,您大概就可以很輕鬆的使用 vi 了。Vi 還有許多功能,你可以 man vi 來獲得更多資訊。

3.4 Shell 環境簡介

在 UNIX 系統中,使用者對於系統的操作是透過 "Shell",Shell 就好像是 DOS 中的 command.com 或 Windows 中的 explorer.exe。Shell 在接收到指令之後,會將它轉換成機器可以讀的語法來對系統進入操作。

FreeBSD 內附的 Shell 有 sh、csh、tcsh,sh 名為 Bourne Shell,它是 UNIX 系統中最悠久的 shell,所有的 UNIX 系統都會內附這個 shell,我們在寫 shell scripts 時為了可移植性,大多使用 sh。在 FreeBSD 中 csh 和 tcsh 是一樣的東西,csh 名稱的由來是因為它的 scripts 語法和 C 語言很像。至於要使用哪一種 shell 全憑個人偏好,您也可以自行從 ports 中安裝 Linux 用的 bash 或 ksh。

以筆者個人而言,我偏好使用 tcsh,它除了有 3.2 節中提及的使用 <Tab> 鍵自動完成檔名外,最重要的一點是它會自動搜尋上一次輸入的指令 (history-search-backward)。

例如,我們輸入下列指令:

# ls /usr/port/www
# cd /usr/port/www
# cd /usr

在輸入上述指令後,現在我們如果使用鍵盤方向鍵按上,將出現上一次所輸入的指令內容。如果我們先打了 ls 再按方向鍵上,則 tcsh 會自動找出最近輸入過開頭為 ls 的指令,多按幾次上它還會繼續出現上上一次輸入過的 ls 指令,很棒吧。

如果您想變更自己所使用的 Shell,可以執行下列指令:

# # chsh -s /bin/tcsh

上述指令中,我們將所使用的 Shell 變更成 /bin/tcsh。請注意,您所輸入的 shell 名稱一定要存在於 /etc/shells 這個檔中。系統預設的 shell 有 /bin/sh/bin/csh/bin/tcsh。 如果想使用自行安裝的 shell,您必須先將該 shell 的路徑加入 /etc/shells 中才可以使用。

3.4.1 Shell 的環境變數

在 Shell 有所謂的環境變數,當我們在 shell 中執行指令時,這些環境變數可能會被該程式用來判斷程式所要執行時的參數。例如,我們在執行 cal 這個指令時,我們不必打它的絕對路徑 /usr/bin/cal,因為 shell 會自動依照 PATH 這個環境變數所設定的路徑去找我們所輸入的指令。您可以使用下列指令來看目前 PATH 這個變數的內容:

# echo $PATH
/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin

如果您使用 tcsh,您也可以打 setenv 來看目前所有的環境變數。以下為一些常用的環境變數:

變數名稱 描述
USER 目前所使用的使用者名稱。
PATH 執行指令所要搜尋的位置,以冒號隔開。
SHELL 目前所使用的 Shell。
TERM 目前所使用的終端機模式。
OSTYPE 作業系統名稱。
MACHTYPE 系統所使用的 CPU 架構。
PAGER 當需要分頁時,所要使用的分頁軟體,如 more 或 less。
EDITOR 預設所要使用的編輯器。

您也可以使用 setenv 來改變一個環境變數的值。例如,我們要將預設的文書編輯器改成 ee,在 tcsh 中可以使用:

# setenv EDITOR ee

如果您使用的是 Bourne Shell:

# export EDITOR="ee"

3.4.2 Tcsh 的環境設定

登入系統後,您會發現在游標之前有一個井字號 "#",這個井字號我們稱之為提示符號 (prompt)。在 tcsh 及 csh 中,當以 root 登入時,預設的提示符號是 "#",而以一般使用者登入時,提示符號為 "%"。

FreeBSD 安裝好後,我們必須做一些設定讓 FreeBSD 使用起來更順手。在預設的況狀下,系統並不支援中文檔名,對於使用中文的人不太方便。另外,命令列提示符號的樣子也不符合我們的需求。如果你想要客製化一些指令,也可以在這裡加上去。所以在開始進行其它設定之前,我們先建立一個良好的使用環境。

在使用者登入後,Tcsh 會先去讀取 /etc/csh.cshrc/etc/csh.login 的設定,接著會讀取該使用者家目錄下的 .cshrc 及 .login。因此,我們可以經由設定這幾個檔案讓設定使用者一登入時就生效。

首先編輯 /etc/csh.cshrc 加入下列設定:

setenv EDITOR ee
alias ls ls -F
set prompt = "%B%m [%~] -%n-> "

第一行設定是將預設的文書編輯器改成 ee。第二行是要將指令 ls 變成 ls -F,就是每次打 ls 時,系統會出現 ls -F 的效果。而第三行是將命令列的提示符號改成下面這樣:

mydomain [/home/john] -john->

就是開頭是機器名稱,再來是路徑名稱,最後是使用者名稱。

由於在 /etc 下的 csh.cshrc 是通用的設定,但如果使用者自己的設定和通用設定一樣時,會以使用者的設定為主。例如,在一般使用者的家目錄下的 .cshrc 也有一行編輯器的設定,當設定不同時,會以使用者目錄下的設定為主。因此,我們必須再編輯 ~/.cshrc,並找到setenv EDITOR vi 換成 setenv EDITOR ee 設定才會生效。

如果您希望日後每個新增的使用者的設定都是這樣,則必須修改 /usr/share/skel/dot.cshrc 檔案,該檔內容的修改和修改 ~/.cshrc 一樣,把 vi 換成 ee ,並加入 alias ls ls -F。因為在使用 adduser 指令新增使用者時,它會問你是否要將 /usr/share/skel/dot.file 複製到使用者目錄下,因此我們就修改這裡,讓日後新增使用者時能使用該設定。

/etc/csh.cshrc/etc/csh.login 的差別在於如果是使用者登入,二個檔案都會被執行,如果是 scripts 則只會去讀取 csh.cshrc。我們接下來要讓使用者登入後可以支援中文的 console 環境,所以我們編輯 /etc/csh.login 並在最後面加入以下的設定:

setenv ENABLE_STARTUP_LOCALE zh_TW.Big5
# 若是使用遠端登入時,才能打出中文
# 4.x 請設定為 is_IS.ISO_8859-1,5.x 為 is_IS.ISO8859-1
setenv LC_CTYPE is_IS.ISO8859-1
# 若是console下用,才能打出中文
setenv LANG zh_TW.Big5

上述的環境變數設定會在使用者登入時自動被載入,一些程式 (例如 date) 會自動讀取這些變數,並產生中文的訊息。不過由於我們的 console 尚未支援中文,我們必須先安裝中文終端機軟體,或在支援中文的 PC 上使用 telnet 登入。別急,我們會在下面幾節中說明如何安裝中文終端機。

3.5 FreeBSD 的目錄結構

在 Windows 作業系統中,在檔案總管中可以看到 Windows 的 "樹狀" 目錄結構。而 FreeBSD 中的目錄也是像一顆樹,一個目錄下還有很多個目錄,和 Windows 不同的是在 UNIX 系統中每一個目錄都有一定用途。我們了解 FreeBSD 目錄結構的用意就是讓我們知道每個目錄的用途,日後我們要安裝新軟體或使用 FreeBSD 時,能按照這種規則來做,這樣一來在管理維護上比較方便,目錄也會比較有條理。

以下我們就簡單的說明 FreeBSD 的目錄結構,您也可以使用指令 man hier 來查看目錄結構說明。

目錄名稱 說明
/ UINX 系統的根目錄,是目錄的最上層。
/bin/ 放置基本的使用者指令,是開機時必備的。
/boot/ 系統開機時必需用到的設定。
/dev/ UNIX 系統將週邊設備視為檔案來管理,這個目錄就是放置裝置節點檔 (device node)。在 FreeBSD 5.0 以前 /dev/MAKEDEV 可以使用管理這些節點檔的工具。5.0 以後這些 device node 都改由 devfs 來管理。
/etc/ 放置系統的設定檔,例如使用者密碼、群組等。
/etc/defaults/ 放置預設的系統設定檔。請 man rc。
/etc/gnats/ gnats 的設定檔,請 man send-pr。
/etc/isdn/ isdn 的設定檔,請 man isdnd。
/etc/kerberosIV/ kerberos version IV 的設定檔,請 man kerberos。
/etc/mail/ Sendmail 的設定檔。
/etc/mtree/ 目錄權限的設定檔,請 man mtree。
/etc/namedb/ DNS 伺服器的設定檔,請 man named。
/etc/periodic/ 每天、每週、每月定時要執行的設定,請 man periodic。
/etc/ppp/ ppp 的設定檔,請 man ppp。
/etc/ssl/ OpenSSL 的設定檔。
/kernel 開機時系統會載入的核心 (kernel)。在 FreeBSD 5.x 中,kernel 這個檔已被放在 /boot 目錄中。
/modules/ Kernel 可以載入的模組,請 man kldstat。在 FreeBSD 5.x 中, 這個目錄已被放在 /boot 目錄中。
/mnt/ 空目錄,我們可以用它來作為暫時 mount 檔案系統。
/proc/ 系統執行中程序 (process) 資料,請 man procfs mount_procfs。
/root/ 超級使用者 root 的家目錄。
/sbin/ 系統程序及管理工具的目錄。
/stand/ 這是安裝磁片上的指令。
/tmp/ 暫存目錄,許多程式都會需要暫存目錄來存放資料。開機時會清除。
/usr/ 包含主要的使用者工具及應用軟體。您可以把它看成 Windows 中的 windows 目錄及 program file 目錄的集合。
/usr/bin/ 一般的使用者指令及應用軟體。
/usr/games/ 一些小游戲。
/usr/include/ 標準 C 語言的標頭檔。
/usr/lib/ 系統函式庫。
/usr/libdata/ 一些系統工具的資料庫。
/usr/libexec/ 系統服務程式 (daemons) 及工具。
/usr/local/ 非 FreeBSD 所附的軟體都會安裝在這個目錄下,我們在安裝軟體時最好都安裝在這個目錄。您可以將它視為 Windows 作業系統中的 program file 目錄。這個目錄中也有 bin sbin etc lib 等目錄。
/usr/obj/ 在編譯 FreeBSD 系統時存放過程中暫存檔的位置。
/usr/ports/ FreeBSD ports 移植軟體的原始程式目錄,我們可以從這個目錄中找到自己想要的軟體來快速安裝。
/usr/sbin/ 可以讓使用者執行的系統服務及工具。
/usr/share/ 系統軟體共享的資料庫。
/usr/src/ 放置 BSD 或其他軟體原始程式碼的目錄。
/usr/X11R6/ X Windows 的目錄。
/var/ 放置系統記錄檔、暫存檔的目錄。
/var/account/ 使用者執行過的指令記錄檔,請 man acct。
/var/at/ 定時執行排程的資料檔。請 man at。
/var/backups/ 系統重要檔案的備份區。
/var/cron/ 使用者排程的資料表,請 man cron。
/var/db/ 重要的系統資料庫。
/var/games/ 內附的遊戲紀錄檔。
/var/log/ 系統記錄檔,我們可以在這裡查看系統狀況記錄。
/var/mail/ 使用者信件暫存區。
/var/preserve/ 文件編輯時異常中止時,會將文件存到這個目錄,請 man ex。
/var/msgs/ 系統訊系的資料庫,請 man msgs。
/var/quotas/ 檔案系統使用容量限制的記錄。
/var/run/ 記錄系統開機後執行狀態的暫存區。請 man utmp。
/var/spool/ 列表機或郵件輸出時的緩衝區。
/var/tmp/ 系統暫存區,開機時不會清除。
/var/yp/ the NIS maps。

3.6 使用者及權限管理

由於 FreeBSD 和所有的 UNIX 系統一樣,在設定上都是為了支援多個使用者的環境,所以在使用者管理上必須考量到多個使用者同時使用時所會造成的影響。例如使用者 A 不可以刪除使用者 B 的資料,某些使用者可以存取某些資料夾,某些則否。為了讓系統管理更有效率,在支援多人使用的作業系統中,都有群組及權限的觀念。

在 UNIX 系統中,每個使用者「至少」會屬於一個群組,我們可以針對不同使用者或不同群組來設定他們在系統中的使用權限。例如,我們有一個使用者名為「豬小弟」,他的群組是「小豬」,我們讓小豬群組可以進入豬圈這個資料夾。同時由於豬小弟生病了,需要吃藥,所以我們將它加入「病豬」群組,所有病豬都可以吃特別的飼料,其他健康的豬隻則禁止存取。如此一來,我們就不必一隻一隻去設定每隻豬及每個資料夾的權限,下次新增一個特別飼料時,只要設定只有病豬可以存取即可。

所以我們在新增使用者時,必須指定他的群組,預設的群組是一個和使用者同名的新群組,我們先來看看新增使用者的過程,請使用指令 adduser 來新增使用者。系統會問您一些問題:

# adduser
Username: jack

執行了 adduser 之後,首先要輸入使用者名稱,使用者名稱除了英文字、數字及 -_ 外不可以包含其他特殊字元。

Full name: Jack

接著我們要輸入使用者全名,這個欄位可以是空的,如果您不輸入則直接按 Enter 即可。

Uid (Leave empty for default):	

這個欄位是使用者編號,直接留白按 Enter 即可,系統會自動指定。

Login group [jack]:

輸入使用者群組名稱,群組名稱預設會自動產生一個和新增的使用者同名的群組,如果要使用不同的群組,必須先手動新增群組。我們直接按 Enter 即可。

Login group is jack. Invite jack into other groups? []: wheel

是否要將新的使用者加入其它群組,由於這是我們新增的第一個一般使用者,所以我們將它加入系統管理者 wheel 這個群組,讓他可以使用 su 這個指令來切換身份成 root。

Login class [default]:

登入的類別,這是用來分類控制使用者對於系統資源的使用,請參考第五章系統資源限制的說明。在這裡我們直接按 Enter 使用預設值即可。

Shell (sh csh tcsh nologin) [sh]: tcsh

輸入所要使用的 Shell,建議輸入 tcsh,如果您不想讓該使用者登入系統,可以輸入 nologin。

Home directory [/home/jack]:

輸入使用者的家目錄,也就是使用者在系統中的資料夾,所有使用者的目錄我們都放在 /home 下,所以我們直接按 Enter 即可。

Use password-based authentication? [yes]:

是否要使用密碼認証的方式,預設為是,我們直接按 Enter 即可。

Use an empty password? (yes/no) [no]:

是否要使用空密碼,預設為否。

Use a random password? (yes/no) [no]:

是否使用隨機產生的密碼,如果使用隨機產生的密碼,在新增完畢後,系統會告知我們產生的密碼,預設為否。

Enter password:

輸入該使用者的密碼。

Enter password again:

再輸入一次密碼,以確認輸入無誤。

Lock out the account after creation? [no]:

在新增完使用者後,是否要先將該帳戶關閉。

最後會顯示我們剛才輸入的結果:

Username : jack
Password : *****
Full Name : Jack
Uid : 1003
Class :
Groups : jack
Home : /home/jack
Shell : /bin/tcsh
Locked : no
OK? (yes/no): y

如果全部 ok 則輸入 y。

adduser: INFO: Successfully added (jack) to the user database.
Add another user? (yes/no): n
Goodbye!

最後系統會詢問我們是否要新增另一個使用者,如果沒有則按 n 離開。

新增完使用者後,我們可以看到 /home 目錄下多了一個使用者 jack 的目錄:

# ls -la /home
drwxr-xr-x  10 root    wheel      512  3 21 16:12 ./
drwxr-xr-x  21 root    wheel      512  1 14 06:29 ../
drwxr-xr-x  13 jack    jack      1024  3 21 16:05 jack/

"." 及 ".." 這二個目錄分別代表著目前所在的目錄及上一層目錄,我們可以看到它的擁有者是 root,群組是 wheel。而 jack 這個目錄的目錄的擁有者是 jack,其群組也是 jack。

在 ls 結果的第一個欄位表著該檔案或目錄的存取權限,該欄位共有十個字元,第一個字元表示檔案的類型,以 jack 這個目錄為例,它的類型是目錄,所以第一個字是 d,如果是一般的檔案,則第一個字是 - 。接下來的九個字元,以三個為單位,分別代表著使用者 (User)、群組 (Group)、及其他人 (Others) 的權限:

我們看到 jack 這個目錄,它的權限是 rwxr-xr-x,前三個字 rwx 表示使用者 jack 對於這個目錄有讀取、寫入及進入目錄的權限;接下來的 r-x 表示 jack 群組可以讀取及進入該目錄,但無法寫入資料;最後三個 r-x 表示其他使用者可以讀取、進入該目錄。

使用者的權限除了可以使用 rwx 來表示外,我們也可以使用數字來設定權限。假設檔案擁有者的權限為 rwx,由於 r 代表的數字是 4、w 是 2、x 是 1,所以檔案擁有者的權限就是 4+2+1,也就是 7。同理,如果群組的權限是 r-x,則數字表示為 4+0+1,也就是 5。如果我們要將權限設成 rwxr-xr--,則數字就是 754,如下圖所示:

圖 3-3

假設我們要更改檔案 file.txt 的權限為 rwxr-xr-- (754),我們可以使用 chmod 這個指令:

# chmod 754 file.txt

我們上面提及的權限都是以三位數字來表示,另外我們也可以使用四位數字表示。所謂的四位數字是指在原本的三位數之前加上一個關於檔案形態的設定。

假設我們要設定檔案 myfile 可以被所有人讀、寫、執行,並設定 sticky:

# chmod 1777 myfile

除了使用數字一次設定權限之外,我們也可以分別針對檔案的使用者、群組及其他人來設定權限。chmod 這個指令在權限的參數部份,除了使用數字外,也可以使用 (對誰)(做什麼動作)(權限) 這種語法。

項目 使用的字元 代表意義
對誰 u 使用者 (User)
對誰 g 群組 (Group)
對誰 o 其他人 (Others)
對誰 a 所有人 (All)
做什麼動作 + 增加權限
做什麼動作 - 移除權限
做什麼動作 = 直接設定權限
權限 r 讀取
權限 w 寫入
權限 x 執行
權限 t Sticky
權限 s Set UID 或 GID

例如,我們要設定其他人對檔案 file.txt 只有讀取及執行的權利:

# chmod o=rx file.txt

更多 chmod 的用法,請參考第二十章指令應用。

3.7 系統服務及行程管理

FreeBSD 和其他常用的作業系統一樣都是多工的環境,我們可以同時執行數個工作,例如同時聽音樂、開瀏覽器上網。在系統一開機後,便會自動執行許多程式來維持系統的正常運作。這些正在執行的程式我們稱之為行程 (process)。

3.7.1 行程

每一個行程都有一個與眾不同的編號,稱之為 process id (PID)。所有正在執行中的程式都需要使用到一些系統資源,例如記憶體、CPU 等等,PID 的做用就是讓系統可以根據這一個獨特的編號來做資源的調配及工作排程。當我們在進行管理這些程式時,也必須要依照 PID 來區分不同的行程。

幾乎所有的行程都是由其它程式所呼叫執行的,這個呼叫、執行一個新的行程的人是該行程的 parent。例如當我們執行了 ls 時,ls 這個行程的 parent 就是我們當時所使用的 shell。唯沒有 parent 的例外是 init 這支程式。當 FreeBSD 開機執行完系統核心程式之後,會自動執行 init 這支程式,由於這是開機後所執行的第一支程式,所以它的 PID 是 1。init 執行之後,會再呼叫其它程式,例如 /etc/rc 來啟動開機必須執行的系統設定等。

每一個行程和檔案、目錄一樣,都有行程的擁有者及群組。程式執行之後,可能必須要開啟某些檔案或對於系統裝置進行存取,而使用這些資源時,即是以該行程的擁有者及群組的身份進行存取。

我們可以使用 ps 這支程式來取得行程的資訊,以下即為 ps 指令的輸出結果:

# ps
PID    TT  STAT   TIME      COMMAND
77393  p0  ILs    0:00.02   login [pam] (login)
78056  p0  IL     0:00.02   su
78057  p0  SL     0:00.02   _su (tcsh)
78074  p0  RL+    0:00.00   ps
89678  v0  ILs+   0:00.01   /usr/libexec/getty Pc ttyv0
78073  v1  SLs+   0:00.01   /usr/libexec/getty Pc ttyv1
 616   v2  ILs+   0:00.00   /usr/libexec/getty Pc ttyv2
 617   v3  ILs+   0:00.00   /usr/libexec/getty Pc ttyv3
 618   v4  ILs+   0:00.00   /usr/libexec/getty Pc ttyv4
 619   v5  ILs+   0:00.00   /usr/libexec/getty Pc ttyv5
 620   v6  ILs+   0:00.00   /usr/libexec/getty Pc ttyv6
 621   v7  ILs+   0:00.00   /usr/libexec/getty Pc ttyv7

我們可以看到第一個欄位是 PID,它的範圍從 1 到 99999,當用完了 99999 後,系統會自動從頭開始找一個沒人用的 PID 來使用。TT 這個欄位是我們正在使用的 tty,如果是在 console 前執行的執令,則 tty 為 ttyvX,如果是 telnet 到系統中,則 tty 為 ttypX。STAT 欄位為目前該程式的狀態。TIME 則是該程式所使用的 CPU 時間。最後的欄位 COMMAND 則是該程式被執行時所下的指令。

除了 ps 之外,我們也可以使用 top 來查看所有行程的狀態:

# top
last pid: 78151;  load averages:  1.11, 1.04, 1.01   up 27+14:45:03  18:02:07
51 processes:  3 running, 48 sleeping
CPU states:  0.2% user, 96.8% nice, 1.5% system, 1.5% interrupt, 0.0% idle
Mem: 114M Active, 45M Inact, 64M Wired, 12M Cache, 34M Buf, 7952K Free
Swap: 512M Total, 372K Used, 512M Free

 PID USERNAME  PRI NICE   SIZE    RES STATE    TIME   WCPU    CPU COMMAND
235  root      96    0  1616K  1044K select 114:50  0.05%  0.05%  natd
425  root      96    0  9644K  4836K select   2:02  0.00%  0.00%  httpd
4872 root      96    0  3900K  2048K select   1:40  0.00%  0.00%  top
470  root      96    0  3776K  2240K select   1:39  0.00%  0.00%  sendmail
290  root      96    0  1312K   764K select   0:30  0.00%  0.00%  syslogd
490  root       8    0  1336K   864K nanslp   0:17  0.00%  0.00%  cron    
    

top 這個指令會每二秒自動更新一次。我們可以看到 top 的輸出分成二個部份,最上方是目前關於行程的的系統狀態。包含最後一個 PID (last pid)、系統負荷 (load average) 、已開機時間 (up)、總共有多少行程正在執行中、及 CPU 和記憶體的使用量等等。第二個部份和 ps 一樣,列出 PID、行程的擁有者、及其他和行程相關的狀態。其它更多關於 ps 及 top 的用法,請參考第二十章指令應用。

3.7.2 系統服務及行程管理

我們每執行一個指令,都會產生一個新的行程,有的程式在執行完畢後,就會結束離開;而有的程式會常駐在系統中。例如當我們執行 ls 這個指令時,會產生一個新的行程,在該指令列出了目錄或檔案資訊後,便會立即結束。而像網頁伺服器所執行的 httpd 這類的程式,會一直常駐在系統中,隨時等候連線的要求,這種常駐的程式稱之為 daemon。

Daemon 這個字是由希臘神話而來,Daemon 是一隻會跟隨在主人身邊的小惡魔,它是個調皮的小東西,會幫人類做一些有用的事。不過它本身並沒有善惡之分,也可能會做出不好的事情,全看人類本身。

FreeBSD 系統內附的 daemon 在命名上大都依循一定的規則,例如 FTP daemon 所執行的程式是 ftpd,而負責 telnet 服務的 daemon 叫做 telnetd,大到上就是在該服務的名字後面加上一個 "d" 結尾。其它非 FreeBSD 內附的程式大都有類似的規則,像 Apahce 這種網路伺服器的主要執行程式為 httpd。但也有例外的程式,例如系統中的郵件伺服器 Sendamil,它的執行檔是 sendmail 而非 smtpd 或 maild。

通常 daemon 在執行後,會將自己的 PID 以副檔名為 .pid 的檔案寫在 /var/run 目錄下,例如 /var/run/syslogd.pid/var/run/cron.pid。 該檔案的內容為該 daemon 的 PID,可以讓我們直接看該檔案而得知該程式的編號。

有時候我們可能會需要和正在執行中的 daemon 溝通。例如當我們修改了 /etc/syslog.conf 這個 syslogd 所使用的設定檔時,我們必須告訴它這個檔被修改過了,請重新讀取。和 daemon 溝通的方式就是傳送給它一個信號 (signal),程式在收到信號後,會依照信號的類別做不同的事。以上述要求 syslogd 重新讀取設定檔為例,我們會送給它一個 SIGHUP 的信號。

除了 SIGHUP 外,如果我們想要終止一個程式的執行,可以傳送 SIGTERM 或 SIGKILL 的信號。SIGTERM 表示通知正在執行中的程式我們希望它中止執行,如果該程式中有接收 SIGTERM 的機制,它可以做一些離開前的處理,例如關閉所開啟的檔案、結束某些正在執行的動作等等。然而,收到 SIGTERM 的程式也可以選擇忽視,但 SIGKILL 則是不管程式是否在忙著其它事情,都必須中即停止,而且這個信號是不可以被忽視的。所有的信號都可以使用數字來表示,例如 SIGHUP 可以使用數字 1 表示、SIGTERM 為 15、SIGKILL 為 9。

系統中傳送信號的指令是 kill 這個指令,假設我們要送一個 SIGHUP 的信號給 PID 為 199 的程式,我們可以使用下列指令:

# kill -HUP 199

上述指令中的參數 -HUP 也可以使用 -1 來取代。

值得注意的是,只有超級使用者 root 可以送信號給不屬於自己的行程,而一般使用者只能管理自己的行程。

3.7.3 基本系統服務 inetd

在系統中有一個專門負責各式網路服務的超級伺服器 "inetd"。 我們可以經由修改設定檔請它負責許多網路相關的服務,例如 telnet、ftp、ssh 等。當有 telnet 連線要求時,inetd 會依照設定執行負責 telnet 服務的 telnetd 這支程式,再將主導權轉手給 telnetd,並繼續等待下一個連線要求。若下一個連線是 ftp,則 inetd 會呼叫 ftpd 這支程式來負責。

其實像 ftpd 這類的程式,它本身也可以自己成為一支 daemon,由自己等待 ftp 的連線要求,而無需經由 inetd。使用 inetd 來管理這些網路服務的好處是我們不必為了提供十種網路服務而執行十個常駐程式。每一個常駐程式都會佔用一些系統資源,而使用一個 inetd 來統籌,可以讓這些資源空出來。另外,inetd 也可以用來過濾連線來源,針對不同的連線,我們可以使用 inetd 內建的 TCP Wrapper 功能來進行連線網域的限制,相關設定我們會再後續章節中提及。

有優點就會有缺點,使用 inetd 來管理網路服務固然有其優點,但對於連線較頻繁、需要更快反應的服務而言並不合適。以 FTP 為例,一個連線進來,inetd 都必須重新執行一次 ftpd。如果我們是以 daemon 的方式,讓 ftpd 常駐於系統中,則當有連線要求時,我們就可以直接將自己複製一份出來進行 ftp 服務,而不需重頭執行。所以對於一台大型的 FTP 伺服器而言,通常會使用獨立 daemon 的方式。而一些較少使用的服務,如 telnet、ssh 等就交由 inetd 來處理。

FreeBSD 預設並不會啟動 inetd,所以如果我們想要讓它在一開機就執行,必須在 /etc/rc.conf 中加入下列設定:

inetd_enable="YES"

假設我們想要讓 inetd 負表 telnet 及 ftp 服務,我們必須修改 /etc/inetd.conf ,將 telnet 及 ftp 前的 "#" 拿掉,如下所示:

# $FreeBSD: src/etc/inetd.conf,v 1.63 2003/06/09 21:04:30 markm Exp $
#
# Internet server configuration database
#
# Define *both* IPv4 and IPv6 entries for dual-stack support.
# To disable a service, comment it out by prefixing the line with '#'.
# To enable a service, remove the '#' at the beginning of the line.
#
ftp     stream  tcp     nowait  root    /usr/libexec/ftpd       ftpd -l
ftp     stream  tcp6    nowait  root    /usr/libexec/ftpd       ftpd -l
#ssh    stream  tcp     nowait  root    /usr/sbin/sshd          sshd -i -4
#ssh    stream  tcp6    nowait  root    /usr/sbin/sshd          sshd -i -6
telnet  stream  tcp     nowait  root    /usr/libexec/telnetd    telnetd
telnet  stream  tcp6    nowait  root    /usr/libexec/telnetd    telnetd
#shell  stream  tcp     nowait  root    /usr/libexec/rshd       rshd
#shell  stream  tcp6    nowait  root    /usr/libexec/rshd       rshd
#login  stream  tcp     nowait  root    /usr/libexec/rlogind    rlogind
#login  stream  tcp6    nowait  root    /usr/libexec/rlogind    rlogind
#finger stream  tcp     nowait/3/10 nobody /usr/libexec/fingerd fingerd -s
#finger stream  tcp6    nowait/3/10 nobody /usr/libexec/fingerd fingerd -s
#exec   stream  tcp     nowait  root    /usr/libexec/rexecd     rexecd
  

接著,再使用下列指令來啟動 inetd 服務:

# /usr/sbin/inetd -wW

如果 inetd 已經被啟動了,而我們修改過 inetd.conf 必須要求 inetd 重新讀取設定檔:

# kill -HUP `cat /var/run/inetd.pid`

請注意這裡 `cat /var/run/inetd.pid` 所使用的 ` 是鍵盤左上角的那一個符號,而非單引號。不過我們建議您使用 ssh 連線以取代 telnet,因為 ssh 是以加密過的方式連線,比較不會以明碼的方式傳送資料。您可以使用 putty 這個軟體在 MS windows 下連線到 FreeBSD 中。您可以從 http://www.chiark.greenend.org.uk/~sgtatham/putty/ 下載 putty,也可以在本書光碟二的 wintools 目錄下找到該軟體。

當然,您也可以在FreeBSD中使用 ssh 的方式連到別台機器,FreeBSD 中內建有 ssh 軟體,你可以使用下列指令:

# ssh jack@123.123.78.9

這個指令表示以使用者 jack 身份連線到 123.123.78.9,我們也可以使用主機名稱的方式,例如jack@dns.abc.edu.tw ,或者也可以只打 ssh dns.abc.edu.tw 來登入,此時登入名稱會是您現在用的使用者名稱。

如果所連線的站台是第一次使用 SSH連線,則會出現下列一堆東西,表示接收到所連線站台RSA key,並詢問您是否要繼續連接。此時打 "yes" 三個字即可:

The authenticity of host '123.456.78.9' can't be established.
RSA key fingerprint is 13:96:8a:61:31:cf:32:3f:7a:0a:77:ad:7e:49:e7:3f.
Are you sure you want to continue connecting (yes/no)?  yes

系統會將所接收到的金鑰 (key) 存放在使用者家目錄下的 .ssh/known_hosts 檔案中。如果日後在 known_hosts 目錄中所記錄的站台金鑰有變更時,我們可以編輯該檔案以刪除舊的金鑰。

設定到這裡後,就可以不必在機器前作業了。通常我的習慣是設定到這個地方後,就使用 telnet 或 ssh 的方式經由其它電腦連線到機器來作其他的設定,這樣我就不必一定要待在機器前,可以在自己家中使用別的機器連線到 FreeBSD 中做設定。不過要注意的是 root 帳號預設是不能使用遠端登入,如果您想使用遠端登入並擁有 root 的權限,您必須先使用一般的使用者登入後,再執行 su 這個指令來切換身份成為 root,而且這個使用者必須加入 wheel 群組中。假設您在新增使用者時並未將該使用加入 wheel 群組,您可以手動編輯 /etc/group 來加入該使用者。例如我們要讓一般使用者 alex 擁有 su 成為 root 的權限:

wheel:*:0:root,alex

3.8 虛擬終端機

大多數的時候,我們都是在命令列模式 (文字模式) 下執行系統管理的工作,命令列模式相較於圖形模式而言,所使用的系統資源較少,同時也是一般 UNIX 最常使用的模式。

在系統一開機後,螢幕上會出現類似下列畫面:

Fri Mar 20 14:05:16 CST 2004
FreeBSD/i386 (example.com) (ttyv0)
login:

我們看到第二行的部份有一個 ttyv0,ttyv0 所代表的是編號為 0的系統 console 終端機。我們在該機器面前所使用的螢幕中文字模式的畫面就叫做 console,我們可以在 console 下執行許多指令。FreeBSD 一開機後就會建立讓多虛擬的 console 終端機機,我們可以同時開機多個 console 畫面同時進行操作。您可以使用 ALT+F2、ALT+F3、…直到 ALT+F8 來切換不同的 console 畫面。當您使用 ALT+2 時,您會看到前面所提及的 login 畫面,而畫面上有一個 ttyv1 的字樣。如果您要切換回 ttyv0 只要按 ALT+F1 即可。

當我們使用 telnet 或 ssh 進入系統時,我們所看到的虛擬終端機是 ttyp0、ttyp1 等等。關於各種 tty 權限的設定被記錄在 /etc/ttys 這個檔案中。

console none                            unknown off secure
#
ttyv0   "/usr/libexec/getty Pc"         cons25  on  secure
# Virtual terminals
ttyv1   "/usr/libexec/getty Pc"         cons25  on  secure
ttyv2   "/usr/libexec/getty Pc"         cons25  on  secure
ttyv3   "/usr/libexec/getty Pc"         cons25  on  secure
ttyv4   "/usr/libexec/getty Pc"         cons25  on  secure
ttyv5   "/usr/libexec/getty Pc"         cons25  on  secure
ttyv6   "/usr/libexec/getty Pc"         cons25  on  secure
ttyv7   "/usr/libexec/getty Pc"         cons25  on  secure
ttyv8   "/usr/X11R6/bin/xdm -nodaemon"  xterm   off secure
# Pseudo terminals
ttyp0   none                    network
ttyp1   none                    network
ttyp2   none                    network
……

這個檔案中設定了每一個不同的終端機類型可以使用的權限,例如 ttyv0 最後面都有一個 secure 的字樣,而 ttyp0 則無,表示 root 可以從 ttyv0 登入,但不可以從 ttyp0 登入,這也就是為什麼 telnet 進來時,不可以使用 root 登入的原因。如果您想讓 root 可以使用 telnet 登入,只要在 ttyp0、ttyp1 等?行加入 secure 即可,但我們並不建議做這樣的設定。更多關於 ttys 這個檔案的格式及其設定,請 man ttys。

3.8.1登入後的訊息

在您登入系統之後,螢幕會自動秀出一段文字,這段文字稱為 Message Of The Day(motd)。這一段文字是可以修改的,你可以編輯 /etc/motd 來製作自己的畫面。如果你想使用像 BBS 中的文書編輯軟體,來畫 ANSI 圖的話,你可以安裝 ve 這個軟體。

# cd /usr/ports/chinese/ve
# make install clean

再使用 ve /etc/motd 來修改訊息。例如筆者所使用的畫面如下:

圖 3-4

您可以在本書第二片光碟 /examples/etc/motd 找到筆者所使用的 motd 設定檔。

3.8.2 登入前的訊息

在登入系統前 FreeBSD 時,你會看到下面的畫面:

FreeBSD/i386 (example.com) (ttyv0)
login:

我們在這裡要做的就是把它改成想要的樣子。更改 login 前的畫面有二種方式,一種是修改 /etc/gettytab/etc/issue,另一種方式是修改 telnetd。

方式一:

編輯 /etc/gettytab,找到 default的地方。

default:\
:cb:ce:ck:lc:fd#1000:im=\r\n%s/%m (%h) (%t)\r\n\r\n:sp#1200:\ :if=/etc/issue:

其中的%s %m %h %t 分別對應到 FreeBSD i386 example.com ttyp0,如果你不想顯示 FreeBSD ,就把 %s 拿掉。最後一行 if=/etc/issue 就是表如果沒有 issue 這個檔的話,就執行 default。

如果你不僅僅是要修改 FreeBSD/i386 這個部份,還想要在 login 前秀出一段文字的話,你可以新增 /etc/issue 這個檔,並編輯你想要的畫面。和 motd 一樣,issue 也可以使用 ANSI 畫面,所以你可以用 ve 來編輯畫面。如果你在該檔中加入 %s %m %h %t 等參數的話,也是會出現 FreeBSD i386 example.com ttyp0等,如果不加就不會出現。

但由於 issue 這個檔只會在 console 登入時才有作用,如果您要在開機前的畫面中秀出更多的資料,您可以使用第二種方式。

方式二:

如果你想要在登入前執行一些指令,例如秀出開機時間等,必須要以更改 telnetd 的方式來做。首先,請編輯一個可執行檔 /usr/local/libexec/telnetd.sh 內容如下:

#!/bin/sh
TTY=`/usr/bin/tty | /usr/bin/cut -c9`

if [ "$TTY" = 'v' ]; then
    exec /usr/libexec/telnetd
else
    /bin/cat /etc/issue
    echo "顏色控制碼`/usr/bin/uptime`控制結束碼"
    exec /usr/libexec/telnetd
fi

上面控制碼部份,你可以使用 ve 來加入顏色控制碼,編輯完後要把該檔變成可執行的檔案,使用下列指令:

# chmod 755 /usr/local/libexec/telnetd.sh

再編輯 /etc/inetd.conf,將原來的 "/usr/libexec/telnetd telnetd" 換成 "/usr/local/libexec/telnetd.sh telnetd.sh":

telnet stream tcp nowait root /usr/libexec/telnetd.sh telnetd.sh

最後重跑 inetd,使用指令 kill -HUP `cat /var/run/inetd.pid` 即完成設定。

3.8.3 使用中文終端機

FreeBSD 的console 並無法顯示中文,如果我們要在 console 下使用中文的環境,則必須安裝 big5con 這套軟體才可以。怎麼安裝呢? 您可以將本書光碟二 /ports/distfiles 目錄中的所有檔案複製到 /usr/ports/distfiles 中,或是將光碟放入光碟機中,並使用指令 mount /cdrom 將光碟機 mount 進來。如此一來,在安裝軟體時,系統就不會要求連上網路取回所需檔案(有的檔案不能從CDROM 安裝,您必須至網路下載)。接著以root 的身份直接使用下列指令來安裝:

# cd /usr/ports/chinese/big5con
# make install clean

安裝完後,先執行 rehash 來更新一下 tcsh 指令的快取,之後我們就可以使用指令 b5c 來出現像 DOS 下倚天中文的環境,如圖 3-5。

圖3-5