当前位置: 澳门新濠3559 > 操作系统 > 正文

一定要先學會的指令,讀者們常常詢問使用USB直

时间:2019-11-09 19:31来源:操作系统
Linux 基本指令介紹 簡易 FTP Server 架設 -- WuFTP 本文已不再維護,更新文章請參考vsftpd的介紹 原文:     最近更新日期:2003/09/13 转自: 一定要先學會的指令:ls, more, cd, pwd, rpm, if

Linux 基本指令介紹

簡易 FTP Server 架設 -- Wu FTP
本文已不再維護,更新文章請參考 vsftpd的介紹

原文:

 

 

最近更新日期:2003/09/13

澳门新濠3559 1

转自:

一定要先學會的指令:ls, more, cd, pwd, rpm, ifconfig, find 
登入與登出(開機與關機):telnet, login, exit, shoudown, reboot 
Linux 多人多工與背景執行功能:& 與 [ctrl]+[z], fg, ps, kill 
檔案與目錄管理:cd, pwd, ls, cat, more, mkdir, rm, rmdir, mv, cp, ln, find, whereis, chmod, chown, chgrp, df, du 
磁碟與硬體管理:mount, fdformat, fdisk, mke2fs, mkbootdisk, badblocks, fsck, rpm 
系統管理員:su, clear, dmesg, groupadd, useradd, userconf, passwd, who, whoami, top, free, quotacheck, edquota 
壓縮指令:compress, gzip, tar 
一些網路功能:ifconfig, route, netstat, hostname, ping, nslookup,talk, traceroute, mail 
其他有的沒的:date, cal, grep 
ftp 指令:ftp, ncftp, gftp 
相關設定指令:set, uname, setup, lilo, Xconfigurator, xf86config 
X-Window內的設定指令:startx, netconf, netcfg, XF86Setup 
問題討論:增加新硬碟,增加新使用者,製作開機磁片, 

 

【首先謝謝「也是新手」讀者先幫忙回了這個問題】

在 Linux 的環境下,如果你不懂 bash 是什麼,那麼其他的東西就不用學了!因為前面幾章我們使用終端機下達指令的方式, 就是透過 bash 的環境來處理的喔!所以說,他很重要吧!bash 的東西非常的多,包括變數的設定與使用、 bash 操作環境的建置、資料流重導向的功能,還有那好用的管線命令!好好清一清腦門,準備用功去囉~ ^_^ 這個章節幾乎是所有指令列模式 (command line) 與未來主機維護與管理的重要基礎,一定要好好仔細的閱讀喔!


在 Internet 上面的傳輸協定當中, FTP ( File Transfer Protocol ) 算是一個最古老的協定之一了!早期還沒有這麼多好用的協定之前( 例如 SAMBA ),都是使用 FTP 來進行資料的傳遞的呢!另外,一般來說,資料的傳輸以 FTP 這個協定來傳送是相當的快速的,而且某些場合當中其實也相當的方便。不過,值得注意的是,使用 FTP 來傳輸時,其實是具有一定程度的『危險性』,因為資料在 Internet 上面是完全沒有受到保護的『明碼』機制!所以,其實鳥哥不太建議大家使用這個伺服器的啦!尤其當你建置好了 FTP 之後,如果經常進行資料的傳遞,對於您的網路頻寬『真的有很大的損害』啊!不過,無論如何, FTP 仍然有其存在的必要!例如中山大學的 FTP 站就作的相當的棒啊!所以,底下我們就來談一談用在這個古老的協定上面,最古老的伺服器之一: Wu FTP

先和大家說聲抱歉,一直忙新書上市的事,因此回文也慢,希望這周能慢慢恢復正常。讀者們常常詢問使用USB直接從Service Console備份Datastore中的問題,事實上在大部分的情況下是不建議的,但還是有這方面的需要,尤其是現在USB Flash的容量越來越大,能直接從Service Console下將資料備份到USB上,對中小型企業,ESX伺服器在身邊的環境來說的確很方便,比使用備份軟體,WinSCP等工具軟體來說的確也比較直觀,因此在這篇文章中,我們就來看看如何使用Service Console中,直接存取USB儲存設備的完整過程。

  • 10.1 認識 BASH 這個 Shell
    • 10.1.1 硬體、核心與 Shell
    • 10.1.2 為何要學文字介面的 shell
    • 10.1.3 系統的合法 shell 與 /etc/shells 功能
    • 10.1.4 Bash shell 的功能
    • 10.1.5 查詢指令是否為 Bash shell 的內建命令: type
    • 10.1.6 指令的下達與快速編輯按鈕
  • 10.2 Shell 的變數功能
    • 10.2.1 什麼是變數?
    • 10.2.2 變數的取用與設定:echo, 變數設定規則, unset
    • 10.2.3 環境變數的功能: env 與常見環境變數說明, set, export
    • 10.2.4 影響顯示結果的語系變數 (locale)
    • 10.2.5 變數的有效範圍
    • 10.2.6 變數鍵盤讀取、陣列與宣告: read, declare, array
    • 10.2.7 與檔案系統及程序的限制關係: ulimit
    • 10.2.8 變數內容的刪除、取代與替換 (Optional):, 刪除與取代, 測試與替換
  • 10.3 命令別名與歷史命令
    • 10.3.1 命令別名設定: alias, unalias
    • 10.3.2 歷史命令: history, HISTSIZE
  • 10.4 Bash shell 的操作環境
    • 10.4.1 路徑與指令搜尋順序
    • 10.4.2 bash 的進站與歡迎訊息: /etc/issue, /etc/motd
    • 10.4.3 環境設定檔: login, non-login shell, /etc/profile, ~/.bash_profile, source, ~/.bashrc
    • 10.4.4 終端機的環境設定: stty, set
    • 10.4.5 萬用字元與特殊符號
  • 10.5 資料流重導向 (Redirection)
    • 10.5.1 何謂資料流重導向?
    • 10.5.2 命令執行的判斷依據: ; , &&, ||
  • 10.6 管線命令 (pipe)
    • 10.6.1 擷取命令: cut, grep
    • 10.6.2 排序命令: sort, uniq, wc
    • 10.6.3 雙向重導向: tee
    • 10.6.4 字元轉換命令: tr, col, join, paste, expand
    • 10.6.5 分割命令: split
    • 10.6.6 參數代換: xargs
    • 10.6.7 關於減號 - 的用途
  • 10.7 重點回顧
  • 10.8 本章習題
  • 10.9 參考資料與延伸閱讀
  • 針對本文的建議:http://phorum.vbird.org/viewtopic.php?t=23884

特別說明:

 
原理:
  :FTP 的功能簡介
  :FTP 的運作流程與使用到的 Port
  :什麼是『被動, passive』的連線?
  :FTP 的替代方案與安全性問題
  :什麼時候才要設定 FTP 啊!開放誰人連進來?
套件安裝:
Server 端設定:
  :Wu FTP 的結構
  :最簡單的 ftpaccess 設定檔
  :使用 Super daemon 管理 FTP 的情況
  :歡迎畫面的建立、 Readme 檔案與關閉 FTP 訊息內容
  :限制最大線上人數
  :限制與取消使用者的家目錄規範
  :時間相關的設定項目
  :流量與上傳下載總量的限制項目
  :創造 guest user 與 guest user 的家目錄問題
  :anonymous 的根目錄與建立可上傳目錄
  :針對人物(real, guest, anonymous)的限制設定項目
  :拒絕某些使用者與開放某些使用者的登入(/etc/ftphosts, deny-uid, allow-uid)
  :目錄與連結檔的問題
  :建立 passive port 提供 client 端登入
  :修改 FTP 預設的 port 21 的連線
  :一個多樣化的實例
Client 端的使用 FTP 軟體:
  :ftp
  :ncftp
Server 端的安全設定項目:
  :iptables
  :TCP_Wrappers
  :pam 模組與 /etc/ftpusers 的關係
  :FTP 本身提供的抵擋 username 或 host 的控制項目
重點回顧
參考資源
本章習題練習

 

10.1 認識 BASH 這個 Shell

我們在第一章 Linux 是什麼當中提到了: 管理整個電腦硬體的其實是作業系統的核心 (kernel),這個核心是需要被保護的! 所以我們一般使用者就只能透過 shell 來跟核心溝通,以讓核心達到我們所想要達到的工作。 那麼系統有多少 shell 可用呢?為什麼我們要使用 bash 啊?底下分別來談一談喔!

Top

先說明一下,基本上雖然 Linux 目前對於圖形界面的使用已經支援的相當的不錯,但是對於一些比較細微的設定方面,畢竟是比不上使用傳統的文字介面來的有效!並且,使用文字介面來設定對於瞭解 Linux 有一定的幫助,畢竟 Linux 與 MS 的咚咚是不太相同的!鳥哥特別建議大家使用文字介面來解決問題!

除此之外,使用文字介面登入 Linux 對於系統資源的損耗也比較少,相對的,就有比較多的資源可以做為網路的用途,進而增加 Linux 的效能。尤其,在我們這個網頁中,基本上是以一般被淘汰的 586 系列電腦做為主機,因此對於記憶體與 CPU 的效能要求並不高,所以能有效的減少系統資源的浪費就盡量的減少一些容易耗掉系統資源的廢物吧!

style="font-family: 宋体;">底下我們會分門別類的將各個比較常用的指令給搬上來,你可以參考一下。另外一個最重要的地方是,在 Linux 主機上,已經內建各個指令的說明內容了,而且是很詳細的線上說明,你可以使用:   

[root@tsai  root]#  man  command <=== command 為你欲查詢的指令名稱
[root@tsai  root]#  info  command 

在上表中,針對 command 這個指令你可以使用 man 或者是 info 來查詢他的功能與說明,例如你要查尋 ls 這個指令時,你可以輸入: man  ls 或  info  ls 來查詢一下!適當的利用線上查詢對於你的英文及相關的指令功能有一定程度的幫助喔!


在開始之前,我們先必須確定下面幾個步驟。

1、USB硬碟是能被ESX認識,並且可以寫入的。目前ESX能讀寫的檔案系統包括了Linux的ext以及Windows下的FAT32。如果你的硬碟是NTFS的話,可能就無法寫入(只能讀取),這就無法完成備份的要求了。

2、ESX有完整安裝,因為在安裝ESX時,必須安裝USB的驅動程式。只要你的ESX系統在安裝時沒有特別「不安裝」什麼,大部分的系統都可以執行。

10.1.1 硬體、核心與 Shell

一定要先學會的指令,讀者們常常詢問使用USB直接從Service。這應該是個蠻有趣的話題:『什麼是 Shell 』?相信只要摸過電腦,對於作業系統 (不論是 Linux 、 Unix 或者是 Windows) 有點概念的朋友們大多聽過這個名詞,因為只要有『作業系統』那麼就離不開 Shell 這個東西。不過,在討論 Shell 之前,我們先來瞭解一下電腦的運作狀況吧! 舉個例子來說:當你要電腦傳輸出來『音樂』的時候,你的電腦需要什麼東西呢?

  1. 硬體:當然就是需要你的硬體有『音效卡晶片』這個配備,否則怎麼會有聲音;
  2. 核心管理:作業系統的核心可以支援這個晶片組,當然還需要提供晶片的驅動程式囉;
  3. 應用程式:需要使用者 (就是你) 輸入發生聲音的指令囉!

這就是基本的一個輸出聲音所需要的步驟!也就是說,你必須要『輸入』一個指令之後, 『硬體』才會透過你下達的指令來工作!那麼硬體如何知道你下達的指令呢?那就是 kernel (核心) 的控制工作了!也就是說,我們必須要透過『 Shell 』將我們輸入的指令與 Kernel 溝通,好讓 Kernel 可以控制硬體來正確無誤的工作! 基本上,我們可以透過底下這張圖來說明一下:

澳门新濠3559 2

圖10.1.1、硬體、核心與使用者的相關性圖示

我們在第零章內的作業系統小節曾經提到過, 作業系統其實是一組軟體,由於這組軟體在控制整個硬體與管理系統的活動監測, 如果這組軟體能被使用者隨意的操作,若使用者應用不當,將會使得整個系統崩潰!因為作業系統管理的就是整個硬體功能嘛! 所以當然不能夠隨便被一些沒有管理能力的終端用戶隨意使用囉!

但是我們總是需要讓使用者操作系統的,所以就有了在作業系統上面發展的應用程式啦!使用者可以透過應用程式來指揮核心, 讓核心達成我們所需要的硬體任務!如果考慮如第零章所提供的作業系統圖示(圖0.4.2), 我們可以發現應用程式其實是在最外層,就如同雞蛋的外殼一樣,因此這個咚咚也就被稱呼為殼程式 (shell) 囉!

其實殼程式的功能只是提供使用者操作系統的一個介面,因此這個殼程式需要可以呼叫其他軟體才好。 我們在第四章到第九章提到過很多指令,包括 man, chmod, chown, vi, fdisk, mkfs 等等指令,這些指令都是獨立的應用程式, 但是我們可以透過殼程式 (就是指令列模式) 來操作這些應用程式,讓這些應用程式呼叫核心來運作所需的工作哩! 這樣對於殼程式是否有了一定的概念了?

Tips澳门新濠3559 3也就是說,只要能夠操作應用程式的介面都能夠稱為殼程式。狹義的殼程式指的是指令列方面的軟體,包括本章要介紹的 bash 等。 廣義的殼程式則包括圖形介面的軟體!因為圖形介面其實也能夠操作各種應用程式來呼叫核心工作啊! 不過在本章中,我們主要還是在使用 bash 啦!

Top


原理:File Transfer Protocol ( FTP )

接下來我們就來看看詳細步驟。

10.1.2 為何要學文字介面的 shell?

文字介面的 shell 是很不好學的,但是學了之後好處多多!所以, 在這裡鳥哥要先對您進行一些心理建設,先來瞭解一下為啥學習 shell 是有好處的,這樣你才會有信心繼續玩下去 ^_^

  • 文字介面的 shell:大家都一樣!

鳥哥常常聽到這個問題:『我幹嘛要學習 shell 呢? 不是已經有很多的工具可以提供我設定我的主機了?我為何要花這麼多時間去學指令呢?不是以 X Window 按一按幾個按鈕就可以搞定了嗎?』唉~還是得一再地強調, X Window 還有 Web 介面的設定工具例如 Webmin (註1) 是真的好用的傢伙, 他真的可以幫助我們很簡易的設定好我們的主機,甚至是一些很進階的設定都可以幫我們搞定。

但是鳥哥在前面的章節裡面也已經提到過相當多次了, X Window 與 web 介面的工具,他的介面雖然親善,功能雖然強大, 但畢竟他是將所有利用到的軟體都整合在一起的一組應用程式而已, 並非是一個完整的套件,所以某些時候當你升級或者是使用其他套件管理模組 (例如 tarball 而非 rpm 檔案等等) 時,就會造成設定的困擾了。甚至不同的 distribution 所設計的 X window 介面也都不相同,這樣也造成學習方面的困擾。

文字介面的 shell 就不同了!幾乎各家 distributions 使用的 bash 都是一樣的!如此一來, 你就能夠輕輕鬆鬆的轉換不同的 distributions ,就像武俠小說裡面提到的『一法通、萬法通!』

  • 遠端管理:文字介面就是比較快!

此外,Linux 的管理常常需要透過遠端連線,而連線時文字介面的傳輸速度一定比較快, 而且,較不容易出現斷線或者是資訊外流的問題,因此,shell 真的是得學習的一項工具。而且,他可以讓您更深入 Linux ,更瞭解他,而不是只會按一按滑鼠而已!所謂『天助自助者!』多摸一點文字模式的東西,會讓你與 Linux 更親近呢!

  • Linux 的任督二脈: shell 是也!

有些朋友也很可愛,常會說:『我學這麼多幹什麼? 又不常用,也用不到!』嘿嘿!有沒有聽過『書到用時方恨少?』 當你的主機一切安然無恙的時候,您當然會覺得好像學這麼多的東西一點幫助也沒有呀! 萬一,某一天真的不幸給他中標了,您該如何是好?是直接重新安裝? 還是先追蹤入侵來源後進行漏洞的修補?或者是乾脆就關站好了?這當然涉及很多的考量, 但就以鳥哥的觀點來看,多學一點總是好的,尤其我們可以有備而無患嘛!甚至學的不精也沒有關係,瞭解概念也就 OK 啦!畢竟沒有人要您一定要背這麼多的內容啦!瞭解概念就很了不起了!

此外,如果你真的有心想要將您的主機管理的好,那麼良好的 shell 程式編寫是一定需要的啦!就鳥哥自己來說,鳥哥管理的主機雖然還不算多, 只有區區不到十部,但是如果每部主機都要花上幾十分鐘來查閱他的登錄檔資訊以及相關的訊息, 那麼鳥哥可能會瘋掉!基本上,也太沒有效率了!這個時候,如果能夠藉由 shell 提供的資料流重導向以及管線命令,呵呵! 那麼鳥哥分析登錄資訊只要花費不到十分鐘就可以看完所有的主機之重要資訊了!相當的好用呢!

由於學習 shell 的好處真的是多多啦!所以,如果你是個系統管理員,或者有心想要管理系統的話,那麼 shell 與 shell scripts 這個東西真的有必要看一看!因為他就像『打通任督二脈,任何武功都能隨你應用』的說!

Top

登入與登出(開機與關機)

 

先設定ESX中的USB存取部分

10.1.3 系統的合法 shell 與 /etc/shells 功能

知道什麼是 Shell 之後,那麼我們來瞭解一下 Linux 使用的是哪一個 shell 呢?什麼!哪一個?難道說 shell 不就是『一個 shell 嗎?』哈哈!那可不!由於早年的 Unix 年代,發展者眾,所以由於 shell 依據發展者的不同就有許多的版本,例如常聽到的 Bourne SHell (sh) 、在 Sun 裡頭預設的 C SHell、 商業上常用的 K SHell、, 還有 TCSH 等等,每一種 Shell 都各有其特點。至於 Linux 使用的這一種版本就稱為『 Bourne Again SHell (簡稱 bash) 』,這個 Shell 是 Bourne Shell 的增強版本,也是基準於 GNU 的架構下發展出來的呦!

在介紹 shell 的優點之前,先來說一說 shell 的簡單歷史吧(註2):第一個流行的 shell 是由 Steven Bourne 發展出來的,為了紀念他所以就稱為 Bourne shell ,或直接簡稱為 sh !而後來另一個廣為流傳的 shell 是由柏克萊大學的 Bill Joy 設計依附於 BSD 版的 Unix 系統中的 shell ,這個 shell 的語法有點類似 C 語言,所以才得名為 C shell ,簡稱為 csh !由於在學術界 Sun 主機勢力相當的龐大,而 Sun 主要是 BSD 的分支之一,所以 C shell 也是另一個很重要而且流傳很廣的 shell 之一 。

Tips澳门新濠3559 4由於 Linux 為 C 程式語言撰寫的,很多程式設計師使用 C 來開發軟體,因此 C shell 相對的就很熱門了。 另外,還記得我們在第一章、Linux 是什麼提到的吧? Sun 公司的創始人就是 Bill Joy,而 BSD 最早就是 Bill Joy 發展出來的啊。

那麼目前我們的 Linux (以 CentOS 7.x 為例) 有多少我們可以使用的 shells 呢? 你可以檢查一下 /etc/shells 這個檔案,至少就有底下這幾個可以用的 shells (鳥哥省略了重複的 shell 了!包括 /bin/sh 等於 /usr/bin/sh 囉!):

  • /bin/sh (已經被 /bin/bash 所取代)
  • /bin/bash (就是 Linux 預設的 shell)
  • /bin/tcsh (整合 C Shell ,提供更多的功能)
  • /bin/csh (已經被 /bin/tcsh 所取代)

雖然各家 shell 的功能都差不多,但是在某些語法的下達方面則有所不同,因此建議你還是得要選擇某一種 shell 來熟悉一下較佳。 Linux 預設就是使用 bash ,所以最初你只要學會 bash 就非常了不起了! ^_^! 另外,咦!為什麼我們系統上合法的 shell 要寫入 /etc/shells 這個檔案啊? 這是因為系統某些服務在運作過程中,會去檢查使用者能夠使用的 shells ,而這些 shell 的查詢就是藉由 /etc/shells 這個檔案囉!

舉例來說,某些 FTP 網站會去檢查使用者的可用 shell ,而如果你不想要讓這些使用者使用 FTP 以外的主機資源時,可能會給予該使用者一些怪怪的 shell,讓使用者無法以其他服務登入主機。 這個時候,你就得將那些怪怪的 shell 寫到 /etc/shells 當中了。舉例來說,我們的 CentOS 7.x 的 /etc/shells 裡頭就有個 /sbin/nologin 檔案的存在,這個就是我們說的怪怪的 shell 囉~

那麼,再想一想,我這個使用者什麼時候可以取得 shell 來工作呢?還有, 我這個使用者預設會取得哪一個 shell 啊?還記得我們在第四章的在終端介面登入linux小節當中提到的登入動作吧? 當我登入的時候,系統就會給我一個 shell 讓我來工作了。 而這個登入取得的 shell 就記錄在 /etc/passwd 這個檔案內!這個檔案的內容是啥?

[dmtsai@study ~]$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
.....(底下省略).....

如上所示,在每一行的最後一個資料,就是你登入後可以取得的預設的 shell 啦!那你也會看到, root 是 /bin/bash ,不過,系統帳號 bin 與 daemon 等等,就使用那個怪怪的 /sbin/nologin 囉~關於使用者這部分的內容,我們留在第十三章的帳號管理時提供更多的說明。

Top

style="font-size: xx-small;">telnet

這套軟體在 Windows 及 Linux 系統中都存在,只是介面有點不很相同就是了。基本上,這個程式是 user 端用來連線登入遠端主機的。例如鳥哥人在台南,但是我可以在台南使用可以連上 Internet 的電腦,經由 telnet 連線上家裡的 Linux 主機,而進行設定!感覺上就好像在家裡玩自己的 Linux 主機一樣!一般來說,如果你是使用 Winodows 系統,則你可以在『開始』-->『執行』後,輸入  telnet  xxx.yyy.zzz.qqq ,其中, xxx.yyy.zzz.qqq 為 IP 位址,則可以連上主機(或者是 BBS )囉。當然,如果您是在 Linux 系統下,亦可直接輸入 telnet xxx.yyy.zzz.qqq 來連上主機或BBS喔!語法: telnet 主機位址(或主機名稱)

style="font-size: xx-small;">login

style="font-family: 宋体;">登入系統的指令,在遠端進入系統時,程式會自動執行。假設你所要登入的系統主機為 sun.os.test.com ,則你可以在 Windows 底下的 Telnet 軟體,或其他軟體上,執行: telnet  sun.os.test.com 則會出現如下的畫面:

SunOS  5.7

login:  username 
Password:

sun# _

style="font-size: xx-small;"> 你只要有 username 及 pass word 就可以登入系統啦!在你登入系統後, sun# 是提示字元,相當於古早的  C:> 的意思!

style="font-size: xx-small;">exit

這是離開 Linux 系統的指令,相當於 login out 的意思。

sun#  exit

style="font-size: xx-small;">shutdown

Linux 用來關機的指令,這個指令只有 root 才有權力下! shutdown 的用法如下:   

[root@tsai  root]#   shutdown  <==系統在兩分鐘後關機,並傳送訊息給在線上的人 
[root@tsai  root]#   shutdown  -h  now  <==系統立刻關機 
[root@tsai  root]#   shutdown  -r  now  <==系統立刻重新開機 
[root@tsai  root]#   shutdown  -h  20:30  <==系統在今天的 20:30 分關機 
[root@tsai  root]#   shutdown  -h  +10   <==系統在 10 分鐘後關機

style="font-size: xx-small;">reboot

style="font-family: 宋体;">這是鳥哥最常用來重新開機的指令(或關機),可以配合寫入緩衝資料的 sync 指令動作,如下:   

[root@tsai  root]# sync; sync; sync; reboot

 

首先我們進入ESX的Service Console,不管是使用SSH,直接到本機,或是使用Dell Perc之類的遠端遙控,重點是必須能使用指令。由於在安裝ESX時,系統會將大部分的空間給Datastore用,因此我們從fdisk中看到的,都是系統碟,目前是看不到USB硬碟的。我們在Service Console下輸入

10.1.4 Bash shell 的功能

既然 /bin/bash 是 Linux 預設的 shell ,那麼總是得瞭解一下這個玩意兒吧!bash 是 GNU 計畫中重要的工具軟體之一,目前也是 Linux distributions 的標準 shell 。 bash 主要相容於 sh ,並且依據一些使用者需求而加強的 shell 版本。不論你使用的是那個 distribution ,你都難逃需要學習 bash 的宿命啦!那麼這個 shell 有什麼好處,幹嘛 Linux 要使用他作為預設的 shell 呢? bash 主要的優點有底下幾個:

  • 命令編修能力 (history):

bash 的功能裡頭,鳥哥個人認為相當棒的一個就是『他能記憶使用過的指令!』 這功能真的相當的棒!因為我只要在指令列按『上下鍵』就可以找到前/後一個輸入的指令!而在很多 distribution 裡頭,預設的指令記憶功能可以到達 1000 個!也就是說,你曾經下達過的指令幾乎都被記錄下來了。

這麼多的指令記錄在哪裡呢?在你的家目錄內的 .bash_history 啦! 不過,需要留意的是,~/.bash_history 記錄的是前一次登入以前所執行過的指令, 而至於這一次登入所執行的指令都被暫存在記憶體中,當你成功的登出系統後,該指令記憶才會記錄到 .bash_history 當中!

這有什麼優點呢?最大的好處就是可以『查詢曾經做過的舉動!』 如此可以知道你的執行步驟,那麼就可以追蹤你曾下達過的指令,以作為除錯的重要流程! 但如此一來也有個煩惱,就是如果被駭客入侵了,那麼他只要翻你曾經執行過的指令, 剛好你的指令又跟系統有關 (例如直接輸入 MySQL 的密碼在指令列上面),那你的伺服器可就傷腦筋了! 到底記錄指令的數目越多還是越少越好?這部份是見仁見智啦,沒有一定的答案的。

  • 命令與檔案補全功能: ([tab] 按鍵的好處)

還記得我們在第四章內的重要的幾個熱鍵小節當中提到的 [tab] 這個按鍵嗎?這個按鍵的功能就是在 bash 裡頭才有的啦!常常在 bash 環境中使用 [tab] 是個很棒的習慣喔!因為至少可以讓你 1)少打很多字; 2)確定輸入的資料是正確的! 使用 [tab] 按鍵的時機依據 [tab] 接在指令後或參數後而有所不同。我們再複習一次:

  • [Tab] 接在一串指令的第一個字的後面,則為命令補全;
  • [Tab] 接在一串指令的第二個字以後時,則為『檔案補齊』!
  • 若安裝 bash-completion 軟體,則在某些指令後面使用 [tab] 按鍵時,可以進行『選項/參數的補齊』功能!

所以說,如果我想要知道我的環境當中所有以 c 為開頭的指令呢?就按下『 c[tab][tab] 』就好啦! ^_^! 是的!真的是很方便的功能,所以,有事沒事,在 bash shell 底下,多按幾次 [tab] 是一個不錯的習慣啦!

  • 命令別名設定功能: (alias)

假如我需要知道這個目錄底下的所有檔案 (包含隱藏檔) 及所有的檔案屬性,那麼我就必須要下達『 ls -al 』這樣的指令串,唉!真麻煩,有沒有更快的取代方式?呵呵!就使用命令別名呀!例如鳥哥最喜歡直接以 lm 這個自訂的命令來取代上面的命令,也就是說, lm 會等於 ls -al 這樣的一個功能,嘿!那麼要如何作呢?就使用 alias 即可!你可以在指令列輸入 alias 就可以知道目前的命令別名有哪些了!也可以直接下達命令來設定別名呦:

  • alias lm='ls -al'
  • 工作控制、前景背景控制: (job control, foreground, background)

這部分我們在第十六章 Linux 程序控制中再提及! 使用前、背景的控制可以讓工作進行的更為順利!至於工作控制(jobs)的用途則更廣, 可以讓我們隨時將工作丟到背景中執行!而不怕不小心使用了 [Ctrl] + c 來停掉該程序!真是好樣的!此外,也可以在單一登入的環境中,達到多工的目的呢!

  • 程式化腳本: (shell scripts)

在 DOS 年代還記得將一堆指令寫在一起的所謂的『批次檔』吧?在 Linux 底下的 shell scripts 則發揮更為強大的功能,可以將你平時管理系統常需要下達的連續指令寫成一個檔案, 該檔案並且可以透過對談互動式的方式來進行主機的偵測工作!也可以藉由 shell 提供的環境變數及相關指令來進行設計,哇!整個設計下來幾乎就是一個小型的程式語言了!該 scripts 的功能真的是超乎鳥哥的想像之外!以前在 DOS 底下需要程式語言才能寫的東西,在 Linux 底下使用簡單的 shell scripts 就可以幫你達成了!真的厲害!這部分我們在第十二章再來談!

  • 萬用字元: (Wildcard)

除了完整的字串之外, bash 還支援許多的萬用字元來幫助使用者查詢與指令下達。 舉例來說,想要知道 /usr/bin 底下有多少以 X 為開頭的檔案嗎?使用:『 ls -l /usr/bin/X* 』就能夠知道囉~此外,還有其他可供利用的萬用字元, 這些都能夠加快使用者的操作呢!

總之,bash 這麼好!不學嗎?怎麼可能!來學吧! ^_^

Top

Linux 多人多工與背景執行功能


fdisk -l

10.1.5 查詢指令是否為 Bash shell 的內建命令: type

我們在第四章提到關於 Linux 的線上說明文件部分,也就是 man page 的內容,那麼 bash 有沒有什麼說明文件啊?開玩笑~ 這麼棒的東西怎麼可能沒有說明文件!請你在 shell 的環境下,直接輸入 man bash 瞧一瞧, 嘿嘿!不是蓋的吧!讓你看個幾天幾夜也無法看完的 bash 說明文件,可是很詳盡的資料啊! ^_^

不過,在這個 bash 的 man page 當中,不知道你是否有察覺到,咦! 怎麼這個說明文件裡面有其他的檔案說明啊?舉例來說,那個 cd 指令的說明就在這個 man page 內? 然後我直接輸入 man cd 時,怎麼出現的畫面中,最上方竟然出現一堆指令的介紹?這是怎麼回事? 為了方便 shell 的操作,其實 bash 已經『內建』了很多指令了,例如上面提到的 cd , 還有例如 umask 等等的指令,都是內建在 bash 當中的呢!

那我怎麼知道這個指令是來自於外部指令(指的是其他非 bash 所提供的指令) 或是內建在 bash 當中的呢? 嘿嘿!利用 type 這個指令來觀察即可!舉例來說:

[dmtsai@study ~]$ type [-tpa] name
選項與參數:
    :不加任何選項與參數時,type 會顯示出 name 是外部指令還是 bash 內建指令
-t  :當加入 -t 參數時,type 會將 name 以底下這些字眼顯示出他的意義:
      file    :表示為外部指令;
      alias   :表示該指令為命令別名所設定的名稱;
      builtin :表示該指令為 bash 內建的指令功能;
-p  :如果後面接的 name 為外部指令時,才會顯示完整檔名;
-a  :會由 PATH 變數定義的路徑中,將所有含 name 的指令都列出來,包含 alias

範例一:查詢一下 ls 這個指令是否為 bash 內建?
[dmtsai@study ~]$ type ls
ls is aliased to `ls --color=auto' <==未加任何參數,列出 ls 的最主要使用情況
[dmtsai@study ~]$ type -t ls
alias                              <==僅列出 ls 執行時的依據
[dmtsai@study ~]$ type -a ls
ls is aliased to `ls --color=auto' <==最先使用 aliase
ls is /usr/bin/ls                  <==還有找到外部指令在 /bin/ls

範例二:那麼 cd 呢?
[dmtsai@study ~]$ type cd
cd is a shell builtin              <==看到了嗎? cd 是 shell 內建指令

透過 type 這個指令我們可以知道每個指令是否為 bash 的內建指令。 此外,由於利用 type 搜尋後面的名稱時,如果後面接的名稱並不能以執行檔的狀態被找到, 那麼該名稱是不會被顯示出來的。也就是說, type 主要在找出『執行檔』而不是一般檔案檔名喔! 呵呵!所以,這個 type 也可以用來作為類似 which 指令的用途啦!找指令用的!

Top

多人多工

Linux 最為人所稱道的即是其多人多工的能力,你可以在任何時刻連線上來你的 Linux 主機,並且同時做很多的工作,例如同時執行 http 的 Web 功能,同時進行 fortran 等程式語言的編輯,並同時上網聊天!你會懷疑, Windows 98 也可以做到這樣的地步呀!不過,不要忘了,在 Linux 的系統下,你所做的任何工作都是獨立的,你可以隨時將你所不要的工作給殺掉,而且,當其中某一個程式當掉的時候, Linux 並不會當機,只要你在其他的視窗再開啟一個終端介面,然後查出當機的那一個指令的 process (過程),然後將之殺掉就可以了!根本不用再重新開機!也因為這種多人多工的強大能力,因此, Linux 系統一般來說是很少當機的,並且,由於其記憶體的管理功能完善,因此也不容易有 CPU 過熱的情況發生(如果只是做為一般伺服器使用)。

在你的 Linux 主機中,可以支援七個終端視窗介面,你可以按[Alt]+[F1].....[F7]來切換不同的終端機介面!所以當其中一個終端機介面當機的時候,你可以在另外一個終端機登入,然後查出錯誤的所在(使用 ps -aux 的功能),再以 kill 將錯誤的地方殺掉即可!

背景執行

style="font-family: 宋体;">另外一個功能,就是『背景執行』的功夫了。當你輸入   

[root@tsai  root]#  cp  file1  file2  &

這一串指令的時候,表示將 file1 這個檔案複製為 file2 ,且放置於背景中執行,也就是說執行這一個命令之後,在這一個終端介面仍然可以做其他的工作!而當這一個指令( cp  file1  file2 )執行完畢之後,系統將會在您的終端介面顯示完成的消息!很便利喔!

多人多工的問題

style="font-family: 宋体;">多人多工確實有很多的好處,但其實也有管理上的困擾,因為使用者越來越多,將導致你管理上的困擾哩!另外,由於使用者日盛,當使用者達到一定的人數後,通常你的機器便需要升級了,因為 CPU 的運算與 RAM 的大小可能就會不敷使用!

& 與 [Ctrl]+[z]

style="font-family: 宋体;">如前所述,背景執行可以提供你在同一個終端機介面(命令模式)當中同時做很多的事情,你可以使用 & 或 [Ctrl]+[z] 來將指令放置背景中執行。例如執行 find  "/"  -name  httpd & 這一行命令,表示將尋找 httpd 這個檔案的指令放置到背景中執行的意思。另外,當你執行一個需要長時間的程式,例如執行 ftp 程式時,在程式進行當中,也可以經由按下 [Ctrl]+[z] 來將程式放置於背景中。那如何由背景中將程式在叫回螢幕上呢?請參考下一個指令 fg。

style="font-size: xx-small;">fg

fg 是將程式再叫回螢幕上顯示的一個指令,在終端模式中輸入 fg 即可。當然,如果你當時並沒有程式在執行的話,系統會告訴你,並無執行中程式(no such job)。

style="font-size: xx-small;">ps       -aux

style="font-family: 宋体;">這是察看執行中的程式的一個指令,你可以配合其參數  -aux  來執行,如下:   

[root@tsai  root]#  ps  -aux

style="font-family: 宋体;">則系統將會列出連同系統服務的程式,在輸出的第一列中會出現 『PID』字樣,在那一欄中的咚咚就是每一個程式執行的代碼。例如下面的輸出畫面。   

[root@tsai  root]#  ps  -aux 
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND 
root         1  0.0  0.1  1324  532 ?        S    Jul16   0:14 init [3] 
root         2  0.0  0.0     0    0 ?        SW   Jul16   0:05 [kflushd] 
root         3  0.0  0.0     0    0 ?        SW   Jul16   0:29 [kupdate] 
root         4  0.0  0.0     0    0 ?        SW   Jul16   0:00 [kpiod] 
root         5  0.0  0.0     0    0 ?        SW   Jul16   0:00 [kswapd]

在上圖中, init 這個程式的 PID 為 1 。

style="font-size: xx-small;">kill

style="font-family: 宋体;">這是用來殺掉執行中程式的指令,需配合 ps 這個指令,當你執行一個 ftp 程式,但是他有點當當的時候,你可以 ps  -aux 這個指令查出  ftp  這個程式的代碼(PID),假設其 PID 為 110 ,然後輸入:   

[root@tsai  root]# kill  110

即可殺掉這個 ftp 程式。

FTP 的功能簡介

澳门新濠3559 5

10.1.6 指令的下達與快速編輯按鈕

我們在第四章的開始下達指令小節已經提到過在 shell 環境下的指令下達方法,如果你忘記了請回到第四章再去回憶一下!這裡不重複說明了。 鳥哥這裡僅就反斜線 () 來說明一下指令下達的方式囉!

範例:如果指令串太長的話,如何使用兩行來輸出?
[dmtsai@study ~]$ cp /var/spool/mail/root /etc/crontab 
> /etc/fstab /root

上面這個指令用途是將三個檔案複製到 /root 這個目錄下而已。不過,因為指令太長, 於是鳥哥就利用『 [Enter] 』來將 [Enter] 這個按鍵『跳脫!』開來,讓 [Enter] 按鍵不再具有『開始執行』的功能!好讓指令可以繼續在下一行輸入。 需要特別留意, [Enter] 按鍵是緊接著反斜線 () 的,兩者中間沒有其他字元。 因為 僅跳脫『緊接著的下一個字符』而已!所以,萬一我寫成: 『  [Enter] 』,亦即 [Enter] 與反斜線中間有一個空格時,則 跳脫的是『空白鍵』而不是 [Enter] 按鍵!這個地方請再仔細的看一遍!很重要!

如果順利跳脫 [Enter] 後,下一行最前面就會主動出現 > 的符號, 你可以繼續輸入指令囉!也就是說,那個 > 是系統自動出現的,你不需要輸入。

另外,當你所需要下達的指令特別長,或者是你輸入了一串錯誤的指令時,你想要快速的將這串指令整個刪除掉,一般來說,我們都是按下刪除鍵的。 有沒有其他的快速組合鍵可以協助呢?是有的!常見的有底下這些:

組合鍵 功能與示範
[ctrl]+u/[ctrl]+k 分別是從游標處向前刪除指令串 ([ctrl]+u) 及向後刪除指令串 ([ctrl]+k)。
[ctrl]+a/[ctrl]+e 分別是讓游標移動到整個指令串的最前面 ([ctrl]+a) 或最後面 ([ctrl]+e)。

總之,當我們順利的在終端機 (tty) 上面登入後, Linux 就會依據 /etc/passwd 檔案的設定給我們一個 shell (預設是 bash),然後我們就可以依據上面的指令下達方式來操作 shell, 之後,我們就可以透過 man 這個線上查詢來查詢指令的使用方式與參數說明, 很不錯吧!那麼我們就趕緊更進一步來操作 bash 這個好玩的東西囉!


 

可以看到目前的sdb就是系統碟。接下來我們將USB Flash插入,輸入

10.2 Shell 的變數功能

變數是 bash 環境中非常重要的一個玩意兒,我們知道 Linux 是多人多工的環境,每個人登入系統都能取得一個 bash shell, 每個人都能夠使用 bash 下達 mail 這個指令來收受『自己』的郵件等等。問題是, bash 是如何得知你的郵件信箱是哪個檔案? 這就需要『變數』的幫助啦!所以,你說變數重不重要呢?底下我們將介紹重要的環境變數、變數的取用與設定等資料, 呼呼!動動腦時間又來到囉!^_^

Top

檔案與目錄管理

 

tail -f  /var/log/messages

10.2.1 什麼是變數?

那麼,什麼是『變數』呢?簡單的說,就是讓某一個特定字串代表不固定的內容就是了。舉個大家在國中都會學到的數學例子, 那就是:『 y = ax + b 』這東西,在等號左邊的(y)就是變數,在等號右邊的(ax+b)就是變數內容。 要注意的是,左邊是未知數,右邊是已知數喔! 講的更簡單一點,我們可以『用一個簡單的 "字眼" 來取代另一個比較複雜或者是容易變動的資料』。這有什麼好處啊?最大的好處就是『方便!』。

  • 變數的可變性與方便性

舉例來說,我們每個帳號的郵件信箱預設是以 MAIL 這個變數來進行存取的, 當 dmtsai 這個使用者登入時,他便會取得 MAIL 這個變數,而這個變數的內容其實就是 /var/spool/mail/dmtsai, 那如果 vbird 登入呢?他取得的 MAIL 這個變數的內容其實就是 /var/spool/mail/vbird 。 而我們使用信件讀取指令 mail 來讀取自己的郵件信箱時,嘿嘿,這支程式可以直接讀取 MAIL 這個變數的內容, 就能夠自動的分辨出屬於自己的信箱信件囉!這樣一來,設計程式的設計師就真的很方便的啦!

澳门新濠3559 6

圖10.2.1、程式、變數與不同使用者的關係

如上圖所示,由於系統已經幫我們規劃好 MAIL 這個變數,所以使用者只要知道 mail 這個指令如何使用即可, mail 會主動的取用 MAIL 這個變數,就能夠如上圖所示的取得自己的郵件信箱了!(注意大小寫,小寫的 mail 是指令, 大寫的 MAIL 則是變數名稱喔!)

那麼使用變數真的比較好嗎?這是當然的!想像一個例子,如果 mail 這個指令將 root 收信的郵件信箱 (mailbox) 檔名為 /var/spool/mail/root 直接寫入程式碼中。那麼當 dmtsai 要使用 mail 時,將會取得 /var/spool/mail/root 這個檔案的內容! 不合理吧!所以你就需要幫 dmtsai 也設計一個 mail 的程式,將 /var/spool/mail/dmtsai 寫死到 mail 的程式碼當中! 天吶!那系統要有多少個 mail 指令啊?反過來說,使用變數就變的很簡單了!因為你不需要更動到程式碼啊! 只要將 MAIL 這個變數帶入不同的內容即可讓所有使用者透過 mail 取得自己的信件!當然簡單多了!

  • 影響 bash 環境操作的變數

某些特定變數會影響到 bash 的環境喔!舉例來說,我們前面已經提到過很多次的那個 PATH 變數! 你能不能在任何目錄下執行某個指令,與 PATH 這個變數有很大的關係。例如你下達 ls 這個指令時,系統就是透過 PATH 這個變數裡面的內容所記錄的路徑順序來搜尋指令的呢!如果在搜尋完 PATH 變數內的路徑還找不到 ls 這個指令時, 就會在螢幕上顯示『 command not found 』的錯誤訊息了。

如果說的學理一點,那麼由於在 Linux System 下面,所有的執行緒都是需要一個執行碼, 而就如同上面提到的,你『真正以 shell 來跟 Linux 溝通,是在正確的登入 Linux 之後!』這個時候你就有一個 bash 的執行程序,也才可以真正的經由 bash 來跟系統溝通囉!而在進入 shell 之前,也正如同上面提到的,由於系統需要一些變數來提供他資料的存取 (或者是一些環境的設定參數值, 例如是否要顯示彩色等等的) ,所以就有一些所謂的『環境變數』 需要來讀入系統中了!這些環境變數例如 PATH、HOME、MAIL、SHELL 等等,都是很重要的, 為了區別與自訂變數的不同,環境變數通常以大寫字元來表示呢!

  • 腳本程式設計 (shell script) 的好幫手

這些還都只是系統預設的變數的目的,如果是個人的設定方面的應用呢:例如你要寫一個大型的 script 時,有些資料因為可能由於使用者習慣的不同而有差異,比如說路徑好了,由於該路徑在 script 被使用在相當多的地方,如果下次換了一部主機,都要修改 script 裡面的所有路徑,那麼我一定會瘋掉! 這個時候如果使用變數,而將該變數的定義寫在最前面,後面相關的路徑名稱都以變數來取代, 嘿嘿!那麼你只要修改一行就等於修改整篇 script 了!方便的很!所以,良好的程式設計師都會善用變數的定義!

澳门新濠3559 7

圖10.2.2、變數應用於 shell script 的示意圖

最後我們就簡單的對『什麼是變數』作個簡單定義好了: 『變數就是以一組文字或符號等,來取代一些設定或者是一串保留的資料!』, 例如:我設定了『myname』就是『VBird』,所以當你讀取 myname 這個變數的時候,系統自然就會知道!哈!那就是 VBird 啦! 那麼如何『顯示變數』呢?這就需要使用到 echo 這個指令啦!

Top

style="font-size: xx-small;">cd

這是用來變換工作路徑的指令。一登入 Linux 系統後,root 會在 /root 下,至於使用者會在預設的 /home/username 底下,例如鳥哥的 ID 為 vbird ,則以 vbird 的身份登入後,會到 /home/vbird 這個路徑下。OK!那回到上一層可以用 cd .. 而到相對路徑可到 cd ../bird,至於絕對路徑則是 cd /usr/sbin !注意喔,在前面的提示字元會改變路徑名稱!   

[root@tsai /root]#  cd ..       <== 回到上一層 
[root@tsai /]#  cd          <== 回到使用者目錄 
[root@tsai root]#  cd /usr/bin  <== 到 /usr/bin 這一個目錄 
[root@tsai bin]#                <== 看吧!到 bin 這個目錄下囉!

style="font-size: xx-small;">pwd

style="font-family: 宋体;">這是顯示目前所在目錄的指令,例如在上個表格最後的目錄是 /usr/bin 這個目錄,但是提示字元僅顯示 bin ,如果你想要知道目前所在的目錄,可以輸入 pwd 即可:   

[root@tsai bin]#  pwd 
/usr/bin  <== 顯示路徑囉! 
[root@tsai bin]# 

style="font-size: xx-small;">ls

style="font-family: 宋体;">這是用來顯示檔案名稱與內容的指令,檔案的內容說明已經在 這裡 說明過了,在此不再重複! ls 的語法為:   

[root@tsai bin]# ls --color 以彩色顯示檔案資料 
[root@tsai bin]# ls -l     詳細列出檔案系統結構 
[root@tsai bin]# ls -a     顯示隱藏檔 (以"."開頭的檔案) 
[root@tsai bin]# ls -al    同時顯示隱藏檔與詳細資料 
[root@tsai bin]# ls -al|more 將檔案內容以一頁一頁顯示

style="font-size: xx-small;">cat

這是將檔案內容列出的指令。例如在 /root 下有一個檔名為 .bashrc (這是系統預設的檔案,是隱藏檔),你可以按下 cd 回到 /root 目錄後,執行:   

[root@tsai /root]# cat .bashrc 
# .bashrc

# User specific aliases and functions

alias rm='rm -i' 
alias cp='cp -i' 
alias mv='mv -i' 
alias ll='ls -l' 
alias lm='ls -al|more'

上面顯示的就是 .bashrc 這個檔案的內容啦!基本上,cat 與 DOS 下的 type 是相同的!

style="font-size: xx-small;">more

是否覺得 cat 在讀取較大的檔案的時候會有看不到的資訊呢(如果檔案太大的話),這時候你可以用 more 來一頁頁讀取喔!另外, more 也可以與其他的程式合併使用,例如 ls !(如下表中,『|』就是分隔號,可以將兩個指令放在一起執行!)   

[root@tsai /root]# more .bashrc 
[root@tsai /root]# ls -al|more

style="font-size: xx-small;">mkdir

建立新的目錄!例如我們要建立一個 test 的目錄,你可以這樣下指令:   

[root@tsai /root]# mkdir test 
[root@tsai /root]# ls -l

再執行了 ls -l 之後,你就可以看到 test 這個目錄啦!

style="font-size: xx-small;">rm    -irf

這是移除的指令,相當於 dos 下的 del 指令!這裡要注意的是,通常在 Linux 系統下,為了怕檔案被誤殺,所以都已經有 -i 這個參數, -i 是指每個檔案被殺掉之前都會確認一次。而如果要連目錄下的東西都一起殺掉的話,就要使用 -rf 這個參數了!你可以用下面這個例子來試試看有什麼不同的現象!   

[root@tsai /root]# rm test 
[root@tsai /root]# rm -rf test

style="font-size: xx-small;">rmdir

mkdir 是建立目錄,而 rmdir 就是移除目錄的指令。不過,若是欲移除的目錄裡頭有檔案或其他目錄存在,就無法移除,這時就要用剛剛的 rm -rf 來移除啦!

style="font-size: xx-small;">mv

style="font-family: 宋体;">這是移動檔案或目錄的指令,例如我們要將 .bashrc 這個檔案移動至根目錄下,則:   

[root@tsai /root]# mv .bashrc / 
[root@tsai /root]# mv /.bashrc .

而將檔案移動至目前的工作目錄,則加上 "." 這個字!

語法: mv 來源檔(或目錄) 目的檔(或目錄)

style="font-size: xx-small;">cp

就是 copy 的意思。例如我們要將 .bashrc 這個檔案複製到 /home 底下,可以:   

[root@tsai /root]# cp .bashrc /home

語法: cp 來源檔 目的檔

style="font-size: xx-small;">ln

 ln  -s  真實目錄或檔案   連結的目錄或檔案:這是連結檔案或目錄的指令,通常我們都會加 -s 這個參數,例如我們將 /usr/bin 這個目錄連接到 /root 底下,可以這樣輸入:   

[root@tsai /root]# ln -s /usr/bin bin

不過請注意喔,在你的 /root 底下的 bin 這個目錄中的所有檔案其實都是 /usr/bin 裡面的東西,所以你如果進入 /root/bin 內亂殺東西的話,等於是將 /usr/bin 內的檔案殺掉喔!

語法: ln -s 來源檔(或目錄) 目的檔(或目錄)

style="font-size: xx-small;">find

style="font-family: 宋体;">尋找檔案的指令,會將欲尋找的檔案找出來,例如下面的例子:   

[root@tsai /root]# find / -name bin

上面的意思為:在 / 目錄(根目錄)下尋找檔名(-name)為 bin 的檔案,要注意的是,因為 Linux 的檔案很多,如果你的電腦比較舊,可能會找很久...

語法: find 路徑 -name 檔名

style="font-size: xx-small;">whereis

相對於 find ,你也可以使用 whereis 這個指令來下達找尋的檔案,whereis 利用曾經找過的系統資訊內的資料去找檔案,所以速度會很快,不過,如果 whereis 找不到的話,並不代表該檔案真的不存在!這個要小心!   

[root@tsai /root]# whereis bin 
bin: /usr/bin

style="font-size: xx-small;">chmod

style="font-family: 宋体;">這是變更檔案屬性的指令,通常鳥哥都是以數字作為改變屬性的依據;在檔案的屬性中, r 為4分、w 為2分, x 為1分,如果你想要讓你剛建立的一個檔案,讓大家都看到的話,即你需要『-rw-r--r--』,這是你的三個群組的分數分別是 r+w=6, r=4, r=4,所以可以下達:   

[root@tsai /root]# chmod 644 .bashrc 
[root@tsai /root]# ls -al .bashrc 
-rw-r--r--   1 root     root          216 Apr  8 13:54 .bashrc

style="font-size: xx-small;">chown

style="font-family: 宋体;">記得檔案有『擁有人』及『擁有群組』吧,這個 chown 就是在改變擁有者的指令。例如你 copy 一個檔案給 vbird ,但是因為你的身份是 root ,所以你 copy 過去的檔案 vbird 可能不能使用,因此你需要將檔案的擁有人改成 vbird 才可以!如下:   

[root@tsai /root]# cp .bashrc /home/vbird 
[root@tsai /root]# cd /home/vbird 
[root@tsai vbird]# chown vbird .bashrc

那如果想要將整個目錄下的檔案都改變擁有者與擁有群組呢?可以下達 
chown  -R  username:groupname  directory  (ex> chown -R root:root /root) 
即可喔!

style="font-size: xx-small;">chgrp

style="font-family: 宋体;">作用與 chown 相似,只是在改變檔案或目錄的『擁有群組』。

style="font-size: xx-small;">df

style="font-family: 宋体;">這是用來察看硬碟空間的指令。由於我們目前將檔案都建立在根目錄『/』下,所以只要沒有空間,則所有檔案都無法複製進來系統。不過,若你規劃出多的硬碟,則可以察看你的硬碟空間資訊,如下所示:   

[root@tsai /root]# df 
Filesystem     1k-blocks      Used Available Use% Mounted on 
/dev/hda5         964312     87648    827680  10% / 
/dev/hdb5        2150420    745500   1295680  37% /home 
/dev/hdb1        2016016   1419708    493896  74% /usr 
/dev/hda1        1022080    349880    672200  34% /win98

上面說,Filesystem 是硬碟所在的劃分表, Used 是指使用掉的硬碟空間(KB),Available是剩下空間,Mounted on則是這顆硬碟代表哪一個目錄。如上所示,根目錄(/)在 hda5 這顆硬碟,總空間有 964312 KB,剩下可用空間為 827680KB,至於 /win98 則在 hda1 中,且全部空間有 1022080 KB。

如果要將資料型態以 MB 數顯示的話,可以輸入 df -m 來達成。

style="font-size: xx-small;">du

style="font-family: 宋体;">這是用來察看目錄內所有檔案使用掉的空間的情況,如下所示:   

[root@tsai /root]# du -m

其中, du 預設的檔案輸出資料為 KB,以參數 -m 使檔案資料顯示為 MB。

  1. 不同等級的使用者身份:FTP 預設的情況下可以提供三種主要的身份,分別是(1)實體帳號,real user;(2)訪客, guest;(3)匿名登入者, anonymous 這三種。分成三種身份主要可以做為主機的控管上面的便利性,而且也可以將使用者作一個有效的管理呢!例如實體用戶可以進行的動作可能會比較多一些,至於匿 名登入者,大概我們就僅提供他下載一下資源而已,並不許匿名者使用太多主機的資源啊!當然,這三種人物能夠使用的『線上指令』自然也就不相同囉! ^_^

澳门新濠3559 8

10.2.2 變數的取用與設定:echo, 變數設定規則, unset

說的口沫橫飛的,也不知道『變數』與『變數代表的內容』有啥關係? 那我們就將『變數』的『內容』拿出來給您瞧瞧好了。你可以利用 echo 這個指令來取用變數, 但是,變數在被取用時,前面必須要加上錢字號『 $ 』才行,舉例來說,要知道 PATH 的內容,該如何是好?

  • 變數的取用: echo
[dmtsai@study ~]$ echo $variable
[dmtsai@study ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
[dmtsai@study ~]$ echo ${PATH}  # 近年來,鳥哥比較偏向使用這種格式喔!

變數的取用就如同上面的範例,利用 echo 就能夠讀出,只是需要在變數名稱前面加上 $ , 或者是以 ${變數} 的方式來取用都可以!當然啦,那個 echo 的功能可是很多的, 我們這裡單純是拿 echo 來讀出變數的內容而已,更多的 echo 使用,請自行給他 man echo 吧! ^_^

例題:
請在螢幕上面顯示出您的環境變數 HOME 與 MAIL:
答:
echo $HOME 或者是 echo ${HOME}
echo $MAIL 或者是 echo ${MAIL}

現在我們知道了變數與變數內容之間的相關性了,好了,那麼我要如何『設定』或者是『修改』 某個變數的內容啊?很簡單啦!用『等號(=)』連接變數與他的內容就好啦!舉例來說: 我要將 myname 這個變數名稱的內容設定為 VBird ,那麼:

[dmtsai@study ~]$ echo ${myname}
       <==這裡並沒有任何資料~因為這個變數尚未被設定!是空的!
[dmtsai@study ~]$ myname=VBird
[dmtsai@study ~]$ echo ${myname}
VBird  <==出現了!因為這個變數已經被設定了!

瞧!如此一來,這個變數名稱 myname 的內容就帶有 VBird 這個資料囉~ 而由上面的例子當中,我們也可以知道: 在 bash 當中,當一個變數名稱尚未被設定時,預設的內容是『空』的。 另外,變數在設定時,還是需要符合某些規定的,否則會設定失敗喔!這些規則如下所示啊!

Tips澳门新濠3559 9要請各位讀者注意喔,每一種 shell 的語法都不相同~在變數的使用上,bash 在你沒有設定的變數中強迫去 echo 時,它會顯示出空的值。 在其他某些 shell 中,隨便去 echo 一個不存在的變數,它是會出現錯誤訊息的喔!要注意!要注意!

  • 變數的設定規則
  1. 變數與變數內容以一個等號『=』來連結,如下所示: 
    『myname=VBird』
  1. 等號兩邊不能直接接空白字元,如下所示為錯誤: 
    『myname = VBird』或『myname=VBird Tsai』
  1. 變數名稱只能是英文字母與數字,但是開頭字元不能是數字,如下為錯誤: 
    『2myname=VBird』
  1. 變數內容若有空白字元可使用雙引號『"』或單引號『'』將變數內容結合起來,但
    • 雙引號內的特殊字元如 $ 等,可以保有原本的特性,如下所示:
      『var="lang is $LANG"』則『echo $var』可得『lang is zh_TW.UTF-8』
    • 單引號內的特殊字元則僅為一般字元 (純文字),如下所示:
      『var='lang is $LANG'』則『echo $var』可得『lang is $LANG』
  2. 可用跳脫字元『 』將特殊符號(如 [Enter], $, , 空白字元, '等)變成一般字元,如:
    『myname=VBird Tsai』
  1. 在一串指令的執行中,還需要藉由其他額外的指令所提供的資訊時,可以使用反單引號『`指令`』或 『$(指令)』。特別注意,那個 ` 是鍵盤上方的數字鍵 1 左邊那個按鍵,而不是單引號! 例如想要取得核心版本的設定:
    『version=$(uname -r)』再『echo $version』可得『3.10.0-229.el7.x86_64』
  1. 若該變數為擴增變數內容時,則可用 "$變數名稱" 或 ${變數} 累加內容,如下所示:
    『PATH="$PATH":/home/bin』或『PATH=${PATH}:/home/bin』

  2. 若該變數需要在其他子程序執行,則需要以 export 來使變數變成環境變數:
    『export PATH』

  1. 通常大寫字元為系統預設變數,自行設定變數可以使用小寫字元,方便判斷 (純粹依照使用者興趣與嗜好) ;

  2. 取消變數的方法為使用 unset :『unset 變數名稱』例如取消 myname 的設定:
    『unset myname』

底下讓鳥哥舉幾個例子來讓你試看看,就知道怎麼設定好你的變數囉!

範例一:設定一變數 name ,且內容為 VBird
[dmtsai@study ~]$ 12name=VBird
bash: 12name=VBird: command not found...  <==螢幕會顯示錯誤!因為不能以數字開頭!
[dmtsai@study ~]$ name = VBird            <==還是錯誤!因為有空白!
[dmtsai@study ~]$ name=VBird              <==OK 的啦!

範例二:承上題,若變數內容為 VBird's name 呢,就是變數內容含有特殊符號時:
[dmtsai@study ~]$ name=VBird's name  
# 單引號與雙引號必須要成對,在上面的設定中僅有一個單引號,因此當你按下 enter 後,
# 你還可以繼續輸入變數內容。這與我們所需要的功能不同,失敗啦!
# 記得,失敗後要復原請按下 [ctrl]-c 結束!
[dmtsai@study ~]$ name="VBird's name"    <==OK 的啦!
# 指令是由左邊向右找→,先遇到的引號先有用,因此如上所示, 單引號變成一般字元!
[dmtsai@study ~]$ name='VBird's name'    <==失敗的啦!
# 因為前兩個單引號已成對,後面就多了一個不成對的單引號了!因此也就失敗了!
[dmtsai@study ~]$ name=VBird's name     <==OK 的啦!
# 利用反斜線 () 跳脫特殊字元,例如單引號與空白鍵,這也是 OK 的啦!

範例三:我要在 PATH 這個變數當中『累加』:/home/dmtsai/bin 這個目錄
[dmtsai@study ~]$ PATH=$PATH:/home/dmtsai/bin
[dmtsai@study ~]$ PATH="$PATH":/home/dmtsai/bin
[dmtsai@study ~]$ PATH=${PATH}:/home/dmtsai/bin
# 上面這三種格式在 PATH 裡頭的設定都是 OK 的!但是底下的例子就不見得囉!

範例四:承範例三,我要將 name 的內容多出 "yes" 呢?
[dmtsai@study ~]$ name=$nameyes  
# 知道了吧?如果沒有雙引號,那麼變數成了啥?name 的內容是 $nameyes 這個變數!
# 呵呵!我們可沒有設定過 nameyes 這個變數吶!所以,應該是底下這樣才對!
[dmtsai@study ~]$ name="$name"yes
[dmtsai@study ~]$ name=${name}yes  <==以此例較佳!

範例五:如何讓我剛剛設定的 name=VBird 可以用在下個 shell 的程序?
[dmtsai@study ~]$ name=VBird
[dmtsai@study ~]$ bash        <==進入到所謂的子程序
[dmtsai@study ~]$ echo $name  <==子程序:再次的 echo 一下;
       <==嘿嘿!並沒有剛剛設定的內容喔!
[dmtsai@study ~]$ exit        <==子程序:離開這個子程序
[dmtsai@study ~]$ export name
[dmtsai@study ~]$ bash        <==進入到所謂的子程序
[dmtsai@study ~]$ echo $name  <==子程序:在此執行!
VBird  <==看吧!出現設定值了!
[dmtsai@study ~]$ exit        <==子程序:離開這個子程序

什麼是『子程序』呢?就是說,在我目前這個 shell 的情況下,去啟用另一個新的 shell ,新的那個 shell 就是子程序啦!在一般的狀態下,父程序的自訂變數是無法在子程序內使用的。但是透過 export 將變數變成環境變數後,就能夠在子程序底下應用了!很不賴吧!至於程序的相關概念, 我們會在第十六章程序管理當中提到的喔!

範例六:如何進入到您目前核心的模組目錄?
[dmtsai@study ~]$ cd /lib/modules/`uname -r`/kernel
[dmtsai@study ~]$ cd /lib/modules/$(uname -r)/kernel  # 以此例較佳!

每個 Linux 都能夠擁有多個核心版本,且幾乎 distribution 的核心版本都不相同。以 CentOS 7.1 (未更新前) 為例,他的預設核心版本是 3.10.0-229.el7.x86_64 ,所以核心模組目錄在 /lib/modules/3.10.0-229.el7.x86_64/kernel/ 內。 也由於每個 distributions 的這個值都不相同,但是我們卻可以利用 uname -r 這個指令先取得版本資訊。所以囉,就可以透過上面指令當中的內含指令 $(uname -r) 先取得版本輸出到 cd ... 那個指令當中,就能夠順利的進入目前核心的驅動程式所放置的目錄囉!很方便吧!

其實上面的指令可以說是作了兩次動作,亦即是:

  1. 先進行反單引號內的動作『uname -r』並得到核心版本為 3.10.0-229.el7.x86_64
  2. 將上述的結果帶入原指令,故得指令為:『cd /lib/modules/3.10.0-229.el7.x86_64/kernel/』

Tips澳门新濠3559 10為什麼鳥哥比較建議記憶 $( command ) 呢?還記得小時候學數學的加減乘除,我們都知道得要先乘除後加減。那如果硬要先加減再乘除呢? 當然就是加上括號 () 來處理即可啊!所以囉,這個指令的處理方式也差不多,只是括號左邊得要加個錢字號就是了!

範例七:取消剛剛設定的 name 這個變數內容
[dmtsai@study ~]$ unset name

根據上面的案例你可以試試看!就可以瞭解變數的設定囉!這個是很重要的呦!請勤加練習! 其中,較為重要的一些特殊符號的使用囉!例如單引號、雙引號、跳脫字元、錢字號、反單引號等等,底下的例題想一想吧!

例題:
在變數的設定當中,單引號與雙引號的用途有何不同?
答:
單引號與雙引號的最大不同在於雙引號仍然可以保有變數的內容,但單引號內僅能是一般字元 ,而不會有特殊符號。我們以底下的例子做說明:假設您定義了一個變數, name=VBird ,現在想以 name 這個變數的內容定義出 myname 顯示 VBird its me 這個內容,要如何訂定呢?
[dmtsai@study ~]$ name=VBird
[dmtsai@study ~]$ echo $name
VBird
[dmtsai@study ~]$ myname="$name its me"
[dmtsai@study ~]$ echo $myname
VBird its me
[dmtsai@study ~]$ myname='$name its me'
[dmtsai@study ~]$ echo $myname
$name its me
發現了嗎?沒錯!使用了單引號的時候,那麼 $name 將失去原有的變數內容,僅為一般字元的顯示型態而已!這裡必需要特別小心在意!
例題:
在指令下達的過程中,反單引號( ` )這個符號代表的意義為何?
答:
在一串指令中,在 ` 之內的指令將會被先執行,而其執行出來的結果將做為外部的輸入資訊!例如 uname -r 會顯示出目前的核心版本,而我們的核心版本在 /lib/modules 裡面,因此,你可以先執行 uname -r 找出核心版本,然後再以『 cd 目錄』到該目錄下,當然也可以執行如同上面範例六的執行內容囉。 

另外再舉個例子,我們也知道, locate 指令可以列出所有的相關檔案檔名,但是,如果我想要知道各個檔案的權限呢?舉例來說,我想要知道每個 crontab 相關檔名的權限:
[dmtsai@study ~]$ ls -ld `locate crontab`
[dmtsai@study ~]$ ls -ld $(locate crontab)
如此一來,先以 locate 將檔名資料都列出來,再以 ls 指令來處理的意思啦!瞭了嗎? ^_^
例題:
若你有一個常去的工作目錄名稱為:『/cluster/server/work/taiwan_2015/003/』,如何進行該目錄的簡化?
答:
在一般的情況下,如果你想要進入上述的目錄得要『cd /cluster/server/work/taiwan_2015/003/』, 以鳥哥自己的案例來說,鳥哥跑數值模式常常會設定很長的目錄名稱(避免忘記),但如此一來變換目錄就很麻煩。 此時,鳥哥習慣利用底下的方式來降低指令下達錯誤的問題:
[dmtsai@study ~]$ work="/cluster/server/work/taiwan_2015/003/"
[dmtsai@study ~]$ cd $work
未來我想要使用其他目錄作為我的模式工作目錄時,只要變更 work 這個變數即可!而這個變數又可以在 bash 的設定檔(~/.bashrc)中直接指定,那我每次登入只要執行『 cd $work 』就能夠去到數值模式模擬的工作目錄了!是否很方便呢? ^_^

Top


 

會發現出現「usb-storage」,但此時系統會以VM為主,因此在Service Console之下,還是看不到USB硬碟。我們要將USB的控制從VM上移到Service Console之中。

10.2.3 環境變數的功能

環境變數可以幫我們達到很多功能~包括家目錄的變換啊、提示字元的顯示啊、執行檔搜尋的路徑啊等等的, 還有很多很多啦!那麼,既然環境變數有那麼多的功能,問一下,目前我的 shell 環境中, 有多少預設的環境變數啊?我們可以利用兩個指令來查閱,分別是 env 與 export 呢!

  • 用 env 觀察環境變數與常見環境變數說明
範例一:列出目前的 shell 環境下的所有環境變數與其內容。
[dmtsai@study ~]$ env
HOSTNAME=study.centos.vbird    <== 這部主機的主機名稱
TERM=xterm                     <== 這個終端機使用的環境是什麼類型
SHELL=/bin/bash                <== 目前這個環境下,使用的 Shell 是哪一個程式?
HISTSIZE=1000                  <== 『記錄指令的筆數』在 CentOS 預設可記錄 1000 筆
OLDPWD=/home/dmtsai            <== 上一個工作目錄的所在
LC_ALL=en_US.utf8              <== 由於語系的關係,鳥哥偷偷丟上來的一個設定
USER=dmtsai                    <== 使用者的名稱啊!
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:
or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:
*.tar=01...                    <== 一些顏色顯示
MAIL=/var/spool/mail/dmtsai    <== 這個使用者所取用的 mailbox 位置
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
PWD=/home/dmtsai               <== 目前使用者所在的工作目錄 (利用 pwd 取出!)
LANG=zh_TW.UTF-8               <== 這個與語系有關,底下會再介紹!
HOME=/home/dmtsai              <== 這個使用者的家目錄啊!
LOGNAME=dmtsai                 <== 登入者用來登入的帳號名稱
_=/usr/bin/env                 <== 上一次使用的指令的最後一個參數(或指令本身)

env 是 environment (環境) 的簡寫啊,上面的例子當中,是列出來所有的環境變數。當然,如果使用 export 也會是一樣的內容~ 只不過, export 還有其他額外的功能就是了,我們等一下再提這個 export 指令。 那麼上面這些變數有些什麼功用呢?底下我們就一個一個來分析分析!

  • HOME
    代表使用者的家目錄。還記得我們可以使用 cd ~ 去到自己的家目錄嗎?或者利用 cd 就可以直接回到使用者家目錄了。那就是取用這個變數啦~ 有很多程式都可能會取用到這個變數的值!
  • SHELL
    告知我們,目前這個環境使用的 SHELL 是哪支程式? Linux 預設使用 /bin/bash 的啦!
  • HISTSIZE
    這個與『歷史命令』有關,亦即是, 我們曾經下達過的指令可以被系統記錄下來,而記錄的『筆數』則是由這個值來設定的。
  • MAIL
    當我們使用 mail 這個指令在收信時,系統會去讀取的郵件信箱檔案 (mailbox)。
  • PATH
    就是執行檔搜尋的路徑啦~目錄與目錄中間以冒號(:)分隔, 由於檔案的搜尋是依序由 PATH 的變數內的目錄來查詢,所以,目錄的順序也是重要的喔。
  • LANG
    這個重要!就是語系資料囉~很多訊息都會用到他, 舉例來說,當我們在啟動某些 perl 的程式語言檔案時,他會主動的去分析語系資料檔案, 如果發現有他無法解析的編碼語系,可能會產生錯誤喔!一般來說,我們中文編碼通常是 zh_TW.Big5 或者是 zh_TW.UTF-8,這兩個編碼偏偏不容易被解譯出來,所以,有的時候,可能需要修訂一下語系資料。 這部分我們會在下個小節做介紹的!
  • RANDOM
    這個玩意兒就是『隨機亂數』的變數啦!目前大多數的 distributions 都會有亂數產生器,那就是/dev/random 這個檔案。 我們可以透過這個亂數檔案相關的變數 ($RANDOM) 來隨機取得亂數值喔。在 BASH 的環境下,這個 RANDOM 變數的內容,介於 0~32767 之間,所以,你只要 echo $RANDOM 時,系統就會主動的隨機取出一個介於 0~32767 的數值。萬一我想要使用 0~9 之間的數值呢?呵呵~利用 declare 宣告數值類型, 然後這樣做就可以了:

    [dmtsai@study ~]$ declare -i number=$RANDOM*10/32768 ; echo $number
    8   <== 此時會隨機取出 0~9 之間的數值喔!
    

大致上是有這些環境變數啦~裡面有些比較重要的參數,在底下我們都會另外進行一些說明的~

  • 用 set 觀察所有變數 (含環境變數與自訂變數)

bash 可不只有環境變數喔,還有一些與 bash 操作介面有關的變數,以及使用者自己定義的變數存在的。 那麼這些變數如何觀察呢?這個時候就得要使用 set 這個指令了。 set 除了環境變數之外, 還會將其他在 bash 內的變數通通顯示出來哩!資訊很多,底下鳥哥僅列出幾個重要的內容:

[dmtsai@study ~]$ set
BASH=/bin/bash                        <== bash 的主程式放置路徑
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(1)-release'      <== 這兩行是 bash 的版本啊!
COLUMNS=90                            <== 在目前的終端機環境下,使用的欄位有幾個字元長度
HISTFILE=/home/dmtsai/.bash_history   <== 歷史命令記錄的放置檔案,隱藏檔
HISTFILESIZE=1000                     <== 存起來(與上個變數有關)的檔案之指令的最大紀錄筆數。
HISTSIZE=1000                         <== 目前環境下,記憶體中記錄的歷史命令最大筆數。
IFS=$' tn'                          <== 預設的分隔符號
LINES=20                              <== 目前的終端機下的最大行數
MACHTYPE=x86_64-redhat-linux-gnu      <== 安裝的機器類型
OSTYPE=linux-gnu                      <== 作業系統的類型!
PS1='[u@h W]$ '                   <== PS1 就厲害了。這個是命令提示字元,也就是我們常見的
                                          [root@www ~]# 或 [dmtsai ~]$ 的設定值啦!可以更動的!
PS2='> '                              <== 如果你使用跳脫符號 () 第二行以後的提示字元也
$                                     <== 目前這個 shell 所使用的 PID
?                                     <== 剛剛執行完指令的回傳值。
...
# 有許多可以使用的函式庫功能被鳥哥取消囉!請自行查閱!

一般來說,不論是否為環境變數,只要跟我們目前這個 shell 的操作介面有關的變數, 通常都會被設定為大寫字元,也就是說,『基本上,在 Linux 預設的情況中,使用{大寫的字母}來設定的變數一般為系統內定需要的變數』。 OK!OK!那麼上頭那些變數當中,有哪些是比較重要的?大概有這幾個吧!

  • PS1:(提示字元的設定)

這是 PS1 (數字的 1 不是英文字母),這個東西就是我們的『命令提示字元』喔! 當我們每次按下 [Enter] 按鍵去執行某個指令後,最後要再次出現提示字元時, 就會主動去讀取這個變數值了。上頭 PS1 內顯示的是一些特殊符號,這些特殊符號可以顯示不同的資訊, 每個 distributions 的 bash 預設的 PS1 變數內容可能有些許的差異,不要緊,『習慣你自己的習慣』就好了。 你可以用 man bash (註3)去查詢一下 PS1 的相關說明,以理解底下的一些符號意義。

  • d :可顯示出『星期 月 日』的日期格式,如:"Mon Feb 2"
  • H :完整的主機名稱。舉例來說,鳥哥的練習機為『study.centos.vbird』
  • h :僅取主機名稱在第一個小數點之前的名字,如鳥哥主機則為『study』後面省略
  • t :顯示時間,為 24 小時格式的『HH:MM:SS』
  • T :顯示時間,為 12 小時格式的『HH:MM:SS』
  • A :顯示時間,為 24 小時格式的『HH:MM』
  • @ :顯示時間,為 12 小時格式的『am/pm』樣式
  • u :目前使用者的帳號名稱,如『dmtsai』;
  • v :BASH 的版本資訊,如鳥哥的測試主機版本為 4.2.46(1)-release,僅取『4.2』顯示
  • w :完整的工作目錄名稱,由根目錄寫起的目錄名稱。但家目錄會以 ~ 取代;
  • W :利用 basename 函數取得工作目錄名稱,所以僅會列出最後一個目錄名。
  • # :下達的第幾個指令。
  • $ :提示字元,如果是 root 時,提示字元為 # ,否則就是 $ 囉~

好了,讓我們來看看 CentOS 預設的 PS1 內容吧:『[u@h W]$ 』,現在你知道那些反斜線後的資料意義了吧? 要注意喔!那個反斜線後的資料為 PS1 的特殊功能,與 bash 的變數設定沒關係啦!不要搞混了喔! 那你現在知道為何你的命令提示字元是:『 [dmtsai@study ~]$ 』了吧?好了,那麼假設我想要有類似底下的提示字元:

[dmtsai@study /home/dmtsai 16:50 #12]$

那個 # 代表第 12 次下達的指令。那麼應該如何設定 PS1 呢?可以這樣啊:

[dmtsai@study ~]$ cd /home
[dmtsai@study home]$ PS1='[u@h w A ##]$ '
[dmtsai@study /home 17:02 #85]$
# 看到了嗎?提示字元變了!變的很有趣吧!其中,那個 #85 比較有趣,
# 如果您再隨便輸入幾次 ls 後,該數字就會增加喔!為啥?上面有說明滴!
  • $:(關於本 shell 的 PID)

錢字號本身也是個變數喔!這個咚咚代表的是『目前這個 Shell 的執行緒代號』,亦即是所謂的 PID (Process ID)。 更多的程序觀念,我們會在第四篇的時候提及。想要知道我們的 shell 的 PID ,就可以用:『 echo $$ 』即可!出現的數字就是你的 PID 號碼。

  • ?:(關於上個執行指令的回傳值)

蝦密?問號也是一個特殊的變數?沒錯!在 bash 裡面這個變數可重要的很! 這個變數是:『上一個執行的指令所回傳的值』, 上面這句話的重點是『上一個指令』與『回傳值』兩個地方。當我們執行某些指令時, 這些指令都會回傳一個執行後的代碼。一般來說,如果成功的執行該指令, 則會回傳一個 0 值,如果執行過程發生錯誤,就會回傳『錯誤代碼』才對!一般就是以非為 0 的數值來取代。 我們以底下的例子來看看:

[dmtsai@study ~]$ echo $SHELL
/bin/bash                                  <==可順利顯示!沒有錯誤!
[dmtsai@study ~]$ echo $?
0                                          <==因為沒問題,所以回傳值為 0
[dmtsai@study ~]$ 12name=VBird
bash: 12name=VBird: command not found...   <==發生錯誤了!bash回報有問題
[dmtsai@study ~]$ echo $?
127                                        <==因為有問題,回傳錯誤代碼(非為0)
# 錯誤代碼回傳值依據軟體而有不同,我們可以利用這個代碼來搜尋錯誤的原因喔!
[dmtsai@study ~]$ echo $?
0
# 咦!怎麼又變成正確了?這是因為 "?" 只與『上一個執行指令』有關,
# 所以,我們上一個指令是執行『 echo $? 』,當然沒有錯誤,所以是 0 沒錯!
  • OSTYPE, HOSTTYPE, MACHTYPE:(主機硬體與核心的等級)

我們在第零章、計算機概論內的 CPU 等級說明中談過 CPU , 目前個人電腦的 CPU 主要分為 32/64 位元,其中 32 位元又可分為 i386, i586, i686,而 64 位元則稱為 x86_64。 由於不同等級的 CPU 指令集不太相同,因此你的軟體可能會針對某些 CPU 進行最佳化,以求取較佳的軟體性能。 所以軟體就有 i386, i686 及 x86_64 之分。以目前 (2015) 的主流硬體來說,幾乎都是 x86_64 的天下! 因此 CentOS 7 開始,已經不支援 i386 相容模式的安裝光碟了~哇嗚!進步的太快了!

要留意的是,較高階的硬體通常會向下相容舊有的軟體,但較高階的軟體可能無法在舊機器上面安裝! 我們在第二章就曾說明過, 這裡再強調一次,你可以在 x86_64 的硬體上安裝 i386 的 Linux 作業系統,但是你無法在 i686 的硬體上安裝 x86_64 的 Linux 作業系統!這點得要牢記在心!

  • export: 自訂變數轉成環境變數

談了 env 與 set 現在知道有所謂的環境變數與自訂變數,那麼這兩者之間有啥差異呢?其實這兩者的差異在於『 該變數是否會被子程序所繼續引用』啦!唔!那麼啥是父程序?子程序? 這就得要瞭解一下指令的下達行為了。

當你登入 Linux 並取得一個 bash 之後,你的 bash 就是一個獨立的程序,這個程序的識別使用的是一個稱為程序識別碼,被稱為 PID 的就是。 接下來你在這個 bash 底下所下達的任何指令都是由這個 bash 所衍生出來的,那些被下達的指令就被稱為子程序了。 我們可以用底下的圖示來簡單的說明一下父程序與子程序的概念:

澳门新濠3559 11

圖10.2.3、程序相關性示意圖

如上所示,我們在原本的 bash 底下執行另一個 bash ,結果操作的環境介面會跑到第二個 bash 去(就是子程序), 那原本的 bash 就會在暫停的情況 (睡著了,就是 sleep)。整個指令運作的環境是實線的部分!若要回到原本的 bash 去, 就只有將第二個 bash 結束掉 (下達 exit 或 logout) 才行。更多的程序概念我們會在第四篇談及,這裡只要有這個概念即可。

這個程序概念與變數有啥關係啊?關係可大了!因為子程序僅會繼承父程序的環境變數, 子程序不會繼承父程序的自訂變數啦!所以你在原本 bash 的自訂變數在進入了子程序後就會消失不見, 一直到你離開子程序並回到原本的父程序後,這個變數才會又出現!

換個角度來想,也就是說,如果我能將自訂變數變成環境變數的話,那不就可以讓該變數值繼續存在於子程序了? 呵呵!沒錯!此時,那個 export 指令就很有用啦!如你想要讓該變數內容繼續的在子程序中使用,那麼就請執行:

[dmtsai@study ~]$ export 變數名稱

這東西用在『分享自己的變數設定給後來呼叫的檔案或其他程序』啦! 像鳥哥常常在自己的主檔案後面呼叫其他附屬檔案(類似函式的功能),但是主檔案與附屬檔案內都有相同的變數名稱, 若一再重複設定時,要修改也很麻煩,此時只要在原本的第一個檔案內設定好『 export 變數 』, 後面所呼叫的檔案就能夠使用這個變數設定了!而不需要重複設定,這非常實用於 shell script 當中喔! 如果僅下達 export 而沒有接變數時,那麼此時將會把所有的『環境變數』秀出來喔!例如:

[dmtsai@study ~]$ export
declare -x HISTSIZE="1000"
declare -x HOME="/home/dmtsai"
declare -x HOSTNAME="study.centos.vbird"
declare -x LANG="zh_TW.UTF-8"
declare -x LC_ALL="en_US.utf8"
# 後面的鳥哥就都直接省略了!不然....浪費版面~ ^_^

那如何將環境變數轉成自訂變數呢?可以使用本章後續介紹的 declare 呢!

Top

磁碟與硬體管理

  1. 命令記錄與登錄檔記錄:FTP 可以利用系統的 syslogd 這個 daemon 來進行資料的紀錄,而記錄的資料包括了使用者曾經下達過的命令與使用者傳輸資料(傳輸時間、檔案大小等等)的紀錄呢!

在ESX/ESXi中,將USB的控制權交還給Service Console,需要將usbarbitrator這個參數關閉,因此我們必須輸入

10.2.4 影響顯示結果的語系變數 (locale)

還記得我們在第四章裡面提到的語系問題嗎? 就是當我們使用 man command 的方式去查詢某個資料的說明檔時,該說明檔的內容可能會因為我們使用的語系不同而產生亂碼。 另外,利用 ls 查詢檔案的時間時,也可能會有亂碼出現在時間的部分。那個問題其實就是語系的問題啦。

目前大多數的 Linux distributions 已經都是支援日漸流行的萬國碼了,也都支援大部分的國家語系。 那麼我們的 Linux 到底支援了多少的語系呢?這可以由 locale 這個指令來查詢到喔!

[dmtsai@study ~]$ locale -a
....(前面省略)....
zh_TW
zh_TW.big5     <==大五碼的中文編碼
zh_TW.euctw
zh_TW.utf8     <==萬國碼的中文編碼
zu_ZA
zu_ZA.iso88591
zu_ZA.utf8

正體中文語系至少支援了兩種以上的編碼,一種是目前還是很常見的 big5 ,另一種則是越來越熱門的 utf-8 編碼。 那麼我們如何修訂這些編碼呢?其實可以透過底下這些變數的說:

[dmtsai@study ~]$ locale  <==後面不加任何選項與參數即可!
LANG=en_US                   <==主語言的環境
LC_CTYPE="en_US"             <==字元(文字)辨識的編碼
LC_NUMERIC="en_US"           <==數字系統的顯示訊息
LC_TIME="en_US"              <==時間系統的顯示資料
LC_COLLATE="en_US"           <==字串的比較與排序等
LC_MONETARY="en_US"          <==幣值格式的顯示等
LC_MESSAGES="en_US"          <==訊息顯示的內容,如功能表、錯誤訊息等
LC_ALL=                      <==整體語系的環境
....(後面省略)....

基本上,你可以逐一設定每個與語系有關的變數資料,但事實上,如果其他的語系變數都未設定, 且你有設定 LANG 或者是 LC_ALL 時,則其他的語系變數就會被這兩個變數所取代! 這也是為什麼我們在 Linux 當中,通常說明僅設定 LANG 或 LC_ALL 這兩個變數而已,因為他是最主要的設定變數! 好了,那麼你應該要覺得奇怪的是,為什麼在 Linux 主機的終端機介面 (tty1 ~ tty6) 的環境下,如果設定『 LANG=zh_TW.utf8 』這個設定值生效後,使用 man 或者其他訊息輸出時, 都會有一堆亂碼,尤其是使用 ls -l 這個參數時?

因為在 Linux 主機的終端機介面環境下是無法顯示像中文這麼複雜的編碼文字, 所以就會產生亂碼了。也就是如此,我們才會必須要在 tty1 ~ tty6 的環境下, 加裝一些中文化介面的軟體,才能夠看到中文啊!不過,如果你是在 MS Windows 主機以遠端連線伺服器的軟體連線到主機的話,那麼,嘿嘿!其實文字介面確實是可以看到中文的。 此時反而你得要在 LC_ALL 設定中文編碼才好呢!

Tips澳门新濠3559 12無論如何,如果發生一些亂碼的問題,那麼設定系統裡面保有的語系編碼, 例如: en_US 或 en_US.utf8 等等的設定,應該就 OK 的啦!好了,那麼系統預設支援多少種語系呢? 當我們使用 locale 時,系統是列出目前 Linux 主機內保有的語系檔案, 這些語系檔案都放置在: /usr/lib/locale/ 這個目錄中。

你當然可以讓每個使用者自己去調整自己喜好的語系,但是整體系統預設的語系定義在哪裡呢? 其實就是在 /etc/locale.conf 囉!這個檔案在 CentOS 7.x 的內容有點像這樣:

[dmtsai@study ~]$ cat /etc/locale.conf
LANG=zh_TW.utf8
LC_NUMERIC=zh_TW.UTF-8
LC_TIME=zh_TW.UTF-8
LC_MONETARY=zh_TW.UTF-8
LC_PAPER=zh_TW.UTF-8
LC_MEASUREMENT=zh_TW.UTF-8

因為鳥哥在第三章的安裝時選擇的是中文語系安裝畫面, 所以這個檔案預設就會使用中文編碼啦!你也可以自行將他改成你想要的語系編碼即可。

Tips澳门新濠3559 13假設你有一個純文字檔案原本是在 Windows 底下建立的,那麼這個檔案預設可能是 big5 的編碼格式。 在你將這個檔案上傳到 Linux 主機後,在 X window 底下打開時,咦!怎麼中文字通通變成亂碼了? 別擔心!因為如上所示, Linux 目前大多預設是萬國碼顯示嘛!你只要將開啟該檔案的軟體編碼由 utf8 改成 big5 就能夠看到正確的中文了!

例題:
鳥哥原本是中文語系,所有顯示的資料通通是中文。但為了網頁顯示的關係,需要將輸出轉成英文 (en_US.utf8) 的語系來展示才行。 但鳥哥又不想要寫入設定檔!畢竟是暫時顯示用的~那該如何處理?
答:
其實不很難,重點是 LANG 及 LC_ALL 而已!但在 CentOS 7 當中,你要讓 LC_ALL 生效時,得要使用 export 轉成環境變數才行耶! 所以就是這樣搞:
[dmtsai@study ~]$ locale
LANG=zh_TW.UTF-8
LC_CTYPE="zh_TW.UTF-8"
LC_NUMERIC="zh_TW.UTF-8"
LC_TIME="zh_TW.UTF-8"

[dmtsai@study ~]$ LANG=en_US.utf8; locale
[dmtsai@study ~]$ export LC_ALL=en_US.utf8; locale  # 你就會看到與上頭有不同的語系囉!

Top

style="font-size: xx-small;">mount

style="font-family: 宋体;">這是將硬碟或者是光碟、軟碟接掛上系統的指令!之前有提過,在 Linux 下面,每一個裝置都是一個檔案(或目錄),而每一種裝置的檔案型態都不相同,因此對於 mount 後面加的參數就很重要囉:例如:   

[root@tsai /root]# mount -t iso9660 /dev/cdrom /mnt/cdrom <=光碟 
[root@tsai /root]# mount -t vfat /dev/fd0 /mnt/floppy     <=軟碟(windows 系統檔) 
[root@tsai /root]# mount -t ext2 /dev/fd0 /mnt/floppy     <=軟碟(Linux 系統檔) 
[root@tsai /root]# mount -t ext2 /dev/hdc1 /mnt/harddisk  <=硬碟

光碟裝置檔=/dev/cdrom、軟碟裝置檔=/dev/fd0、硬碟裝置檔=/dev/hdxx。 
如上表所示, -t 是參數,至於 iso9660, vfat, ext2則是這些裝置的檔案型態!後面接的則是這個裝置所在的目錄!千萬記得,這些目錄需要是早已存在的,而且最好是空的目錄,不然目錄裡面原本存在的檔案會不見去! 
另外,注意喔!當你 mount 上光碟機或軟碟的時候,請不要輕易的拿出磁片(而且光碟片也不會被你退出),因為會造成系統讀取的錯誤!你應該用 umount 來退出!指令為 
umount  /mnt/cdrom  (umount  裝置所在目錄)

style="font-size: xx-small;">fdformat

style="font-family: 宋体;">這是用來『低階格式化』軟碟的指令。(注意:軟碟的裝置檔為 /dev/fd0 )不必將軟碟 mount 就可以格式化了,指令內容為:   

[root@tsai /root]# fdformat /dev/fd0H1440

注意喔!在上面的裝置檔案為 /dev/fd0H1440 ,其中加在 /fd0 之後的 H1440 為表示 1.44MB 的軟碟容量!在低階格式化之後,還要將軟碟的檔案格式化為 Linux 的 ext2 之型態,則需要使用 mke2fs 指令!

style="font-size: xx-small;">fdisk

style="font-family: 宋体;">這是對硬碟(也可以對軟碟喔)做分割的程式。基本的用法為=> fdisk 裝置檔案,假設您有一顆硬碟要重新規劃,而這顆硬碟為 hdc ,則你可以輸入:   

[root@tsai /root]# fdisk /dev/hdc

然後,按下 m 會出現 help 的選單,要知道的大概只有兩個子指令,一個是刪除 partition 按 d ,一個是增加 partition 按 n,假設你要增加一個 primary partition,按下 n 再按 p 再按你要的 primary partition 號碼(1-4)就可以了。假設你的 hdc 需要規劃成為一個硬碟(即 hdc1)則在輸入 fdisk /dev/hdc 後,需要按: 
n(增加) -> p(primary partition) -> 1(partition 1) -> w (儲存寫入) -> q (離開) 

style="font-family: 宋体;">同樣的,分割完硬碟(或軟碟)後,要以 mke2fs 格式化!

style="font-size: xx-small;">mke2fs

這是用來將磁碟格式化成 Linux 系統檔的指令。基本上,只要寫入對的裝置檔案就可以了。例如我們要格式化軟碟的話,或是新的硬碟 hdc1 ,則可以如此寫:   

[root@tsai /root]# mke2fs -c /dev/fd0 
[root@tsai /root]# mke2fs -c /dev/hdc1

要記得的是,在你做這個格式化的動作時,軟碟與硬碟均不可 mount 到 Linux 的系統中。

style="font-size: xx-small;">mkbootdisk

style="font-family: 宋体;">這是製作開機磁片的指令。指令很簡單:   

[root@tsai /root]# mkbootdisk --device /dev/fd0 `uname -r`

其中, `uname -r` 是目前 Linux 系統所使用的核心版本,如果你有多個核心版本的話,你以可以直接輸入核心版本。例如在這個網頁中所使用的核心有兩個版本,一個是 2.2.12-20,另一個是 2.2.18,若要以 2.2.18 設定開機的話,可以使用: mkbootdisk  --device  /dev/fd0  2.2.18 !

style="font-size: xx-small;">badblocks

style="font-family: 宋体;">這是用來檢查硬碟或軟碟有沒有壞軌的指令,你可以用底下的方式來下達:   

[root@tsai /root]# badblocks  -svw  /dev/hdc1

style="font-size: xx-small;">fsck

style="font-family: 宋体;">這是用來檢查與修正硬碟錯誤的指令。注意:通常只有身為 root 且你的系統有問題的時候才使用這個指令,否則在正常狀況下使用此一指令,可能會造成對檔案的危害!   

[root@tsai /root]#  fsck  /dev/hdc1

通常使用這個指令的場合都是在系統出現極大的問題,導致你在 Linux 開機的時候得進入單人單機模式下進行維護的行為時,才必須使用此一指令!

style="font-size: xx-small;">rpm

這是一個安裝或者是解安裝 RedHat 軟體的指令,在 RedHat 中已經有設定了一些有點像 Windows 的軟體安裝功能,這就是 rpm 這套軟體了!而 rpm 所安裝的軟體又分為兩種形式,因此你可以分別使用下面兩種參數對不同的檔案進行安裝:   

[root@tsai /root]# rpm  -ivh  xxxxx.rpm  <==將 xxxxx.rpm 檔案安裝於 Linux 系統中 
[root@tsai /root]# rpm  -ivh  --nodeps xxxxx.rpm  <==將 xxxxx.rpm 檔案『強制』安裝於 Linux 系統中 
[root@tsai /root]# rpm  -Uvh  xxxxx.rpm  <==將 xxxxx.rpm 升級 
[root@tsai /root]# rpm  -e    xxxxx.rpm  <==將 xxxxx.rpm 解除安裝 
[root@tsai /root]# rpm  -q    squid  <==察看 squid 這一個軟體的版本 
[root@tsai /root]# rpm  --recompile  yyyyy.src.rpm  <==安裝檔名為 .src.rpm 的檔案!

這裡要注意的是, rpm 的檔案主要有兩種形式,一種是已經經過編譯的 i386.rpm 檔案,令一種是未經編譯的 .src.rpm 檔案,兩種檔案形式的安裝參數是不一樣的,請小心注意!

 

chkconfig usbarbitrator off

10.2.5 變數的有效範圍

蝦密?變數也有使用的『範圍』?沒錯啊~我們在上頭的 export 指令說明中,就提到了這個概念了。如果在跑程式的時候,有父程序與子程序的不同程序關係時, 則『變數』可否被引用與 export 有關。被 export 後的變數,我們可以稱他為『環境變數』! 環境變數可以被子程序所引用,但是其他的自訂變數內容就不會存在於子程序中。

Tips澳门新濠3559 14在某些不同的書籍會談到『全域變數, global variable』與『區域變數, local variable』。 在鳥哥的這個章節中,基本上你可以這樣看待:
環境變數=全域變數
自訂變數=區域變數

在學理方面,為什麼環境變數的資料可以被子程序所引用呢?這是因為記憶體配置的關係!理論上是這樣的:

  • 當啟動一個 shell,作業系統會分配一記憶區塊給 shell 使用,此記憶體內之變數可讓子程序取用
  • 若在父程序利用 export 功能,可以讓自訂變數的內容寫到上述的記憶區塊當中(環境變數);
  • 當載入另一個 shell 時 (亦即啟動子程序,而離開原本的父程序了),子 shell 可以將父 shell 的環境變數所在的記憶區塊導入自己的環境變數區塊當中。

透過這樣的關係,我們就可以讓某些變數在相關的程序之間存在,以幫助自己更方便的操作環境喔! 不過要提醒的是,這個『環境變數』與『bash 的操作環境』意思不太一樣,舉例來說, PS1 並不是環境變數, 但是這個 PS1 會影響到 bash 的介面 (提示字元嘛)!相關性要釐清喔!^_^

Top


  1. 限制或解除使用者家目錄所在(change root, 簡稱 chroot):為了避免使用者在您的 Linux 系統當中隨意逛大街,意指離開使用者家目錄而進入到 Linux 系統的其他目錄去,所以將使用者的工作範圍『侷限』在使用者的家目錄底下,嗯!實在是個不錯的好主意!FTP 可以限制使用者僅能在自己的家目錄當中活動喔!如此一來,由於使用者無法離開自己的家目錄,而且登入 FTP 後,顯示的『根目錄』就是自己家目錄的內容,這種環境稱之為 change root ,簡稱 chroot ,改變根目錄的意思啦!這有什麼好處呢?當一個惡意的使用者以 FTP 登入您的系統當中,如果沒有 chroot 的環境下,他可以到 /etc, /usr/local, /home 等其他重要目錄底下去察看檔案資料,尤其是很重要的 /etc/ 底下的設定檔,如 /etc/passwd 等等。這樣他就有辦法取得系統的某些重要資訊,用來『入侵』您的系統呢!所以在 chroot 的環境下,當然就比較安全一些咯!

澳门新濠3559 15

10.2.6 變數鍵盤讀取、陣列與宣告: read, array, declare

我們上面提到的變數設定功能,都是由指令列直接設定的,那麼,可不可以讓使用者能夠經由鍵盤輸入? 什麼意思呢?是否記得某些程式執行的過程當中,會等待使用者輸入 "yes/no" 之類的訊息啊? 在 bash 裡面也有相對應的功能喔!此外,我們還可以宣告這個變數的屬性,例如:陣列或者是數字等等的。底下就來看看吧!

  • read

要讀取來自鍵盤輸入的變數,就是用 read 這個指令了。這個指令最常被用在 shell script 的撰寫當中, 想要跟使用者對談?用這個指令就對了。關於 script 的寫法,我們會在第十三章介紹,底下先來瞧一瞧 read 的相關語法吧!

[dmtsai@study ~]$ read [-pt] variable
選項與參數:
-p  :後面可以接提示字元!
-t  :後面可以接等待的『秒數!』這個比較有趣~不會一直等待使用者啦!

範例一:讓使用者由鍵盤輸入一內容,將該內容變成名為 atest 的變數
[dmtsai@study ~]$ read atest
This is a test        <==此時游標會等待你輸入!請輸入左側文字看看
[dmtsai@study ~]$ echo ${atest}
This is a test          <==你剛剛輸入的資料已經變成一個變數內容!

範例二:提示使用者 30 秒內輸入自己的大名,將該輸入字串作為名為 named 的變數內容
[dmtsai@study ~]$ read -p "Please keyin your name: " -t 30 named
Please keyin your name: VBird Tsai   <==注意看,會有提示字元喔!
[dmtsai@study ~]$ echo ${named}
VBird Tsai        <==輸入的資料又變成一個變數的內容了!

read 之後不加任何參數,直接加上變數名稱,那麼底下就會主動出現一個空白行等待你的輸入(如範例一)。 如果加上 -t 後面接秒數,例如上面的範例二,那麼 30 秒之內沒有任何動作時, 該指令就會自動略過了~如果是加上 -p ,嘿嘿!在輸入的游標前就會有比較多可以用的提示字元給我們參考! 在指令的下達裡面,比較美觀啦! ^_^

  • declare / typeset

declare 或 typeset 是一樣的功能,就是在『宣告變數的類型』。如果使用 declare 後面並沒有接任何參數,那麼 bash 就會主動的將所有的變數名稱與內容通通叫出來,就好像使用 set 一樣啦! 那麼 declare 還有什麼語法呢?看看先:

[dmtsai@study ~]$ declare [-aixr] variable
選項與參數:
-a  :將後面名為 variable 的變數定義成為陣列 (array) 類型
-i  :將後面名為 variable 的變數定義成為整數數字 (integer) 類型
-x  :用法與 export 一樣,就是將後面的 variable 變成環境變數;
-r  :將變數設定成為 readonly 類型,該變數不可被更改內容,也不能 unset

範例一:讓變數 sum 進行 100+300+50 的加總結果
[dmtsai@study ~]$ sum=100+300+50
[dmtsai@study ~]$ echo ${sum}
100+300+50  <==咦!怎麼沒有幫我計算加總?因為這是文字型態的變數屬性啊!
[dmtsai@study ~]$ declare -i sum=100+300+50
[dmtsai@study ~]$ echo ${sum}
450         <==瞭乎??

由於在預設的情況底下, bash 對於變數有幾個基本的定義:

  • 變數類型預設為『字串』,所以若不指定變數類型,則 1+2 為一個『字串』而不是『計算式』。 所以上述第一個執行的結果才會出現那個情況的;
  • bash 環境中的數值運算,預設最多僅能到達整數形態,所以 1/3 結果是 0;

現在你曉得為啥你需要進行變數宣告了吧?如果需要非字串類型的變數,那就得要進行變數的宣告才行啦! 底下繼續來玩些其他的 declare 功能。

範例二:將 sum 變成環境變數
[dmtsai@study ~]$ declare -x sum
[dmtsai@study ~]$ export | grep sum
declare -ix sum="450"  <==果然出現了!包括有 i 與 x 的宣告!

範例三:讓 sum 變成唯讀屬性,不可更動!
[dmtsai@study ~]$ declare -r sum
[dmtsai@study ~]$ sum=tesgting
-bash: sum: readonly variable  <==老天爺~不能改這個變數了!

範例四:讓 sum 變成非環境變數的自訂變數吧!
[dmtsai@study ~]$ declare +x sum  <== 將 - 變成 + 可以進行『取消』動作
[dmtsai@study ~]$ declare -p sum  <== -p 可以單獨列出變數的類型
declare -ir sum="450" <== 看吧!只剩下 i, r 的類型,不具有 x 囉!

declare 也是個很有用的功能~尤其是當我們需要使用到底下的陣列功能時, 他也可以幫我們宣告陣列的屬性喔!不過,老話一句,陣列也是在 shell script 比較常用的啦! 比較有趣的是,如果你不小心將變數設定為『唯讀』,通常得要登出再登入才能復原該變數的類型了! @_@

  • 陣列 (array) 變數類型

某些時候,我們必須使用陣列來宣告一些變數,這有什麼好處啊?在一般人的使用上, 果然是看不出來有什麼好處的!不過,如果您曾經寫過程式的話,那才會比較瞭解陣列的意義~ 陣列對寫數值程式的設計師來說,可是不能錯過學習的重點之一哩!好!不囉唆~ 那麼要如何設定陣列的變數與內容呢?在 bash 裡頭,陣列的設定方式是:

var[index]=content

意思是說,我有一個陣列名稱為 var ,而這個陣列的內容為 var[1]=小明, var[2]=大明, var[3]=好明 .... 等等,那個 index 就是一些數字啦,重點是用中刮號 ([ ]) 來設定的。 目前我們 bash 提供的是一維陣列。老實說,如果您不必寫一些複雜的程式, 那麼這個陣列的地方,可以先略過,等到有需要再來學習即可!因為要製作出陣列, 通常與迴圈或者其他判斷式交互使用才有比較高的存在意義!

範例:設定上面提到的 var[1] ~ var[3] 的變數。
[dmtsai@study ~]$ var[1]="small min"
[dmtsai@study ~]$ var[2]="big min"
[dmtsai@study ~]$ var[3]="nice min"
[dmtsai@study ~]$ echo "${var[1]}, ${var[2]}, ${var[3]}"
small min, big min, nice min

陣列的變數類型比較有趣的地方在於『讀取』,一般來說,建議直接以 ${陣列} 的方式來讀取,比較正確無誤的啦!這也是為啥鳥哥一開始就建議你使用 ${變數} 來記憶的原因!

Top

系統管理員

 

這個動作是讓USB的使用從系統管理,還原到Service Console之下。在設定完之後,必須重新啟動ESX,輸入「reboot」重新啟動ESX。重新啟動之後,當插入USB硬碟時,系統會自動有訊息,並且提示已經抓到USB硬碟,並且指定到sda這個硬碟了。

10.2.7 與檔案系統及程序的限制關係: ulimit

想像一個狀況:我的 Linux 主機裡面同時登入了十個人,這十個人不知怎麼搞的, 同時開啟了 100 個檔案,每個檔案的大小約 10MBytes ,請問一下, 我的 Linux 主機的記憶體要有多大才夠? 10*100*10 = 10000 MBytes = 10GBytes ... 老天爺,這樣,系統不掛點才有鬼哩!為了要預防這個情況的發生,所以我們的 bash 是可以『限制使用者的某些系統資源』的,包括可以開啟的檔案數量, 可以使用的 CPU 時間,可以使用的記憶體總量等等。如何設定?用 ulimit 吧!

[dmtsai@study ~]$ ulimit [-SHacdfltu] [配額]
選項與參數:
-H  :hard limit ,嚴格的設定,必定不能超過這個設定的數值;
-S  :soft limit ,警告的設定,可以超過這個設定值,但是若超過則有警告訊息。
      在設定上,通常 soft 會比 hard 小,舉例來說,soft 可設定為 80 而 hard 
      設定為 100,那麼你可以使用到 90 (因為沒有超過 100),但介於 80~100 之間時,
      系統會有警告訊息通知你!
-a  :後面不接任何選項與參數,可列出所有的限制額度;
-c  :當某些程式發生錯誤時,系統可能會將該程式在記憶體中的資訊寫成檔案(除錯用),
      這種檔案就被稱為核心檔案(core file)。此為限制每個核心檔案的最大容量。
-f  :此 shell 可以建立的最大檔案容量(一般可能設定為 2GB)單位為 Kbytes
-d  :程序可使用的最大斷裂記憶體(segment)容量;
-l  :可用於鎖定 (lock) 的記憶體量
-t  :可使用的最大 CPU 時間 (單位為秒)
-u  :單一使用者可以使用的最大程序(process)數量。

範例一:列出你目前身份(假設為一般帳號)的所有限制資料數值
[dmtsai@study ~]$ ulimit -a
core file size          (blocks, -c) 0          <==只要是 0 就代表沒限制
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited  <==可建立的單一檔案的大小
pending signals                 (-i) 4903
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024       <==同時可開啟的檔案數量
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 4096
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

範例二:限制使用者僅能建立 10MBytes 以下的容量的檔案
[dmtsai@study ~]$ ulimit -f 10240
[dmtsai@study ~]$ ulimit -a | grep 'file size'
core file size          (blocks, -c) 0
file size               (blocks, -f) 10240 <==最大量為10240Kbyes,相當10Mbytes

[dmtsai@study ~]$ dd if=/dev/zero of=123 bs=1M count=20
File size limit exceeded (core dumped) <==嘗試建立 20MB 的檔案,結果失敗了!

[dmtsai@study ~]$ rm 123  <==趕快將這個檔案刪除囉!同時你得要登出再次的登入才能解開 10M 的限制

還記得我們在第七章 Linux 磁碟檔案系統裡面提到過,單一 filesystem 能夠支援的單一檔案大小與 block 的大小有關。但是檔案系統的限制容量都允許的太大了!如果想要讓使用者建立的檔案不要太大時, 我們是可以考慮用 ulimit 來限制使用者可以建立的檔案大小喔!利用 ulimit -f 就可以來設定了!例如上面的範例二,要注意單位喔!單位是 Kbytes。 若改天你一直無法建立一個大容量的檔案,記得瞧一瞧 ulimit 的資訊喔!

Tips澳门新濠3559 16想要復原 ulimit 的設定最簡單的方法就是登出再登入,否則就是得要重新以 ulimit 設定才行! 不過,要注意的是,一般身份使用者如果以 ulimit 設定了 -f 的檔案大小, 那麼他『只能繼續減小檔案容量,不能增加檔案容量喔!』另外,若想要管控使用者的 ulimit 限值, 可以參考第十三章的 pam 的介紹。

Top

style="font-size: xx-small;">su

這是一個用來轉換你身份成為 super user (系統管理員)的指令,任何人只要知道 root 的密碼,就可以成為 super user,所以密碼可千萬不要外流呀!由於 RedHat 在主機之外的終端機上,無法以 root 的身份直接連線,所以你需要以一般身份的 user 連線之後,再以 su 指令來成為 super user:   

[vbird@tsai vbird]# su  <==輸入指令 
Password:       <==在這裡輸入 root 的密碼 
[root@tsai vibrd]#      <==看,使用者名稱變囉!

style="font-size: xx-small;">clear

style="font-family: 宋体;">這是用來清除螢幕畫面用的,沒有什麼太大的用處。通常是你覺得畫面太亂的時候輸入用的!直接輸入 clear 就可以了!

style="font-size: xx-small;">dmesg

style="font-family: 宋体;">在開機的時候你會發現有很多的訊息出現吧,例如 CPU 的形式、硬碟、光碟型號及硬碟分割表等等。但是訊息都是『刷』的一聲就跑過去了!這些訊息有時候對於系統管理員是很重要的,因為他提供了系統的資訊呀!要看這些訊息你可以用 dmesg 這個指令來觀看!   

[root@tsai /root]# dmesg|more

加上 |more 的原因是因為訊息太多了,所以可以加入這個管線指令來使畫面暫停!

style="font-size: xx-small;">groupadd

style="font-family: 宋体;">這是用來增加群組的指令,通常鳥哥都不用這個指令的,因為有更容易使用的指令 /bin/userconf 可以使用哩(注意,在 RedHat 7.0 以後的版本,就要使用 /sbin/userconf 哩)!

style="font-size: xx-small;">useradd

style="font-family: 宋体;">這是用來增加使用者的指令,鳥哥通常不使用這個指令,你可以使用 /bin/userconf 這個指令,更簡單易用喔(是視窗介面的喔!)(注意,在 RedHat 7.0 以後的版本,就要使用 /sbin/userconf 哩)

style="font-size: xx-small;">userconf

style="font-family: 宋体;">這是用來增加使用者、群組等,且以視窗為介面的一個指令!如果你是以遠端登入,並使用 su 指令成為 super user 的話,直接輸入 userconf 可能會找不到這個指令,你可以輸入: /bin/userconf 來啟動這個指令!(注意,在 RedHat 7.0 以後的版本,就要使用 /sbin/userconf 哩),由於這個指令的圖示較多,請到這裡來看看!

style="font-size: xx-small;">passwd

style="font-family: 宋体;">這是用來更改密碼的指令,很簡單,只要在提示字元下輸入 passwd ,然後輸入目前的密碼,再輸入兩次欲修改成的新密碼,就修改OK了!不過要注意,密碼的形式:不能與帳號相同,且需要 8 個字元以上,另外,帳號也不能太簡單!否則系統會不接受!   

[vbird@tsai vbird]# passwd 
Changing password for vbird 
(current) UNIX password:      <==這裡輸入目前的密碼 
New UNIX password:     <==這裡輸入新的密碼 
Retype new UNIX password:     <==這裡再輸入新的密碼一次 
passwd: all authentication tokens updated successfully

style="font-size: xx-small;">who

style="font-family: 宋体;">這是用來視察目前在系統上的使用者指令,你也可以使用 w 這個指令來下達動作。   

[root@tsai /root]# who 
root     pts/0    Aug  2 20:43

[root@tsai /root]# w 
  8:48pm  up 4 days,  5:08,  1 user,  load average: 0.00, 0.00, 0.00 
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU  WHAT 
root     pts/0    192.168.1.2       8:43pm  0.00s  0.38s   ?     -

基本上,who 與 w 的功能是相同的,只是 who 僅列出使用者名稱與登入時間,至於 w 則會列出使用者的

  • 來源位址(IP):就是 FROM 那一項即是IP;
  • 登入時間:即是 LOGIN@ 那一項;
  • 工作項目:就是 WHAT 那一項!

style="font-size: xx-small;">whoami

style="font-family: 宋体;">這是用來確認你目前的身份的指令,由於你可能會有幾個身份在你的機器上,所以需要以這個指令來確認你的身份,不過由於 Linux 會將使用者名稱寫在提示字元上,所以這個指令目前比較少用到了。

style="font-size: xx-small;">top

style="font-family: 宋体;">這是用來指示目前系統的服務項目的動態資料。   

[root@tsai /root]# top 
 10:14pm  up 4 days,  6:34,  1 user,  load average: 0.01, 0.01, 0.00 
40 processes: 39 sleeping, 1 running, 0 zombie, 0 stopped 
CPU states:  0.5% user,  0.3% system,  0.0% nice, 99.0% idle 
Mem:   63124K av,  60844K used,   2280K free,  23604K shrd,  35648K buff 
Swap: 104380K av,   1684K used, 102696K free                 10788K cached

  PID USER     PRI  NI  SIZE  RSS SHARE STAT  LIB %CPU %MEM   TIME COMMAND 
 3121 root      20   0  1016 1016   820 R       0  0.9  1.6   0:47 top 
    1 root       0   0   380  368   320 S       0  0.0  0.5   0:04 init 
    2 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 kflushd 
    3 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 kupdate 
    4 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 kpiod 
    5 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 kswapd 
    6 root     -20 -20     0    0     0 SW<     0  0.0  0.0   0:00 mdrecoveryd 
  366 bin        0   0   308  288   228 S       0  0.0  0.4   0:00 portmap 
  382 root       0   0   392  376   328 S       0  0.0  0.5   0:00 apmd 
  435 root       0   0   488  480   388 S       0  0.0  0.7   0:00 syslogd 
  446 root       0   0   688  676   316 S       0  0.0  1.0   0:00 klogd

輸入 top 之後,會出現類似上面的顯示情況。上圖中說明了你的記憶體有63124K,而下方的面版說明了目前正在執行中的工作內容!

style="font-size: xx-small;">free

style="font-family: 宋体;">這是用來察看記憶體的指令。   

[root@tsai /root]# free 
             total       used       free     shared    buffers     cached 
Mem:         63124      60732       2392      23136      35648      10796 
-/+ buffers/cache:      14288      48836 
Swap:       104380       1684     102696

如上圖中,說明總記憶體容量為 63124K,而使用了 60732K,另外,虛擬記憶體(Swap)共有 104380K(亦即共有 100MB 的虛擬記憶體)。

style="font-size: xx-small;">quotacheck, edquota

這些檔案是用來限制使用者在 Linux 主機上的硬碟使用容量。例如,有十個人同時分享一個 2G 的硬碟空間,但是有一個使用者就用了 1.5 GB 的容量,那相對的,其他人可使用的空間就只有剩下 0.5G 啦!不公平對不對,而且也怕被使用者填充大量的垃圾,而使用系統資源被瓜分掉!因此就有 Quota 這個咚咚的出現啦!由於執行的步驟較為繁瑣,所以額外寫了一個頁面,請到這裡來看看。

 

澳门新濠3559 17

10.2.8 變數內容的刪除、取代與替換 (Optional)

變數除了可以直接設定來修改原本的內容之外,有沒有辦法透過簡單的動作來將變數的內容進行微調呢? 舉例來說,進行變數內容的刪除、取代與替換等!是可以的!我們可以透過幾個簡單的小步驟來進行變數內容的微調喔! 底下就來試試看!

  • 變數內容的刪除與取代

變數的內容可以很簡單的透過幾個咚咚來進行刪除喔!我們使用 PATH 這個變數的內容來做測試好了。 請你依序進行底下的幾個例子來玩玩,比較容易感受的到鳥哥在這裡想要表達的意義:

範例一:先讓小寫的 path 自訂變數設定的與 PATH 內容相同
[dmtsai@study ~]$ path=${PATH}
[dmtsai@study ~]$ echo ${path}
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

範例二:假設我不喜歡 local/bin,所以要將前 1 個目錄刪除掉,如何顯示?
[dmtsai@study ~]$ echo ${path#/*local/bin:}
/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

上面這個範例很有趣的!他的重點可以用底下這張表格來說明:

${variable#/*local/bin:}
   上面的特殊字體部分是關鍵字!用在這種刪除模式所必須存在的

${variable#/*local/bin:}
   這就是原本的變數名稱,以上面範例二來說,這裡就填寫 path 這個『變數名稱』啦!

${variable#/*local/bin:}
   這是重點!代表『從變數內容的最前面開始向右刪除』,且僅刪除最短的那個

${variable#/*local/bin:}
   代表要被刪除的部分,由於 # 代表由前面開始刪除,所以這裡便由開始的 / 寫起。
   需要注意的是,我們還可以透過萬用字元 * 來取代 0 到無窮多個任意字元

   以上面範例二的結果來看, path 這個變數被刪除的內容如下所示:
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

很有趣吧!這樣瞭解了 # 的功能了嗎?接下來讓我們來看看底下的範例三!

範例三:我想要刪除前面所有的目錄,僅保留最後一個目錄
[dmtsai@study ~]$ echo ${path#/*:}
/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
# 由於一個 # 僅刪除掉最短的那個,因此他刪除的情況可以用底下的刪除線來看:
# /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

[dmtsai@study ~]$ echo ${path##/*:}
/home/dmtsai/bin
# 嘿!多加了一個 # 變成 ## 之後,他變成『刪除掉最長的那個資料』!亦即是:
# /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

非常有趣!不是嗎?因為在 PATH 這個變數的內容中,每個目錄都是以冒號『:』隔開的, 所以要從頭刪除掉目錄就是介於斜線 (/) 到冒號 (:) 之間的資料!但是 PATH 中不止一個冒號 (:) 啊! 所以 # 與 ## 就分別代表:

  • # :符合取代文字的『最短的』那一個;
  • ##:符合取代文字的『最長的』那一個

上面談到的是『從前面開始刪除變數內容』,那麼如果想要『從後面向前刪除變數內容』呢? 這個時候就得使用百分比 (%) 符號了!來看看範例四怎麼做吧!

範例四:我想要刪除最後面那個目錄,亦即從 : 到 bin 為止的字串
[dmtsai@study ~]$ echo ${path%:*bin}
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin
# 注意啊!最後面一個目錄不見去!
# 這個 % 符號代表由最後面開始向前刪除!所以上面得到的結果其實是來自如下:
# /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

範例五:那如果我只想要保留第一個目錄呢?
[dmtsai@study ~]$ echo ${path%%:*bin}
/usr/local/bin
# 同樣的, %% 代表的則是最長的符合字串,所以結果其實是來自如下:
# /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin

由於我是想要由變數內容的後面向前面刪除,而我這個變數內容最後面的結尾是『/home/dmtsai/bin』, 所以你可以看到上面我刪除的資料最終一定是『bin』,亦即是『:*bin』那個 * 代表萬用字元! 至於 % 與 %% 的意義其實與 # 及 ## 類似!這樣理解否?

例題:
假設你是 dmtsai ,那你的 MAIL 變數應該是 /var/spool/mail/dmtsai 。假設你只想要保留最後面那個檔名 (dmtsai), 前面的目錄名稱都不要了,如何利用 $MAIL 變數來達成?
答:
題意其實是這樣『/var/spool/mail/dmtsai』,亦即刪除掉兩條斜線間的所有資料(最長符合)。 這個時候你就可以這樣做即可:
[dmtsai@study ~]$ echo ${MAIL##/*/}
相反的,如果你只想要拿掉檔名,保留目錄的名稱,亦即是『/var/spool/mail/dmtsai』 (最短符合)。但假設你並不知道結尾的字母為何,此時你可以利用萬用字元來處理即可,如下所示:
[dmtsai@study ~]$ echo ${MAIL%/*}

瞭解了刪除功能後,接下來談談取代吧!繼續玩玩範例六囉!

範例六:將 path 的變數內容內的 sbin 取代成大寫 SBIN:
[dmtsai@study ~]$ echo ${path/sbin/SBIN}
/usr/local/bin:/usr/bin:/usr/local/SBIN:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
# 這個部分就容易理解的多了!關鍵字在於那兩個斜線,兩斜線中間的是舊字串
# 後面的是新字串,所以結果就會出現如上述的特殊字體部分囉!

[dmtsai@study ~]$ echo ${path//sbin/SBIN}
/usr/local/bin:/usr/bin:/usr/local/SBIN:/usr/SBIN:/home/dmtsai/.local/bin:/home/dmtsai/bin
# 如果是兩條斜線,那麼就變成所有符合的內容都會被取代喔!

我們將這部份作個總結說明一下:

變數設定方式 說明
${變數#關鍵字}
${變數##關鍵字}
若變數內容從頭開始的資料符合『關鍵字』,則將符合的最短資料刪除
若變數內容從頭開始的資料符合『關鍵字』,則將符合的最長資料刪除
${變數%關鍵字}
${變數%%關鍵字}
若變數內容從尾向前的資料符合『關鍵字』,則將符合的最短資料刪除
若變數內容從尾向前的資料符合『關鍵字』,則將符合的最長資料刪除
${變數/舊字串/新字串}
${變數//舊字串/新字串}
若變數內容符合『舊字串』則『第一個舊字串會被新字串取代』
若變數內容符合『舊字串』則『全部的舊字串會被新字串取代』
  • 變數的測試與內容替換

在某些時刻我們常常需要『判斷』某個變數是否存在,若變數存在則使用既有的設定,若變數不存在則給予一個常用的設定。 我們舉底下的例子來說明好了,看看能不能較容易被你所理解呢!

範例一:測試一下是否存在 username 這個變數,若不存在則給予 username 內容為 root
[dmtsai@study ~]$ echo ${username}
           <==由於出現空白,所以 username 可能不存在,也可能是空字串
[dmtsai@study ~]$ username=${username-root}
[dmtsai@study ~]$ echo ${username}
root       <==因為 username 沒有設定,所以主動給予名為 root 的內容。
[dmtsai@study ~]$ username="vbird tsai" <==主動設定 username 的內容
[dmtsai@study ~]$ username=${username-root}
[dmtsai@study ~]$ echo ${username}
vbird tsai <==因為 username 已經設定了,所以使用舊有的設定而不以 root 取代

在上面的範例中,重點在於減號『 - 』後面接的關鍵字!基本上你可以這樣理解:

new_var=${old_var-content}
   新的變數,主要用來取代舊變數。新舊變數名稱其實常常是一樣的

new_var=${old_var-content}
   這是本範例中的關鍵字部分!必須要存在的哩!

new_var=${old_var-content}
   舊的變數,被測試的項目!

new_var=${old_var-content}
   變數的『內容』,在本範例中,這個部分是在『給予未設定變數的內容』

不過這還是有點問題!因為 username 可能已經被設定為『空字串』了!果真如此的話,那你還可以使用底下的範例來給予 username 的內容成為 root 喔!

範例二:若 username 未設定或為空字串,則將 username 內容設定為 root
[dmtsai@study ~]$ username=""
[dmtsai@study ~]$ username=${username-root}
[dmtsai@study ~]$ echo ${username}
      <==因為 username 被設定為空字串了!所以當然還是保留為空字串!
[dmtsai@study ~]$ username=${username:-root}
[dmtsai@study ~]$ echo ${username}
root  <==加上『 : 』後若變數內容為空或者是未設定,都能夠以後面的內容替換!

在大括號內有沒有冒號『 : 』的差別是很大的!加上冒號後,被測試的變數未被設定或者是已被設定為空字串時, 都能夠用後面的內容 (本例中是使用 root 為內容) 來替換與設定!這樣可以瞭解了嗎?除了這樣的測試之外, 還有其他的測試方法喔!鳥哥將他整理如下:

Tips澳门新濠3559 18底下的例子當中,那個 var 與 str 為變數,我們想要針對 str 是否有設定來決定 var 的值喔! 一般來說, str: 代表『str 沒設定或為空的字串時』;至於 str 則僅為『沒有該變數』。

變數設定方式 str 沒有設定 str 為空字串 str 已設定非為空字串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str
var=${str+expr} var= var=expr var=expr
var=${str:+expr} var= var= var=expr
var=${str=expr} str=expr
var=expr
str 不變
var=
str 不變
var=$str
var=${str:=expr} str=expr
var=expr
str=expr
var=expr
str 不變
var=$str
var=${str?expr} expr 輸出至 stderr var= var=$str
var=${str:?expr} expr 輸出至 stderr expr 輸出至 stderr var=$str

根據上面這張表,我們來進行幾個範例的練習吧! ^_^!首先讓我們來測試一下,如果舊變數 (str) 不存在時, 我們要給予新變數一個內容,若舊變數存在則新變數內容以舊變數來替換,結果如下:

測試:先假設 str 不存在 (用 unset) ,然後測試一下減號 (-) 的用法:
[dmtsai@study ~]$ unset str; var=${str-newvar}
[dmtsai@study ~]$ echo "var=${var}, str=${str}"
var=newvar, str=        <==因為 str 不存在,所以 var 為 newvar

測試:若 str 已存在,測試一下 var 會變怎樣?:
[dmtsai@study ~]$ str="oldvar"; var=${str-newvar}
[dmtsai@study ~]$ echo "var=${var}, str=${str}"
var=oldvar, str=oldvar  <==因為 str 存在,所以 var 等於 str 的內容

關於減號 (-) 其實上面我們談過了!這裡的測試只是要讓你更加瞭解,這個減號的測試並不會影響到舊變數的內容。 如果你想要將舊變數內容也一起替換掉的話,那麼就使用等號 (=) 吧!

測試:先假設 str 不存在 (用 unset) ,然後測試一下等號 (=) 的用法:
[dmtsai@study ~]$ unset str; var=${str=newvar}
[dmtsai@study ~]$ echo "var=${var}, str=${str}"
var=newvar, str=newvar  <==因為 str 不存在,所以 var/str 均為 newvar

測試:如果 str 已存在了,測試一下 var 會變怎樣?
[dmtsai@study ~]$ str="oldvar"; var=${str=newvar}
[dmtsai@study ~]$ echo "var=${var}, str=${str}"
var=oldvar, str=oldvar  <==因為 str 存在,所以 var 等於 str 的內容

那如果我只是想知道,如果舊變數不存在時,整個測試就告知我『有錯誤』,此時就能夠使用問號『 ? 』的幫忙啦! 底下這個測試練習一下先!

測試:若 str 不存在時,則 var 的測試結果直接顯示 "無此變數"
[dmtsai@study ~]$ unset str; var=${str?無此變數}
-bash: str: 無此變數    <==因為 str 不存在,所以輸出錯誤訊息 

測試:若 str 存在時,則 var 的內容會與 str 相同!
[dmtsai@study ~]$ str="oldvar"; var=${str?novar}
[dmtsai@study ~]$ echo "var=${var}, str=${str}"
var=oldvar, str=oldvar  <==因為 str 存在,所以 var 等於 str 的內容

基本上這種變數的測試也能夠透過 shell script 內的 if...then... 來處理, 不過既然 bash 有提供這麼簡單的方法來測試變數,那我們也可以多學一些嘛! 不過這種變數測試通常是在程式設計當中比較容易出現,如果這裡看不懂就先略過,未來有用到判斷變數值時,再回來看看吧! ^_^



我們可以再輸入「fdisk -l」來查看,發現剛才的USB硬碟已經被認識,在嘉許的系統中,是「/dev/sda」,並且其上有一個分割區是「/dev/sda1」。

10.3 命令別名與歷史命令

我們知道在早期的 DOS 年代,清除螢幕上的資訊可以使用 cls 來清除,但是在 Linux 裡面, 我們則是使用 clear 來清除畫面的。那麼可否讓 cls 等於 clear 呢?可以啊!用啥方法? link file 還是什麼的?別急!底下我們介紹不用 link file 的命令別名來達成。那麼什麼又是歷史命令? 曾經做過的舉動我們可以將他記錄下來喔!那就是歷史命令囉~底下分別來談一談這兩個玩意兒。

Top

壓縮指令

澳门新濠3559,FTP 的運作流程與使用到的 port

澳门新濠3559 19

10.3.1 命令別名設定: alias, unalias

命令別名是一個很有趣的東西,特別是你的慣用指令特別長的時候!還有, 增設預設的選項在一些慣用的指令上面,可以預防一些不小心誤殺檔案的情況發生的時候! 舉個例子來說,如果你要查詢隱藏檔,並且需要長的列出與一頁一頁翻看,那麼需要下達『 ls -al | more 』這個指令,鳥哥是覺得很煩啦! 要輸入好幾個單字!那可不可以使用 lm 來簡化呢?當然可以,你可以在命令列下面下達:

[dmtsai@study ~]$ alias lm='ls -al | more'

立刻多出了一個可以執行的指令喔!這個指令名稱為 lm ,且其實他是執行 ls -al | more 啊!真是方便。不過, 要注意的是:『alias 的定義規則與變數定義規則幾乎相同』, 所以你只要在 alias 後面加上你的 {『別名』='指令 選項...' }, 以後你只要輸入 lm 就相當於輸入了 ls -al|more 這一串指令!很方便吧!

另外,命令別名的設定還可以取代既有的指令喔!舉例來說,我們知道 root 可以移除 (rm) 任何資料!所以當你以 root 的身份在進行工作時,需要特別小心, 但是總有失手的時候,那麼 rm 提供了一個選項來讓我們確認是否要移除該檔案,那就是 -i 這個選項!所以,你可以這樣做:

[dmtsai@study ~]$ alias rm='rm -i'

那麼以後使用 rm 的時候,就不用太擔心會有錯誤刪除的情況了!這也是命令別名的優點囉! 那麼如何知道目前有哪些的命令別名呢?就使用 alias 呀!

[dmtsai@study ~]$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias lm='ls -al | more'
alias ls='ls --color=auto'
alias rm='rm -i'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

由上面的資料當中,你也會發現一件事情啊,我們在第九章的 vim 程式編輯器裡面提到 vi 與 vim 是不太一樣的,vim 可以多作一些額外的語法檢驗與顏色顯示。一般用戶會有 vi=vim 的命令別名,但是 root 則是單純使用 vi 而已。 如果你想要使用 vi 就直接以 vim 來開啟檔案的話,使用『 alias vi='vim' 』這個設定即可。 至於如果要取消命令別名的話,那麼就使用 unalias 吧!例如要將剛剛的 lm 命令別名拿掉,就使用:

[dmtsai@study ~]$ unalias lm

那麼命令別名與變數有什麼不同呢?命令別名是『新創一個新的指令, 你可以直接下達該指令』的,至於變數則需要使用類似『 echo 』指令才能夠呼叫出變數的內容! 這兩者當然不一樣!很多初學者在這裡老是搞不清楚!要注意啊! ^_^

例題:
DOS 年代,列出目錄與檔案就是 dir ,而清除螢幕就是 cls ,那麼如果我想要在 linux 裡面也使用相同的指令呢?
答:
很簡單,透過 clear 與 ls 來進行命令別名的建置:
alias cls='clear'
alias dir='ls -l'

Top

style="font-size: xx-small;">compress

這是用來壓縮及解壓縮檔名為 .Z 的壓縮檔。要注意的是,用 compress 壓縮的時候,會將原檔案殺掉而變成檔名為 .Z 的檔案,例如你壓縮一個名為 bird.test 的檔案,則壓縮完成後只會剩下 bird.test.Z 這個壓縮檔!當然,解壓縮的時候也是一樣的,壓縮檔不見了,只有剩下被解壓縮的檔案。指令如下:   

[root@tsai /root]# compress xxxxx        <==將 xxxxx 檔案壓縮成為 xxxxx.Z 檔名 
[root@tsai /root]# compress -d xxxxx.Z   <==將 xxxxx.Z 解壓縮成 xxxxx

上表中,解壓縮也可以用 uncompress xxxxx.Z 來達成!

style="font-size: xx-small;">gzip

這個也是一個壓縮指令,與 compress 很相似,指令的用法也相同!只是壓縮的檔名為 .gz 罷了!   

[root@tsai /root]# gzip  xxxxx         <==這是壓縮指令 
[root@tsai /root]# gzip  -d  xxxxx.gz  <==這是解壓縮指令

style="font-size: xx-small;">tar

style="font-family: 宋体;">這是一個很棒的壓縮指令,這個指令可以配合 gzip 來進行整個目錄的壓縮!例如有一個名為 bird 的目錄要被你整合成一個檔案,你可以使用:tar  -xvf  *.tar  *(其中 * 為你所要整合的目錄名稱)。   

[root@tsai /root]# tar  -cvf  bird.tar  bird  <==只有將目錄轉成一個檔案,沒有壓縮 
[root@tsai /root]# tar  -zcvf  bird.tar.gz  bird <==壓縮一整個目錄成為 .tar.gz 檔案

上面這個例子的 bird.tar 只是將 bird 這個目錄整個拷貝成為一個檔案而已,並沒有壓縮,而 bird.tar.gz 則是將 bird 這個目錄壓縮成為一個檔案!基本上,我們都是使用 -zxvf 來壓縮一整個目錄的!而如果是要解壓縮呢?由於有沒有壓縮所下的參數並不相同,所以針對兩種檔案也是有兩種參數的組合:   

[root@tsai /root]# tar  -xvf  bird.tar 
[root@tsai /root]# tar  -zxvf  bird.tar.gz

上面則是解壓縮的參數! 
注意了,用 compress 及 gzip 壓縮及解壓縮的時候,會將原檔案取代掉!而使用 tar 來壓縮及解壓縮的時候,原檔案將會與產生檔案同時存在!通常我們都是使用 tar 來進行壓縮或解壓縮的!(當然,你還是可以使用 compress 及 gzip 來壓縮一個大的檔案!)

FTP 正常情況下的連線方向:

將USB硬碟掛載入ESX的Service Console之下

10.3.2 歷史命令:history

前面我們提過 bash 有提供指令歷史的服務!那麼如何查詢我們曾經下達過的指令呢?就使用 history 囉!當然,如果覺得 histsory 要輸入的字元太多太麻煩,可以使用命令別名來設定呢! 不要跟我說還不會設定呦! ^_^

[dmtsai@study ~]$ alias h='history'

如此則輸入 h 等於輸入 history 囉!好了,我們來談一談 history 的用法吧!

[dmtsai@study ~]$ history [n]
[dmtsai@study ~]$ history [-c]
[dmtsai@study ~]$ history [-raw] histfiles
選項與參數:
n   :數字,意思是『要列出最近的 n 筆命令列表』的意思!
-c  :將目前的 shell 中的所有 history 內容全部消除
-a  :將目前新增的 history 指令新增入 histfiles 中,若沒有加 histfiles ,
      則預設寫入 ~/.bash_history
-r  :將 histfiles 的內容讀到目前這個 shell 的 history 記憶中;
-w  :將目前的 history 記憶內容寫入 histfiles 中!

範例一:列出目前記憶體內的所有 history 記憶
[dmtsai@study ~]$ history
# 前面省略
 1017  man bash
 1018  ll
 1019  history 
 1020  history
# 列出的資訊當中,共分兩欄,第一欄為該指令在這個 shell 當中的代碼,
# 另一個則是指令本身的內容喔!至於會秀出幾筆指令記錄,則與 HISTSIZE 有關!

範例二:列出目前最近的 3 筆資料
[dmtsai@study ~]$ history 3
 1019  history 
 1020  history
 1021  history 3

範例三:立刻將目前的資料寫入 histfile 當中
[dmtsai@study ~]$ history -w
# 在預設的情況下,會將歷史紀錄寫入 ~/.bash_history 當中!
[dmtsai@study ~]$ echo ${HISTSIZE}
1000

在正常的情況下,歷史命令的讀取與記錄是這樣的:

  • 當我們以 bash 登入 Linux 主機之後,系統會主動的由家目錄的 ~/.bash_history 讀取以前曾經下過的指令,那麼 ~/.bash_history 會記錄幾筆資料呢?這就與你 bash 的 HISTFILESIZE 這個變數設定值有關了!

  • 假設我這次登入主機後,共下達過 100 次指令,『等我登出時, 系統就會將 101~1100 這總共 1000 筆歷史命令更新到 ~/.bash_history 當中。』 也就是說,歷史命令在我登出時,會將最近的 HISTFILESIZE 筆記錄到我的紀錄檔當中啦!

  • 當然,也可以用 history -w 強制立刻寫入的!那為何用『更新』兩個字呢? 因為 ~/.bash_history 記錄的筆數永遠都是 HISTFILESIZE 那麼多,舊的訊息會被主動的拿掉! 僅保留最新的!

那麼 history 這個歷史命令只可以讓我查詢命令而已嗎?呵呵!當然不止啊! 我們可以利用相關的功能來幫我們執行命令呢!舉例來說囉:

[dmtsai@study ~]$ !number
[dmtsai@study ~]$ !command
[dmtsai@study ~]$ !!
選項與參數:
number  :執行第幾筆指令的意思;
command :由最近的指令向前搜尋『指令串開頭為 command』的那個指令,並執行;
!!      :就是執行上一個指令(相當於按↑按鍵後,按 Enter)

[dmtsai@study ~]$ history
   66  man rm
   67  alias
   68  man history
   69  history 
[dmtsai@study ~]$ !66  <==執行第 66 筆指令
[dmtsai@study ~]$ !!   <==執行上一個指令,本例中亦即 !66 
[dmtsai@study ~]$ !al  <==執行最近以 al 為開頭的指令(上頭列出的第 67 個)

經過上面的介紹,瞭乎?歷史命令用法可多了!如果我想要執行上一個指令, 除了使用上下鍵之外,我可以直接以『 !! 』 來下達上個指令的內容,此外, 我也可以直接選擇下達第 n 個指令,『 !n 』來執行,也可以使用指令標頭,例如 『 !vi 』來執行最近指令開頭是 vi 的指令列!相當的方便而好用!

基本上 history 的用途很大的!但是需要小心安全的問題!尤其是 root 的歷史紀錄檔案,這是 Cracker 的最愛!因為不小心的 root 會將很多的重要資料在執行的過程中會被紀錄在 ~/.bash_history 當中,如果這個檔案被解析的話,後果不堪吶!無論如何,使用 history 配合『 ! 』曾經使用過的指令下達是很有效率的一個指令下達方法!

  • 同一帳號同時多次登入的 history 寫入問題

有些朋友在練習 linux 的時候喜歡同時開好幾個 bash 介面,這些 bash 的身份都是 root 。 這樣會有 ~/.bash_history 的寫入問題嗎?想一想,因為這些 bash 在同時以 root 的身份登入, 因此所有的 bash 都有自己的 1000 筆記錄在記憶體中。因為等到登出時才會更新記錄檔,所以囉, 最後登出的那個 bash 才會是最後寫入的資料。唔!如此一來其他 bash 的指令操作就不會被記錄下來了 (其實有被記錄,只是被後來的最後一個 bash 所覆蓋更新了) 。

由於多重登入有這樣的問題,所以很多朋友都習慣單一 bash 登入,再用工作控制 (job control, 第四篇會介紹)來切換不同工作! 這樣才能夠將所有曾經下達過的指令記錄下來,也才方便未來系統管理員進行指令的 debug 啊!

  • 無法記錄時間

歷史命令還有一個問題,那就是無法記錄指令下達的時間。由於這 1000 筆歷史命令是依序記錄的, 但是並沒有記錄時間,所以在查詢方面會有一些不方便。如果讀者們有興趣,其實可以透過 ~/.bash_logout 來進行 history 的記錄,並加上 date 來增加時間參數,也是一個可以應用的方向喔! 有興趣的朋友可以先看看情境模擬題一吧!

Tips澳门新濠3559 20鳥哥經常需要設計線上題目給學生考試用,所以需要登入系統去設計環境,設計完畢後再將該硬碟分派給學生來考試使用。 只是,經常很擔心同學不小心輸入 history 就會得知鳥哥要考試的重點檔案與指令,因此就得要使用 history -c; history -w 來強迫更新紀錄檔了! 提供給您參考!


網路基礎

找到硬碟之後,就可以將這個分割區掛載到Service Console的檔案系統之下了。首先我們先建立一個臨時的目錄,輸入

10.4 Bash Shell 的操作環境:

是否記得我們登入主機的時候,螢幕上頭會有一些說明文字,告知我們的 Linux 版本啊什麼的, 還有,登入的時候我們還可以給予使用者一些訊息或者歡迎文字呢。此外, 我們習慣的環境變數、命令別名等等的,是否可以登入就主動的幫我設定好? 這些都是需要注意的。另外,這些設定值又可以分為系統整體設定值與各人喜好設定值, 僅是一些檔案放置的地點不同啦!這我們後面也會來談一談的!

Top

一些網路功能

 

mkdir /mnt/usbdisk

10.4.1 路徑與指令搜尋順序

我們在第五章與第六章都曾談過『相對路徑與絕對路徑』的關係, 在本章的前幾小節也談到了 alias 與 bash 的內建命令。現在我們知道系統裡面其實有不少的 ls 指令, 或者是包括內建的 echo 指令,那麼來想一想,如果一個指令 (例如 ls) 被下達時, 到底是哪一個 ls 被拿來運作?很有趣吧!基本上,指令運作的順序可以這樣看:

  1. 以相對/絕對路徑執行指令,例如『 /bin/ls 』或『 ./ls 』;
  2. 由 alias 找到該指令來執行;
  3. 由 bash 內建的 (builtin) 指令來執行;
  4. 透過 $PATH 這個變數的順序搜尋到的第一個指令來執行。

舉例來說,你可以下達 /bin/ls 及單純的 ls 看看,會發現使用 ls 有顏色但是 /bin/ls 則沒有顏色。 因為 /bin/ls 是直接取用該指令來下達,而 ls 會因為『 alias ls='ls --color=auto' 』這個命令別名而先使用! 如果想要瞭解指令搜尋的順序,其實透過 type -a ls 也可以查詢的到啦!上述的順序最好先瞭解喔!

例題:
設定 echo 的命令別名成為 echo -n ,然後再觀察 echo 執行的順序
答:
[dmtsai@study ~]$ alias echo='echo -n'
[dmtsai@study ~]$ type -a echo
echo is aliased to `echo -n'
echo is a shell builtin
echo is /usr/bin/echo
瞧!很清楚吧!先 alias 再 builtin 再由 $PATH 找到 /bin/echo 囉!

Top

style="font-size: xx-small;">ifconfig

style="font-family: 宋体;">這是用來查詢目前我們這個系統的網路卡的狀況的指令,可以查詢 IP、子遮罩網路及網路卡的硬體資訊等等。例如:   

[root@tsai /root]# ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:50:FC:20:F1:4D 
          inet addr:192.168.1.2  Bcast:192.168.1.255  Mask:255.255.255.0 
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1 
          RX packets:7651977 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:7467862 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:961 txqueuelen:100 
          Interrupt:10 Base address:0x6100

eth1      Link encap:Ethernet  HWaddr 00:80:C8:5A:87:01 
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1 
          RX packets:7492497 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:7617653 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:289 txqueuelen:100 
          Interrupt:9 Base address:0x6200

lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.0.0.0 
          UP LOOPBACK RUNNING  MTU:3924  Metric:1 
          RX packets:512 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:512 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:0

ppp0      Link encap:Point-to-Point Protocol 
          inet addr:211.74.249.38  P-t-P:172.16.11.8  Mask:255.255.255.255 
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1492  Metric:1 
          RX packets:7469726 errors:0 dropped:0 overruns:0 frame:0 
          TX packets:7617651 errors:0 dropped:0 overruns:0 carrier:0 
          collisions:0 txqueuelen:10

由於上面的例子是使用兩張網路卡,因此會有 eth0 及 eth1 兩個介面,至於 lo 是系統內設的遞迴網路,這是一定會有的咚咚,而且其 inet addr(IP)一定是 127.0.0.1!另外, ppp0 則是 ADSL 撥接之後所產生的虛擬介面(對外的介面!)。在這個例子中,鳥哥使用了兩張網路卡, eth0 用在內部網路, eth1 用在 ADSL 撥接,所以 eth1 就沒有 address。至於第一張網路卡的網路位址是虛擬的 192.168.1.2。而真正的對外聯繫是 ppp0 這一個撥接介面,其 internet 是 211.74.249.38!

style="font-size: xx-small;">route

style="font-family: 宋体;">這是用來看你的網路通訊包傳送的路由情況的指令。由於通信包是藉由一個一個的路由表來傳遞的,所以觀察你的路由表,對於網路除錯(debuge)就很重要啦!   

[root@tsai /root]# route 
Kernel IP routing table 
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface 
192.168.1.2     *               255.255.255.255 UH    0      0        0 eth0 
172.16.11.8     *               255.255.255.255 UH    0      0        0 ppp0 
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0 
127.0.0.0       *               255.0.0.0       U     0      0        0 lo 
default         172.16.11.8     0.0.0.0         UG    0      0        0 ppp0

例如上表中,所有的通訊都是藉由 ppp0 這一個介面卡(Iface)並且其通訊閘(Gateway)為 172.16.11.8 這一個!另外,在虛擬 IP (內部網路)則是藉由 eth0 (192.168.1.2)這一塊網卡來連線的!

另外,你也可以使用 route 來加入你的路由表,假如你要將一個網路為 192.56.76.XXX 且子網路為 255.255.255.0 的位置加入你的 eth0 這個網路卡的連線處理中,就可以使用如下的語法:   

[root@tsai /root]# route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0

style="font-size: xx-small;">netstat

style="font-family: 宋体;">這也是用來觀察網路狀況的指令。   

[root@tsai /root]# netstat 
Active Internet connections (w/o servers) 
Proto Recv-Q Send-Q Local Address           Foreign Address         State 
tcp        0    126 swks249-38.adsl.:telnet 192.168.1.15:1341     ESTABLISHED 
Active UNIX domain sockets (w/o servers) 
Proto RefCnt Flags       Type       State         I-Node Path 
unix  2      [ ]         DGRAM                    87643  /dev/log 
unix  0      [ ]         STREAM     CONNECTED     116    @00000012

在上表黃色的部分,由於鳥哥是在另一部電腦連線進入的,所以網路位址就會不同囉!

style="font-size: xx-small;">hostname

style="font-family: 宋体;">這只是用來觀看你的主機名稱而已。   

[root@tsai /root]# hostname 
tsai.adsldns.org

style="font-size: xx-small;">ping

style="font-family: 宋体;">這是用來察看對方網路是否有動作的指令,這個指令亦可以在 windows 上面執行!   

[root@tsai /root]# ping www.kimo.com.tw 
PING www.kimo.com.tw (202.1.237.21) from 211.74.249.38 : 56(84) bytes of data. 
64 bytes from 202.1.237.21: icmp_seq=0 ttl=245 time=56.7 ms 
64 bytes from 202.1.237.21: icmp_seq=1 ttl=245 time=58.0 ms 
64 bytes from 202.1.237.21: icmp_seq=2 ttl=245 time=58.7 ms 
64 bytes from 202.1.237.21: icmp_seq=3 ttl=245 time=52.0 ms 
64 bytes from 202.1.237.21: icmp_seq=4 ttl=245 time=72.2 ms 
--- www.kimo.com.tw ping statistics --- 
5 packets transmitted, 5 packets received, 0% packet loss 
round-trip min/avg/max = 52.0/59.5/72.2 ms

例如上表中,我們去觀察 www.kimo.com.tw 是否有啟動,看每一列的最後一行,會告訴你訊息回應的時間大約是 56ms!(10-3 sec.)

style="font-size: xx-small;">nslookup

這是用來查詢或反查詢 DNS 的指令!例如我們要知道 奇摩 的網路位址,則可以如此查詢:   

[root@tsai /root]# nslookup www.kimo.com.tw 
Server:  ksdns.seed.net.tw 
Address:  139.175.10.20

Non-authoritative answer: 
Name:    www.kimo.com.tw 
Address:  202.1.237.21

系統會告訴你,我們使用的 DNS server 是 ksdns.seed.net.tw,而查詢到的網址是 202.1.237.21。如果需要更詳細的查詢,可以用下面的方式來查!   

[root@tsai /root]# nslookup 
Default Server:  ksdns.seed.net.tw 
Address:  139.175.10.20

> set type=any            <==告訴系統我們要詳細的資料! 
> www.kimo.com.tw 
Server:  ksdns.seed.net.tw 
Address:  139.175.10.20

Non-authoritative answer: 
www.kimo.com.tw internet address = 202.1.237.21

Authoritative answers can be found from: 
kimo.com.tw     nameserver = ns1.kimo.com.tw 
kimo.com.tw     nameserver = ns1.yahoo.com 
kimo.com.tw     nameserver = ns3.europe.yahoo.com 
kimo.com.tw     nameserver = ns5.dcx.yahoo.com 
ns1.kimo.com.tw internet address = 210.59.144.1 
ns1.yahoo.com   internet address = 204.71.200.33 
ns3.europe.yahoo.com    internet address = 217.12.4.71 
ns5.dcx.yahoo.com       internet address = 216.32.74.10

style="font-size: xx-small;">talk

這是用來交談的指令。

style="font-size: xx-small;">traceroute

style="font-family: 宋体;">這是用來追查通訊包傳送的情況,例如我們要從 seednet 的網路上查詢到成大的代理伺服器的通訊狀況,可以使用如下的指令:   

[root@tsai /root]# /usr/sbin/traceroute proxy.ncku.edu.tw 
traceroute to proxy.ncku.edu.tw (163.28.112.100), 30 hops max, 38 byte packets 
 1  172.16.11.8 (172.16.11.8)  128.378 ms  68.920 ms  118.313 ms 
 2  139.175.15.1 (139.175.15.1)  54.146 ms  38.557 ms  44.320 ms 
 3  R58-37.seed.net.tw (139.175.58.37)  61.339 ms  43.177 ms  39.548 ms 
 4  R56-162.seed.net.tw (139.175.56.162)  66.631 ms  43.182 ms  41.429 ms 
 5  203.72.191.222 (203.72.191.222)  65.538 ms  61.379 ms  38.887 ms 
 6  140.116.241.230 (140.116.241.230)  40.159 ms  46.107 ms  46.854 ms 
 7  proxy.tnrc.edu.tw (163.28.112.100)  38.641 ms  57.286 ms  46.380 ms

系統會告訴你,總共通過了7個路由,並列出了每一個路由的 Internet 位址。這個東西有個好處,可以告訴你,當網路出問題時,問題是在哪一個地方!

style="font-size: xx-small;">mail

style="font-family: 宋体;">這是用來收發信件的指令,詳細的流程我們會在 mail 架站中提及。

  1. Client 端主動向 Server 端發送連線需求:由於是用戶端想要連上 FTP 主機,所以呢,當然連線的方向首先會由 Client 發起!此時,Client 端隨機選取一個大於 1024 以上的 port 來主動的連線到 FTP 主機提供的 FTP 埠口(通常為port 21),而由於是主動的連線封包,所以這個連線會帶有 SYN 的標誌在;

澳门新濠3559 21

10.4.2 bash 的進站與歡迎訊息: /etc/issue, /etc/motd

蝦密! bash 也有進站畫面與歡迎訊息喔?真假?真的啊! 還記得在終端機介面 (tty1 ~ tty6) 登入的時候,會有幾行提示的字串嗎?那就是進站畫面啊! 那個字串寫在哪裡啊?呵呵!在 /etc/issue 裡面啊!先來看看:

[dmtsai@study ~]$ cat /etc/issue
S
Kernel r on an m

鳥哥是以完全未更新過的 CentOS 7.1 作為範例,裡面預設有三行,較有趣的地方在於 r 與 m。 就如同 $PS1 這變數一樣,issue 這個檔案的內容也是可以使用反斜線作為變數取用喔!你可以 man issue 配合 man agetty 得到底下的結果:

issue 內的各代碼意義
d 本地端時間的日期;
l 顯示第幾個終端機介面;
m 顯示硬體的等級 (i386/i486/i586/i686...);
n 顯示主機的網路名稱;
O 顯示 domain name;
r 作業系統的版本 (相當於 uname -r)
t 顯示本地端時間的時間;
S 作業系統的名稱;
v 作業系統的版本。

做一下底下這個練習,看看能不能取得你要的進站畫面?

例題:
如果你在 tty3 的進站畫面看到如下顯示,該如何設定才能得到如下畫面?
CentOS Linux 7 (Core) (terminal: tty3)
Date: 2015-07-08 17:29:19
Kernel 3.10.0-229.el7.x86_64 on an x86_64
Welcome!

注意,tty3 在不同的 tty 有不同顯示,日期則是再按下 [enter] 後就會所有不同。
答:
很簡單,用 root 的身份,並參考上述的反斜線功能去修改 /etc/issue 成為如下模樣即可(共五行):
S (terminal: l)
Date: d t
Kernel r on an m
Welcome!

曾有鳥哥的學生在這個 /etc/issue 內修改資料,光是利用簡單的英文字母作出屬於他自己的進站畫面, 畫面裡面有他的中文名字呢!非常厲害!也有學生做成類似很大一個『囧』在進站畫面,都非常有趣!

你要注意的是,除了 /etc/issue 之外還有個 /etc/issue.net 呢!這是啥?這個是提供給 telnet 這個遠端登入程式用的。 當我們使用 telnet 連接到主機時,主機的登入畫面就會顯示 /etc/issue.net 而不是 /etc/issue 呢!

至於如果您想要讓使用者登入後取得一些訊息,例如您想要讓大家都知道的訊息, 那麼可以將訊息加入 /etc/motd 裡面去!例如:當登入後,告訴登入者, 系統將會在某個固定時間進行維護工作,可以這樣做 (一定要用 root 的身份才能修改喔!):

[root@study ~]# vim /etc/motd
Hello everyone,
Our server will be maintained at 2015/07/10 0:00 ~ 24:00.
Please don't login server at that time. ^_^

那麼當你的使用者(包括所有的一般帳號與 root)登入主機後,就會顯示這樣的訊息出來:

Last login: Wed Jul  8 23:22:25 2015 from 127.0.0.1
Hello everyone,
Our server will be maintained at 2015/07/10 0:00 ~ 24:00.
Please don't login server at that time. ^_^

Top


 

輸入完之後,我們就要將USB硬碟掛載在這個目錄之下。接下來輸入

10.4.3 bash 的環境設定檔

你是否會覺得奇怪,怎麼我們什麼動作都沒有進行,但是一進入 bash 就取得一堆有用的變數了? 這是因為系統有一些環境設定檔案的存在,讓 bash 在啟動時直接讀取這些設定檔,以規劃好 bash 的操作環境啦! 而這些設定檔又可以分為全體系統的設定檔以及使用者個人偏好設定檔。要注意的是, 我們前幾個小節談到的命令別名啦、自訂的變數啦,在你登出 bash 後就會失效,所以你想要保留你的設定, 就得要將這些設定寫入設定檔才行。底下就讓我們來聊聊吧!

  • login 與 non-login shell

在開始介紹 bash 的設定檔前,我們一定要先知道的就是 login shell 與 non-login shell! 重點在於有沒有登入 (login) 啦!

  • login shell:取得 bash 時需要完整的登入流程的,就稱為 login shell。舉例來說,你要由 tty1 ~ tty6 登入,需要輸入使用者的帳號與密碼,此時取得的 bash 就稱為『 login shell 』囉;

  • non-login shell:取得 bash 介面的方法不需要重複登入的舉動,舉例來說,(1)你以 X window 登入 Linux 後, 再以 X 的圖形化介面啟動終端機,此時那個終端介面並沒有需要再次的輸入帳號與密碼,那個 bash 的環境就稱為 non-login shell了。(2)你在原本的 bash 環境下再次下達 bash 這個指令,同樣的也沒有輸入帳號密碼, 那第二個 bash (子程序) 也是 non-login shell 。

為什麼要介紹 login, non-login shell 呢?這是因為這兩個取得 bash 的情況中,讀取的設定檔資料並不一樣所致。 由於我們需要登入系統,所以先談談 login shell 會讀取哪些設定檔?一般來說,login shell 其實只會讀取這兩個設定檔:

  1. /etc/profile:這是系統整體的設定,你最好不要修改這個檔案;
  2. ~/.bash_profile 或 ~/.bash_login 或 ~/.profile:屬於使用者個人設定,你要改自己的資料,就寫入這裡!

那麼,就讓我們來聊一聊這兩個檔案吧!這兩個檔案的內容可是非常繁複的喔!

  • /etc/profile (login shell 才會讀)

你可以使用 vim 去閱讀一下這個檔案的內容。這個設定檔可以利用使用者的識別碼 (UID) 來決定很多重要的變數資料, 這也是每個使用者登入取得 bash 時一定會讀取的設定檔! 所以如果你想要幫所有使用者設定整體環境,那就是改這裡囉!不過,沒事還是不要隨便改這個檔案喔 這個檔案設定的變數主要有:

  • PATH:會依據 UID 決定 PATH 變數要不要含有 sbin 的系統指令目錄;
  • MAIL:依據帳號設定好使用者的 mailbox 到 /var/spool/mail/帳號名;
  • USER:根據使用者的帳號設定此一變數內容;
  • HOSTNAME:依據主機的 hostname 指令決定此一變數內容;
  • HISTSIZE:歷史命令記錄筆數。CentOS 7.x 設定為 1000 ;
  • umask:包括 root 預設為 022 而一般用戶為 002 等!

/etc/profile 可不止會做這些事而已,他還會去呼叫外部的設定資料喔!在 CentOS 7.x 預設的情況下,底下這些資料會依序的被呼叫進來:

  • /etc/profile.d/*.sh

其實這是個目錄內的眾多檔案!只要在 /etc/profile.d/ 這個目錄內且副檔名為 .sh ,另外,使用者能夠具有 r 的權限, 那麼該檔案就會被 /etc/profile 呼叫進來。在 CentOS 7.x 中,這個目錄底下的檔案規範了 bash 操作介面的顏色、 語系、ll 與 ls 指令的命令別名、vi 的命令別名、which 的命令別名等等。如果你需要幫所有使用者設定一些共用的命令別名時, 可以在這個目錄底下自行建立副檔名為 .sh 的檔案,並將所需要的資料寫入即可喔!

  • /etc/locale.conf

這個檔案是由 /etc/profile.d/lang.sh 呼叫進來的!這也是我們決定 bash 預設使用何種語系的重要設定檔! 檔案裡最重要的就是 LANG/LC_ALL 這些個變數的設定啦!我們在前面的 locale 討論過這個檔案囉! 自行回去瞧瞧先!

  • /usr/share/bash-completion/completions/*

記得我們上頭談過 [tab] 的妙用吧?除了命令補齊、檔名補齊之外,還可以進行指令的選項/參數補齊功能!那就是從這個目錄裡面找到相對應的指令來處理的! 其實這個目錄底下的內容是由 /etc/profile.d/bash_completion.sh 這個檔案載入的啦!

反正你只要記得,bash 的 login shell 情況下所讀取的整體環境設定檔其實只有 /etc/profile,但是 /etc/profile 還會呼叫出其他的設定檔,所以讓我們的 bash 操作介面變的非常的友善啦! 接下來,讓我們來瞧瞧,那麼個人偏好的設定檔又是怎麼回事?

  • ~/.bash_profile (login shell 才會讀)

bash 在讀完了整體環境設定的 /etc/profile 並藉此呼叫其他設定檔後,接下來則是會讀取使用者的個人設定檔。 在 login shell 的 bash 環境中,所讀取的個人偏好設定檔其實主要有三個,依序分別是:

  1. ~/.bash_profile
  2. ~/.bash_login
  3. ~/.profile

其實 bash 的 login shell 設定只會讀取上面三個檔案的其中一個, 而讀取的順序則是依照上面的順序。也就是說,如果 ~/.bash_profile 存在,那麼其他兩個檔案不論有無存在,都不會被讀取。 如果 ~/.bash_profile 不存在才會去讀取 ~/.bash_login,而前兩者都不存在才會讀取 ~/.profile 的意思。 會有這麼多的檔案,其實是因應其他 shell 轉換過來的使用者的習慣而已。 先讓我們來看一下 dmtsai 的 /home/dmtsai/.bash_profile 的內容是怎樣呢?

[dmtsai@study ~]$ cat ~/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then    <==底下這三行在判斷並讀取 ~/.bashrc
        . ~/.bashrc
fi

# User specific environment and startup programs
PATH=$PATH:$HOME/.local/bin:$HOME/bin    <==底下這幾行在處理個人化設定
export PATH

這個檔案內有設定 PATH 這個變數喔!而且還使用了 export 將 PATH 變成環境變數呢! 由於 PATH 在 /etc/profile 當中已經設定過,所以在這裡就以累加的方式增加使用者家目錄下的 ~/bin/ 為額外的執行檔放置目錄。這也就是說,你可以將自己建立的執行檔放置到你自己家目錄下的 ~/bin/ 目錄啦! 那就可以直接執行該執行檔而不需要使用絕對/相對路徑來執行該檔案。

這個檔案的內容比較有趣的地方在於 if ... then ... 那一段!那一段程式碼我們會在第十二章 shell script 談到,假設你現在是看不懂的。 該段的內容指的是『判斷家目錄下的 ~/.bashrc 存在否,若存在則讀入 ~/.bashrc 的設定』。 bash 設定檔的讀入方式比較有趣,主要是透過一個指令『 source 』來讀取的! 也就是說 ~/.bash_profile 其實會再呼叫 ~/.bashrc 的設定內容喔!最後,我們來看看整個 login shell 的讀取流程:

澳门新濠3559 22

圖10.4.1、login shell 的設定檔讀取流程

實線的的方向是主線流程,虛線的方向則是被呼叫的設定檔!從上面我們也可以清楚的知道,在 CentOS 的 login shell 環境下,最終被讀取的設定檔是『 ~/.bashrc 』這個檔案喔!所以,你當然可以將自己的偏好設定寫入該檔案即可。 底下我們還要討論一下 source 與 ~/.bashrc 喔!

  • source :讀入環境設定檔的指令

由於 /etc/profile 與 ~/.bash_profile 都是在取得 login shell 的時候才會讀取的設定檔,所以, 如果你將自己的偏好設定寫入上述的檔案後,通常都是得登出再登入後,該設定才會生效。那麼,能不能直接讀取設定檔而不登出登入呢? 可以的!那就得要利用 source 這個指令了!

[dmtsai@study ~]$ source 設定檔檔名

範例:將家目錄的 ~/.bashrc 的設定讀入目前的 bash 環境中
[dmtsai@study ~]$ source ~/.bashrc  <==底下這兩個指令是一樣的!
[dmtsai@study ~]$  .  ~/.bashrc

利用 source 或小數點 (.) 都可以將設定檔的內容讀進來目前的 shell 環境中! 舉例來說,我修改了 ~/.bashrc ,那麼不需要登出,立即以 source ~/.bashrc 就可以將剛剛最新設定的內容讀進來目前的環境中!很不錯吧!還有,包括 ~/bash_profile 以及 /etc/profile 的設定中, 很多時候也都是利用到這個 source (或小數點) 的功能喔!

有沒有可能會使用到不同環境設定檔的時候?有啊! 最常發生在一個人的工作環境分為多種情況的時候了!舉個例子來說,在鳥哥的大型主機中, 常常需要負責兩到三個不同的案子,每個案子所需要處理的環境變數訂定並不相同, 那麼鳥哥就將這兩三個案子分別編寫屬於該案子的環境變數設定檔案,當需要該環境時,就直接『 source 變數檔 』,如此一來,環境變數的設定就變的更簡便而靈活了!

  • ~/.bashrc (non-login shell 會讀)

談完了 login shell 後,那麼 non-login shell 這種非登入情況取得 bash 操作介面的環境設定檔又是什麼? 當你取得 non-login shell 時,該 bash 設定檔僅會讀取 ~/.bashrc 而已啦!那麼預設的 ~/.bashrc 內容是如何?

[root@study ~]# cat ~/.bashrc
# .bashrc

# User specific aliases and functions
alias rm='rm -i'             <==使用者的個人設定
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then  <==整體的環境設定
        . /etc/bashrc
fi

特別注意一下,由於 root 的身份與一般使用者不同,鳥哥是以 root 的身份取得上述的資料, 如果是一般使用者的 ~/.bashrc 會有些許不同。看一下,你會發現在 root 的 ~/.bashrc 中其實已經規範了較為保險的命令別名了。 此外,咱們的 CentOS 7.x 還會主動的呼叫 /etc/bashrc 這個檔案喔!為什麼需要呼叫 /etc/bashrc 呢? 因為 /etc/bashrc 幫我們的 bash 定義出底下的資料:

  • 依據不同的 UID 規範出 umask 的值;
  • 依據不同的 UID 規範出提示字元 (就是 PS1 變數);
  • 呼叫 /etc/profile.d/*.sh 的設定

你要注意的是,這個 /etc/bashrc 是 CentOS 特有的 (其實是 Red Hat 系統特有的),其他不同的 distributions 可能會放置在不同的檔名就是了。由於這個 ~/.bashrc 會呼叫 /etc/bashrc 及 /etc/profile.d/*.sh , 所以,萬一你沒有 ~/.bashrc (可能自己不小心將他刪除了),那麼你會發現你的 bash 提示字元可能會變成這個樣子:

-bash-4.2$ 

不要太擔心啦!這是正常的,因為你並沒有呼叫 /etc/bashrc 來規範 PS1 變數啦!而且這樣的情況也不會影響你的 bash 使用。 如果你想要將命令提示字元捉回來,那麼可以複製 /etc/skel/.bashrc 到你的家目錄,再修訂一下你所想要的內容, 並使用 source 去呼叫 ~/.bashrc ,那你的命令提示字元就會回來啦!

  • 其他相關設定檔

事實上還有一些設定檔可能會影響到你的 bash 操作的,底下就來談一談:

  • /etc/man_db.conf

這個檔案乍看之下好像跟 bash 沒相關性,但是對於系統管理員來說, 卻也是很重要的一個檔案!這的檔案的內容『規範了使用 man 的時候, man page 的路徑到哪裡去尋找!』所以說的簡單一點,這個檔案規定了下達 man 的時候,該去哪裡查看資料的路徑設定!

那麼什麼時候要來修改這個檔案呢?如果你是以 tarball 的方式來安裝你的資料,那麼你的 man page 可能會放置在 /usr/local/softpackage/man 裡頭,那個 softpackage 是你的套件名稱, 這個時候你就得以手動的方式將該路徑加到 /etc/man_db.conf 裡頭,否則使用 man 的時候就會找不到相關的說明檔囉。

  • ~/.bash_history

還記得我們在歷史命令提到過這個檔案吧?預設的情況下, 我們的歷史命令就記錄在這裡啊!而這個檔案能夠記錄幾筆資料,則與 HISTFILESIZE 這個變數有關啊。每次登入 bash 後,bash 會先讀取這個檔案,將所有的歷史指令讀入記憶體, 因此,當我們登入 bash 後就可以查知上次使用過哪些指令囉。至於更多的歷史指令, 請自行回去參考喔!

  • ~/.bash_logout

這個檔案則記錄了『當我登出 bash 後,系統再幫我做完什麼動作後才離開』的意思。 你可以去讀取一下這個檔案的內容,預設的情況下,登出時, bash 只是幫我們清掉螢幕的訊息而已。 不過,你也可以將一些備份或者是其他你認為重要的工作寫在這個檔案中 (例如清空暫存檔), 那麼當你離開 Linux 的時候,就可以解決一些煩人的事情囉!

Top

其他有的沒的

  1. Server 端接受後,回應給 Client 端:當 Server 接收到 Client 的要求之後,會回應 Client 端的需求,此時 Server 端會建立等待連線的資源,並且將一帶有 SYN 與確認 (ACK) 的封包送回 Client 端;

mount /dev/sda1 /mnt/usbdisk -t vfat

10.4.4 終端機的環境設定: stty, set

我們在第四章首次登入 Linux 時就提過,可以在 tty1 ~ tty6 這六個文字介面的終端機 (terminal) 環境中登入,登入的時候我們可以取得一些字元設定的功能喔! 舉例來說,我們可以利用倒退鍵 (backspace,就是那個←符號的按鍵) 來刪除命令列上的字元, 也可以使用 [ctrl]+c 來強制終止一個指令的運行,當輸入錯誤時,就會有聲音跑出來警告。這是怎麼辦到的呢? 很簡單啊!因為登入終端機的時候,會自動的取得一些終端機的輸入環境的設定啊!

事實上,目前我們使用的 Linux distributions 都幫我們作了最棒的使用者環境了, 所以大家可以不用擔心操作環境的問題。不過,在某些 Unix like 的機器中,還是可能需要動用一些手腳, 才能夠讓我們的輸入比較快樂~舉例來說,利用 [backspace] 刪除,要比利用 [Del] 按鍵來的順手吧! 但是某些 Unix 偏偏是以 [del] 來進行字元的刪除啊!所以,這個時候就可以動動手腳囉~

那麼如何查閱目前的一些按鍵內容呢?可以利用 stty (setting tty 終端機的意思) 呢! stty 也可以幫助設定終端機的輸入按鍵代表意義喔!

[dmtsai@study ~]$ stty [-a]
選項與參數:
-a  :將目前所有的 stty 參數列出來;

範例一:列出所有的按鍵與按鍵內容
[dmtsai@study ~]$ stty -a
speed 38400 baud; rows 20; columns 90; line = 0;
intr = ^C; quit = ^; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V;
flush = ^O; min = 1; time = 0;
....(以下省略)....

我們可以利用 stty -a 來列出目前環境中所有的按鍵列表,在上頭的列表當中,需要注意的是特殊字體那幾個, 此外,如果出現 ^ 表示 [Ctrl] 那個按鍵的意思。舉例來說, intr = ^C 表示利用 [ctrl] + c 來達成的。幾個重要的代表意義是:

  • intr  : 送出一個 interrupt (中斷) 的訊號給目前正在 run 的程序 (就是終止囉!);
  • quit  : 送出一個 quit 的訊號給目前正在 run 的程序;
  • erase : 向後刪除字元,
  • kill  : 刪除在目前指令列上的所有文字;
  • eof   : End of file 的意思,代表『結束輸入』。
  • start : 在某個程序停止後,重新啟動他的 output
  • stop  : 停止目前螢幕的輸出;
  • susp  : 送出一個 terminal stop 的訊號給正在 run 的程序。

記不記得我們在第四章講過幾個 Linux 熱鍵啊?沒錯! 就是這個 stty 設定值內的 intr([ctrl]+c) / eof([ctrl]+d) 囉~至於刪除字元,就是 erase 那個設定值啦! 如果你想要用 [ctrl]+h 來進行字元的刪除,那麼可以下達:

[dmtsai@study ~]$ stty erase ^h  # 這個設定看看就好,不必真的實做!不然還要改回來!

那麼從此之後,你的刪除字元就得要使用 [ctrl]+h 囉,按下 [backspace] 則會出現 ^? 字樣呢! 如果想要回復利用 [backspace] ,就下達 stty erase ^? 即可啊! 至於更多的 stty 說明,記得參考一下 man stty 的內容喔!

問:
因為鳥哥的工作經常在 Windows/Linux 之間切換,在 windows 底下,很多軟體預設的儲存快捷按鈕是 [ctrl]+s ,所以鳥哥習慣按這個按鈕來處理。 不過,在 Linux 底下使用 vim 時,卻也經常不小心就按下 [ctrl]+s !問題來了,按下這個組合鈕之後,整個 vim 就不能動了 (整個畫面鎖死)! 請問鳥哥該如何處置?
答:
參考一下 stty -a 的輸出中,有個 stop 的項目就是按下 [ctrl]+s 的!那麼恢復成 start 就是 [ctrl]+q 啊!因此, 嘗試按下 [ctrl]+q 應該就可以讓整個畫面重新恢復正常咯!

除了 stty 之外,其實我們的 bash 還有自己的一些終端機設定值呢!那就是利用 set 來設定的! 我們之前提到一些變數時,可以利用 set 來顯示,除此之外,其實 set 還可以幫我們設定整個指令輸出/輸入的環境。 例如記錄歷史命令、顯示錯誤內容等等。

[dmtsai@study ~]$ set [-uvCHhmBx]
選項與參數:
-u  :預設不啟用。若啟用後,當使用未設定變數時,會顯示錯誤訊息;
-v  :預設不啟用。若啟用後,在訊息被輸出前,會先顯示訊息的原始內容;
-x  :預設不啟用。若啟用後,在指令被執行前,會顯示指令內容(前面有 ++ 符號)
-h  :預設啟用。與歷史命令有關;
-H  :預設啟用。與歷史命令有關;
-m  :預設啟用。與工作管理有關;
-B  :預設啟用。與刮號 [] 的作用有關;
-C  :預設不啟用。若使用 > 等,則若檔案存在時,該檔案不會被覆蓋。

範例一:顯示目前所有的 set 設定值
[dmtsai@study ~]$ echo $-
himBH
# 那個 $- 變數內容就是 set 的所有設定啦! bash 預設是 himBH 喔!

範例二:設定 "若使用未定義變數時,則顯示錯誤訊息" 
[dmtsai@study ~]$ set -u
[dmtsai@study ~]$ echo $vbirding
-bash: vbirding: unbound variable
# 預設情況下,未設定/未宣告 的變數都會是『空的』,不過,若設定 -u 參數,
# 那麼當使用未設定的變數時,就會有問題啦!很多的 shell 都預設啟用 -u 參數。
# 若要取消這個參數,輸入 set +u 即可!

範例三:執行前,顯示該指令內容。
[dmtsai@study ~]$ set -x
++ printf '33]0;%s@%s:%s07' dmtsai study '~'    # 這個是在列出提示字元的控制碼!
[dmtsai@study ~]$ echo ${HOME}
+ echo /home/dmtsai
/home/dmtsai
++ printf '33]0;%s@%s:%s07' dmtsai study '~'
# 看見否?要輸出的指令都會先被列印到螢幕上喔!前面會多出 + 的符號!

另外,其實我們還有其他的按鍵設定功能呢!就是在前一小節提到的 /etc/inputrc 這個檔案裡面設定。 還有例如 /etc/DIR_COLORS* 與 /usr/share/terminfo/* 等,也都是與終端機有關的環境設定檔案呢! 不過,事實上,鳥哥並不建議您修改 tty 的環境呢,這是因為 bash 的環境已經設定的很親和了, 我們不需要額外的設定或者修改,否則反而會產生一些困擾。不過,寫在這裡的資料, 只是希望大家能夠清楚的知道我們的終端機是如何進行設定的喔! ^_^! 最後,我們將 bash 預設的組合鍵給他彙整如下:

組合按鍵 執行結果
Ctrl + C 終止目前的命令
Ctrl + D 輸入結束 (EOF),例如郵件結束的時候;
Ctrl + M 就是 Enter 啦!
Ctrl + S 暫停螢幕的輸出
Ctrl + Q 恢復螢幕的輸出
Ctrl + U 在提示字元下,將整列命令刪除
Ctrl + Z 『暫停』目前的命令

Top

style="font-size: xx-small;">date

這是用來察看日期的指令。   

[root@tsai /root]# date 
Fri Aug  3 19:09:31 CST 2001

style="font-size: xx-small;">cal

這是用來叫出日曆的指令。   

[root@tsai /root]# cal 
     August 2001 
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 31

style="font-size: xx-small;">grep

style="font-family: 宋体;">這是用來搜尋某些特定字元的指令。例如使用 ps -aux 查詢系統服務時,我們只需要知道 sendmail 是否有動作,則可以使用管線指令『|』來加入 grep 這個指令同時運作。   

[root@tsai /root]# ps -aux|grep sendmail 
root       443  0.0  1.0  2092  660 ?        S    Jul26   0:36 sendmail: accepti 
vbird     8387  0.0  0.7  1240  492 pts/1    S    19:11   0:00 grep sendmail

上表則表示 sendmail 有在運作了!

 

澳门新濠3559 23

10.4.5 萬用字元與特殊符號

在 bash 的操作環境中還有一個非常有用的功能,那就是萬用字元 (wildcard) ! 我們利用 bash 處理資料就更方便了!底下我們列出一些常用的萬用字元喔:

符號 意義
* 代表『 0 個到無窮多個』任意字元
? 代表『一定有一個』任意字元
[ ] 同樣代表『一定有一個在括號內』的字元(非任意字元)。例如 [abcd] 代表『一定有一個字元, 可能是 a, b, c, d 這四個任何一個』
[ - ] 若有減號在中括號內時,代表『在編碼順序內的所有字元』。例如 [0-9] 代表 0 到 9 之間的所有數字,因為數字的語系編碼是連續的!
[^ ] 若中括號內的第一個字元為指數符號 (^) ,那表示『反向選擇』,例如 [^abc] 代表 一定有一個字元,只要是非 a, b, c 的其他字元就接受的意思。

接下來讓我們利用萬用字元來玩些東西吧!首先,利用萬用字元配合 ls 找檔名看看:

[dmtsai@study ~]$ LANG=C              <==由於與編碼有關,先設定語系一下

範例一:找出 /etc/ 底下以 cron 為開頭的檔名
[dmtsai@study ~]$ ll -d /etc/cron*    <==加上 -d 是為了僅顯示目錄而已

範例二:找出 /etc/ 底下檔名『剛好是五個字母』的檔名
[dmtsai@study ~]$ ll -d /etc/?????    <==由於 ? 一定有一個,所以五個 ? 就對了

範例三:找出 /etc/ 底下檔名含有數字的檔名
[dmtsai@study ~]$ ll -d /etc/*[0-9]*  <==記得中括號左右兩邊均需 *

範例四:找出 /etc/ 底下,檔名開頭非為小寫字母的檔名:
[dmtsai@study ~]$ ll -d /etc/[^a-z]*  <==注意中括號左邊沒有 *

範例五:將範例四找到的檔案複製到 /tmp/upper 中
[dmtsai@study ~]$ mkdir /tmp/upper; cp -a /etc/[^a-z]* /tmp/upper

除了萬用字元之外,bash 環境中的特殊符號有哪些呢?底下我們先彙整一下:

符號 內容
# 註解符號:這個最常被使用在 script 當中,視為說明!在後的資料均不執行
跳脫符號:將『特殊字元或萬用字元』還原成一般字元
| 管線 (pipe):分隔兩個管線命令的界定(後兩節介紹);
; 連續指令下達分隔符號:連續性命令的界定 (注意!與管線命令並不相同)
~ 使用者的家目錄
$ 取用變數前置字元:亦即是變數之前需要加的變數取代值
& 工作控制 (job control):將指令變成背景下工作
! 邏輯運算意義上的『非』 not 的意思!
/ 目錄符號:路徑分隔的符號
>, >> 資料流重導向:輸出導向,分別是『取代』與『累加』
<, << 資料流重導向:輸入導向 (這兩個留待下節介紹)
' ' 單引號,不具有變數置換的功能 ($ 變為純文字)
" " 具有變數置換的功能! ($ 可保留相關功能)
` ` 兩個『 ` 』中間為可以先執行的指令,亦可使用 $( )
( ) 在中間為子 shell 的起始與結束
{ } 在中間為命令區塊的組合!

以上為 bash 環境中常見的特殊符號彙整!理論上,你的『檔名』盡量不要使用到上述的字元啦!


  1. Client 端回應確認封包:在 Client 端接收到來自 Server 端告知的封包後,會再次的發送一個確認封包給主機,此時,兩邊才會正式的建立起連線的通道,這個步驟 1 ~ 3 就是 Three-Way Handshake(三向交握的啦!)。需要注意的是,這個已經建立連線的通道(通常是 port 21)僅能進行 FTP 的『指令』而已,如果該指令涉及到資料的傳送(data transfer)時,例如上傳或下載等等,那麼就需要額外建立一條資料傳輸的通道才行 ( ftp-data )!而資料傳輸的通道建立則需要繼續底下的步驟;

這個指令的參數是將「/dev/sda1」這個裝置掛載到「/mnt/usbdisk」這個目錄下。而「-t vfat」則是指定該分割區的檔案系統。如果你的USB硬碟是Linux可認出的ext2/3的話,甚至可以不需要輸入檔案系統「-v」的參數。

10.5 資料流重導向

資料流重導向 (redirect) 由字面上的意思來看,好像就是將『資料給他傳導到其他地方去』的樣子? 沒錯~資料流重導向就是將某個指令執行後應該要出現在螢幕上的資料, 給他傳輸到其他的地方,例如檔案或者是裝置 (例如印表機之類的)!這玩意兒在 Linux 的文字模式底下可重要的! 尤其是如果我們想要將某些資料儲存下來時,就更有用了!

Top

ftp 指令

 

找到置放VM的Datastore並且開始複製

10.5.1 什麼是資料流重導向

什麼是資料流重導向啊?這得要由指令的執行結果談起!一般來說,如果你要執行一個指令,通常他會是這樣的:

澳门新濠3559 24

圖10.5.1、指令執行過程的資料傳輸情況

我們執行一個指令的時候,這個指令可能會由檔案讀入資料,經過處理之後,再將資料輸出到螢幕上。 在上圖當中, standard output 與 standard error output 分別代表『標準輸出 (STDOUT)』與『標準錯誤輸出 (STDERR)』, 這兩個玩意兒預設都是輸出到螢幕上面來的啊!那麼什麼是標準輸出與標準錯誤輸出呢?

  • standard output 與 standard error output

簡單的說,標準輸出指的是『指令執行所回傳的正確的訊息』,而標準錯誤輸出可理解為『 指令執行失敗後,所回傳的錯誤訊息』。舉個簡單例子來說,我們的系統預設有 /etc/crontab 但卻無 /etc/vbirdsay, 此時若下達『 cat /etc/crontab /etc/vbirdsay 』這個指令時,cat 會進行:

  • 標準輸出:讀取 /etc/crontab 後,將該檔案內容顯示到螢幕上;
  • 標準錯誤輸出:因為無法找到 /etc/vbirdsay,因此在螢幕上顯示錯誤訊息

不管正確或錯誤的資料都是預設輸出到螢幕上,所以螢幕當然是亂亂的!那能不能透過某些機制將這兩股資料分開呢? 當然可以啊!那就是資料流重導向的功能啊!資料流重導向可以將 standard output (簡稱 stdout) 與 standard error output (簡稱 stderr) 分別傳送到其他的檔案或裝置去,而分別傳送所用的特殊字元則如下所示:

  1. 標準輸入  (stdin) :代碼為 0 ,使用 < 或 << ;
  2. 標準輸出  (stdout):代碼為 1 ,使用 > 或 >> ;
  3. 標準錯誤輸出(stderr):代碼為 2 ,使用 2> 或 2>> ;

為了理解 stdout 與 stderr ,我們先來進行一個範例的練習:

範例一:觀察你的系統根目錄 (/) 下各目錄的檔名、權限與屬性,並記錄下來
[dmtsai@study ~]$ ll /  <==此時螢幕會顯示出檔名資訊

[dmtsai@study ~]$ ll / > ~/rootfile <==螢幕並無任何資訊
[dmtsai@study ~]$ ll  ~/rootfile <==有個新檔被建立了!
-rw-rw-r--. 1 dmtsai dmtsai 1078 Jul  9 18:51 /home/dmtsai/rootfile

怪了!螢幕怎麼會完全沒有資料呢?這是因為原本『 ll / 』所顯示的資料已經被重新導向到 ~/rootfile 檔案中了! 那個 ~/rootfile 的檔名可以隨便你取。如果你下達『 cat ~/rootfile 』那就可以看到原本應該在螢幕上面的資料囉。 如果我再次下達:『 ll /home > ~/rootfile 』後,那個 ~/rootfile 檔案的內容變成什麼? 他將變成『僅有 ll /home 的資料』而已!咦!原本的『 ll / 』資料就不見了嗎?是的!因為該檔案的建立方式是:

  1. 該檔案 (本例中是 ~/rootfile) 若不存在,系統會自動的將他建立起來,但是
  2. 當這個檔案存在的時候,那麼系統就會先將這個檔案內容清空,然後再將資料寫入!
  3. 也就是若以 > 輸出到一個已存在的檔案中,那個檔案就會被覆蓋掉囉!

那如果我想要將資料累加而不想要將舊的資料刪除,那該如何是好?利用兩個大於的符號 (>>) 就好啦!以上面的範例來說,你應該要改成『 ll / >> ~/rootfile 』即可。 如此一來,當 (1) ~/rootfile 不存在時系統會主動建立這個檔案;(2)若該檔案已存在, 則資料會在該檔案的最下方累加進去!

上面談到的是 standard output 的正確資料,那如果是 standard error output 的錯誤資料呢?那就透過 2> 及 2>> 囉!同樣是覆蓋 (2>) 與累加 (2>>) 的特性!我們在剛剛才談到 stdout 代碼是 1 而 stderr 代碼是 2 , 所以這個 2> 是很容易理解的,而如果僅存在 > 時,則代表預設的代碼 1 囉!也就是說:

  • 1> :以覆蓋的方法將『正確的資料』輸出到指定的檔案或裝置上;
  • 1>>:以累加的方法將『正確的資料』輸出到指定的檔案或裝置上;
  • 2> :以覆蓋的方法將『錯誤的資料』輸出到指定的檔案或裝置上;
  • 2>>:以累加的方法將『錯誤的資料』輸出到指定的檔案或裝置上;

要注意喔,『 1>> 』以及『 2>> 』中間是沒有空格的!OK!有些概念之後讓我們繼續聊一聊這傢伙怎麼應用吧! 當你以一般身份執行 find 這個指令的時候,由於權限的問題可能會產生一些錯誤資訊。例如執行『find / -name testing 』時,可能會產生類似『 find: /root: Permission denied 』之類的訊息。 例如底下這個範例:

範例二:利用一般身份帳號搜尋 /home 底下是否有名為 .bashrc 的檔案存在
[dmtsai@study ~]$ find /home -name .bashrc <==身份是 dmtsai 喔!
find: '/home/arod': Permission denied    <== Standard error output
find: '/home/alex': Permission denied    <== Standard error output
/home/dmtsai/.bashrc                     <== Standard output

由於 /home 底下還有我們之前建立的帳號存在,那些帳號的家目錄你當然不能進入啊!所以就會有錯誤及正確資料了。 好了,那麼假如我想要將資料輸出到 list 這個檔案中呢?執行『 find /home -name .bashrc > list 』 會有什麼結果?呵呵,你會發現 list 裡面存了剛剛那個『正確』的輸出資料, 至於螢幕上還是會有錯誤的訊息出現呢!傷腦筋!如果想要將正確的與錯誤的資料分別存入不同的檔案中需要怎麼做?

範例三:承範例二,將 stdout 與 stderr 分存到不同的檔案去
[dmtsai@study ~]$ find /home -name .bashrc > list_right 2> list_error

注意喔,此時『螢幕上不會出現任何訊息』!因為剛剛執行的結果中,有 Permission 的那幾行錯誤資訊都會跑到 list_error 這個檔案中,至於正確的輸出資料則會存到 list_right 這個檔案中囉!這樣可以瞭解了嗎? 如果有點混亂的話,去休息一下再回來看看吧!

  • /dev/null 垃圾桶黑洞裝置與特殊寫法

想像一下,如果我知道錯誤訊息會發生,所以要將錯誤訊息忽略掉而不顯示或儲存呢? 這個時候黑洞裝置 /dev/null 就很重要了!這個 /dev/null 可以吃掉任何導向這個裝置的資訊喔!將上述的範例修訂一下:

範例四:承範例三,將錯誤的資料丟棄,螢幕上顯示正確的資料
[dmtsai@study ~]$ find /home -name .bashrc 2> /dev/null
/home/dmtsai/.bashrc  <==只有 stdout 會顯示到螢幕上, stderr 被丟棄了

再想像一下,如果我要將正確與錯誤資料通通寫入同一個檔案去呢?這個時候就得要使用特殊的寫法了! 我們同樣用底下的案例來說明:

範例五:將指令的資料全部寫入名為 list 的檔案中
[dmtsai@study ~]$ find /home -name .bashrc > list 2> list  <==錯誤
[dmtsai@study ~]$ find /home -name .bashrc > list 2>&1     <==正確
[dmtsai@study ~]$ find /home -name .bashrc &> list         <==正確

上述表格第一行錯誤的原因是,由於兩股資料同時寫入一個檔案,又沒有使用特殊的語法, 此時兩股資料可能會交叉寫入該檔案內,造成次序的錯亂。所以雖然最終 list 檔案還是會產生,但是裡面的資料排列就會怪怪的,而不是原本螢幕上的輸出排序。 至於寫入同一個檔案的特殊語法如上表所示,你可以使用 2>&1 也可以使用 &> ! 一般來說,鳥哥比較習慣使用 2>&1 的語法啦!

  • standard input : < 與 <<

瞭解了 stderr 與 stdout 後,那麼那個 < 又是什麼呀?呵呵!以最簡單的說法來說, 那就是『將原本需要由鍵盤輸入的資料,改由檔案內容來取代』的意思。 我們先由底下的 cat 指令操作來瞭解一下什麼叫做『鍵盤輸入』吧!

範例六:利用 cat 指令來建立一個檔案的簡單流程
[dmtsai@study ~]$ cat > catfile
testing
cat file test
<==這裡按下 [ctrl]+d 來離開

[dmtsai@study ~]$ cat catfile
testing
cat file test

由於加入 > 在 cat 後,所以那個 catfile 會被主動的建立,而內容就是剛剛鍵盤上面輸入的那兩行資料了。 唔!那我能不能用純文字檔取代鍵盤的輸入,也就是說,用某個檔案的內容來取代鍵盤的敲擊呢? 可以的!如下所示:

範例七:用 stdin 取代鍵盤的輸入以建立新檔案的簡單流程
[dmtsai@study ~]$ cat > catfile < ~/.bashrc
[dmtsai@study ~]$ ll catfile ~/.bashrc
-rw-r--r--. 1 dmtsai dmtsai 231 Mar  6 06:06 /home/dmtsai/.bashrc
-rw-rw-r--. 1 dmtsai dmtsai 231 Jul  9 18:58 catfile
# 注意看,這兩個檔案的大小會一模一樣!幾乎像是使用 cp 來複製一般!

這東西非常的有幫助!尤其是用在類似 mail 這種指令的使用上。 理解 < 之後,再來則是怪可怕一把的 << 這個連續兩個小於的符號了。 他代表的是『結束的輸入字元』的意思!舉例來講:『我要用 cat 直接將輸入的訊息輸出到 catfile 中, 且當由鍵盤輸入 eof 時,該次輸入就結束』,那我可以這樣做:

[dmtsai@study ~]$ cat > catfile << "eof"
> This is a test.
> OK now stop
> eof  <==輸入這關鍵字,立刻就結束而不需要輸入 [ctrl]+d

[dmtsai@study ~]$ cat catfile
This is a test.
OK now stop     <==只有這兩行,不會存在關鍵字那一行!

看到了嗎?利用 << 右側的控制字元,我們可以終止一次輸入, 而不必輸入 [ctrl]+d 來結束哩!這對程式寫作很有幫助喔!好了,那麼為何要使用命令輸出重導向呢?我們來說一說吧!

  • 螢幕輸出的資訊很重要,而且我們需要將他存下來的時候;
  • 背景執行中的程式,不希望他干擾螢幕正常的輸出結果時;
  • 一些系統的例行命令 (例如寫在 /etc/crontab 中的檔案) 的執行結果,希望他可以存下來時;
  • 一些執行命令的可能已知錯誤訊息時,想以『 2> /dev/null 』將他丟掉時;
  • 錯誤訊息與正確訊息需要分別輸出時。

當然還有很多的功能的,最簡單的就是網友們常常問到的:『為何我的 root 都會收到系統 crontab 寄來的錯誤訊息呢』這個咚咚是常見的錯誤, 而如果我們已經知道這個錯誤訊息是可以忽略的時候,嗯!『 2> errorfile 』這個功能就很重要了吧! 瞭解了嗎?

問:
假設我要將 echo "error message" 以 standard error output 的格式來輸出,該如何處置?
答:
既然有 2>&1 來將 2> 轉到 1> 去,那麼應該也會有 1>&2 吧?沒錯!就是這個概念!因此你可以這樣作:
[dmtsai@study ~]$ echo "error message" 1>&2 
[dmtsai@study ~]$ echo "error message" 2> /dev/null 1>&2
你會發現第一條有訊息輸出到螢幕上,第二條則沒有訊息!這表示該訊息已經是透過 2> /dev/null 丟到垃圾桶去了! 可以肯定是錯誤訊息囉! ^_^

Top

style="font-size: xx-small;">ftp

FTP 這個功能不用再多談了吧?這是用來捉取網路上免費檔案的一套軟體。例如我們要連上交大的 FTP 站捉東西,可以如下:   

[root@tsai /root]#  ftp linux.cis.nctu.edu.tw 
Connected to linux.cis.nctu.edu.tw. 
220 ProFTPD 1.2.0rc3 Server (Linux.CIS FTP server) [linux.cis.nctu.edu.tw] 
Name (linux.cis.nctu.edu.tw:vbird): anonymous <==輸入 anonymous 匿名登入 
331 Anonymous login ok, send your complete email address as your password. 
Password:         <==輸入 name@server.xxx.xxx 型態的 mail-address 密碼 
230 Anonymous access granted, restrictions apply. 
Remote system type is UNIX. 
Using binary mode to transfer files. 
ftp> dir   <==檢查網站上的目錄 
200 PORT command successful. 
150 Opening ASCII mode data connection for file list. 
-rw-rw-rw-   1 linux    adm      39491400 Aug  3 21:00 00ls-lR 
-rw-rw-rw-   1 linux    adm       3091546 Aug  3 21:01 00ls-lR.gz 
-rw-r--r--   1 linux    wheel         232 Mar 15 22:00 00mirror.today 
drwxr-xr-x   5 linux    wheel        4096 Oct 29  2000 java 
drwxr-xr-x  14 linux    wheel        4096 Aug  2 19:31 kernel 
drwxr-xr-x   4 linux    wheel        4096 Sep 28  2000 mirrors 
226-Transfer complete. 
226 Quotas off 
ftp> cd kernel/v2.4 <==進入 kernel 底下的 v2.4 目錄 
250 CWD command successful. 
ftp> get linux-2.4.0.tar.bz2.sign <==捉下 linux-2.4.0.tar.bz.2.sign 這個檔 
local: linux-2.4.0.tar.bz2.sign remote: linux-2.4.0.tar.bz2.sign 
200 PORT command successful. 
150 Opening BINARY mode data connection for linux-2.4.0.tar.bz2.sign (248 bytes) 

226 Transfer complete. 
248 bytes received in 0.014 secs (17 Kbytes/sec)

style="font-size: xx-small;">ncftp

在使用 FTP 功能的時候,因為只能一次捉一個檔案,所以要捉一群檔案的時候就會有困擾。這時我們可以使用更容易登入匿名 FTP 站的 ncftp 來執行 FTP 功能!   

[root@tsai /root]# ncftp linux.cis.nctu.edu.tw 
ncftp / > mget  -R  kernel  <==將 kernel 這個目錄的東西全捉下來!

加上了 mget -R 目錄 這個指令後,就可以將目錄下的東西完全捉下來!好用吧!

style="font-size: xx-small;">gftp

這是在 X-Windows 使用的圖形介面 FTP 咚咚!這個咚咚的使用方法就跟 CutFTP 很相似!

  1. Client 端發送資料傳輸要求的命令給 Server:當需要進行資料的傳輸時,Client 端會啟用另一個高於 1024 的埠口來做為連線的準備(這個高於 1024 的埠口與步驟 1 那個埠口不是同一個!),並且 Client 端會主動的利用剛剛已經建立的指令通道(通常是 port 21)發送一個命令告訴 Server 說:『我已經準備好一個資料傳輸的埠口了,請準備進行傳輸吧』!特別留意喔,這個時候 Client 是透過『命令通道』來對 Server 下達命令的,而且已經通知 Server 我(client)要啟用的埠口了喔!

接下來我們進入/mnt/usbdisk」查看,可以看到這個USB硬碟的檔案,接下來要將資料拷貝出來就簡單了。舉例來說,如果我們想要將本機硬碟上的某個Datastore中的VM複製到USB硬碟中,只要先找到該VM置放的Datastore,再使用標準的Linux指令將資料copy出來就行。舉例來說,我們要將Nostalgia下的VM備份到USB中,只要輸入下面的指令即可。

10.5.2 命令執行的判斷依據: ; , &&, ||

在某些情況下,很多指令我想要一次輸入去執行,而不想要分次執行時,該如何是好?基本上你有兩個選擇, 一個是透過第十二章要介紹的 shell script 撰寫腳本去執行,一種則是透過底下的介紹來一次輸入多重指令喔!

  • cmd ; cmd (不考慮指令相關性的連續指令下達)

在某些時候,我們希望可以一次執行多個指令,例如在關機的時候我希望可以先執行兩次 sync 同步化寫入磁碟後才 shutdown 電腦,那麼可以怎麼作呢?這樣做呀:

[root@study ~]# sync; sync; shutdown -h now

在指令與指令中間利用分號 (;) 來隔開,這樣一來,分號前的指令執行完後就會立刻接著執行後面的指令了。 這真是方便啊~再來,換個角度來想,萬一我想要在某個目錄底下建立一個檔案,也就是說,如果該目錄存在的話, 那我才建立這個檔案,如果不存在,那就算了。也就是說這兩個指令彼此之間是有相關性的, 前一個指令是否成功的執行與後一個指令是否要執行有關!那就得動用到 && 或 || 囉!

  • $? (指令回傳值) 與 && 或 ||

如同上面談到的,兩個指令之間有相依性,而這個相依性主要判斷的地方就在於前一個指令執行的結果是否正確。 還記得本章之前我們曾介紹過指令回傳值吧!嘿嘿!沒錯,您真聰明!就是透過這個回傳值啦! 再複習一次『若前一個指令執行的結果為正確,在 Linux 底下會回傳一個 $? = 0 的值』。 那麼我們怎麼透過這個回傳值來判斷後續的指令是否要執行呢?這就得要藉由『 && 』及『 || 』的幫忙了! 注意喔,兩個 & 之間是沒有空格的!那個 | 則是 [Shift]+[] 的按鍵結果。

指令下達情況 說明
cmd1 && cmd2 1. 若 cmd1 執行完畢且正確執行($?=0),則開始執行 cmd2。
2. 若 cmd1 執行完畢且為錯誤 ($?≠0),則 cmd2 不執行。
cmd1 || cmd2 1. 若 cmd1 執行完畢且正確執行($?=0),則 cmd2 不執行。
2. 若 cmd1 執行完畢且為錯誤 ($?≠0),則開始執行 cmd2。

上述的 cmd1 及 cmd2 都是指令。好了,回到我們剛剛假想的情況,就是想要: (1)先判斷一個目錄是否存在; (2)若存在才在該目錄底下建立一個檔案。由於我們尚未介紹如何判斷式 (test) 的使用,在這裡我們使用 ls 以及回傳值來判斷目錄是否存在啦! 讓我們進行底下這個練習看看:

範例一:使用 ls 查閱目錄 /tmp/abc 是否存在,若存在則用 touch 建立 /tmp/abc/hehe 
[dmtsai@study ~]$ ls /tmp/abc && touch /tmp/abc/hehe
ls: cannot access /tmp/abc: No such file or directory
# ls 很乾脆的說明找不到該目錄,但並沒有 touch 的錯誤,表示 touch 並沒有執行

[dmtsai@study ~]$ mkdir /tmp/abc
[dmtsai@study ~]$ ls /tmp/abc && touch /tmp/abc/hehe
[dmtsai@study ~]$ ll /tmp/abc
-rw-rw-r--. 1 dmtsai dmtsai 0 Jul  9 19:16 hehe

看到了吧?如果 /tmp/abc 不存在時,touch 就不會被執行,若 /tmp/abc 存在的話,那麼 touch 就會開始執行囉! 很不錯用吧!不過,我們還得手動自行建立目錄,傷腦筋~能不能自動判斷,如果沒有該目錄就給予建立呢? 參考一下底下的例子先:

範例二:測試 /tmp/abc 是否存在,若不存在則予以建立,若存在就不作任何事情
[dmtsai@study ~]$ rm -r /tmp/abc                <==先刪除此目錄以方便測試
[dmtsai@study ~]$ ls /tmp/abc || mkdir /tmp/abc
ls: cannot access /tmp/abc: No such file or directory  <==真的不存在喔!
[dmtsai@study ~]$ ll -d /tmp/abc                  
drwxrwxr-x. 2 dmtsai dmtsai 6 Jul  9 19:17 /tmp/abca   <==結果出現了!有進行 mkdir

如果你一再重複『 ls /tmp/abc || mkdir /tmp/abc 』畫面也不會出現重複 mkdir 的錯誤!這是因為 /tmp/abc 已經存在, 所以後續的 mkdir 就不會進行!這樣理解否?好了,讓我們再次的討論一下,如果我想要建立 /tmp/abc/hehe 這個檔案, 但我並不知道 /tmp/abc 是否存在,那該如何是好?試看看:

範例三:我不清楚 /tmp/abc 是否存在,但就是要建立 /tmp/abc/hehe 檔案
[dmtsai@study ~]$ ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe

上面這個範例三總是會嘗試建立 /tmp/abc/hehe 的喔!不論 /tmp/abc 是否存在。那麼範例三應該如何解釋呢? 由於Linux 底下的指令都是由左往右執行的,所以範例三有幾種結果我們來分析一下:

  • (1)若 /tmp/abc 不存在故回傳 $?≠0,則 (2)因為 || 遇到非為 0 的 $? 故開始 mkdir /tmp/abc,由於 mkdir /tmp/abc 會成功進行,所以回傳 $?=0 (3)因為 && 遇到 $?=0 故會執行 touch /tmp/abc/hehe,最終 hehe 就被建立了;

  • (1)若 /tmp/abc 存在故回傳 $?=0,則 (2)因為 || 遇到 0 的 $? 不會進行,此時 $?=0 繼續向後傳,故 (3)因為 && 遇到 $?=0 就開始建立 /tmp/abc/hehe 了!最終 /tmp/abc/hehe 被建立起來。

整個流程圖示如下:

澳门新濠3559 25

圖10.5.2、指令依序執行的關係示意圖

上面這張圖顯示的兩股資料中,上方的線段為不存在 /tmp/abc 時所進行的指令行為,下方的線段則是存在 /tmp/abc 所在的指令行為。如上所述,下方線段由於存在 /tmp/abc 所以導致 $?=0 ,讓中間的 mkdir 就不執行了! 並將 $?=0 繼續往後傳給後續的 touch 去利用啦!瞭乎?在任何時刻你都可以拿上面這張圖作為示意! 讓我們來想想底下這個例題吧!

例題:
以 ls 測試 /tmp/vbirding 是否存在,若存在則顯示 "exist" ,若不存在,則顯示 "not exist"!
答:
這又牽涉到邏輯判斷的問題,如果存在就顯示某個資料,若不存在就顯示其他資料,那我可以這樣做:
ls /tmp/vbirding && echo "exist" || echo "not exist"
意思是說,當 ls /tmp/vbirding 執行後,若正確,就執行 echo "exist" ,若有問題,就執行 echo "not exist" !那如果寫成如下的狀況會出現什麼?
ls /tmp/vbirding || echo "not exist" && echo "exist"
這其實是有問題的,為什麼呢?由圖 10.5.2 的流程介紹我們知道指令是一個一個往後執行, 因此在上面的例子當中,如果 /tmp/vbirding 不存在時,他會進行如下動作:
  1. 若 ls /tmp/vbirding 不存在,因此回傳一個非為 0 的數值;
  2. 接下來經過 || 的判斷,發現前一個指令回傳非為 0 的數值,因此,程式開始執行 echo "not exist" ,而 echo "not exist" 程式肯定可以執行成功,因此會回傳一個 0 值給後面的指令;
  3. 經過 && 的判斷,咦!是 0 啊!所以就開始執行 echo "exist" 。
所以啊,嘿嘿!第二個例子裡面竟然會同時出現 not exist 與 exist 呢!真神奇~

經過這個例題的練習,你應該會瞭解,由於指令是一個接著一個去執行的,因此,如果真要使用判斷, 那麼這個 && 與 || 的順序就不能搞錯。一般來說,假設判斷式有三個,也就是:

command1 && command2 || command3

而且順序通常不會變,因為一般來說, command2 與 command3 會放置肯定可以執行成功的指令, 因此,依據上面例題的邏輯分析,您就會曉得為何要如此放置囉~這很有用的啦!而且.....考試也很常考~


 

cp /vmfs/volumes/datastore1/Nostalgia/*.* /mnt/usbdisk/.

10.6 管線命令 (pipe)

就如同前面所說的, bash 命令執行的時候有輸出的資料會出現! 那麼如果這群資料必需要經過幾道手續之後才能得到我們所想要的格式,應該如何來設定? 這就牽涉到管線命令的問題了 (pipe) ,管線命令使用的是『 | 』這個界定符號! 另外,管線命令與『連續下達命令』是不一樣的呦! 這點底下我們會再說明。底下我們先舉一個例子來說明一下簡單的管線命令。

假設我們想要知道 /etc/ 底下有多少檔案,那麼可以利用 ls /etc 來查閱,不過, 因為 /etc 底下的檔案太多,導致一口氣就將螢幕塞滿了~不知道前面輸出的內容是啥?此時,我們可以透過 less 指令的協助,利用:

[dmtsai@study ~]$ ls -al /etc | less

如此一來,使用 ls 指令輸出後的內容,就能夠被 less 讀取,並且利用 less 的功能,我們就能夠前後翻動相關的資訊了!很方便是吧?我們就來瞭解一下這個管線命令『 | 』的用途吧! 其實這個管線命令『 | 』僅能處理經由前面一個指令傳來的正確資訊,也就是 standard output 的資訊,對於 stdandard error 並沒有直接處理的能力。那麼整體的管線命令可以使用下圖表示:

澳门新濠3559 26

圖10.6.1、管線命令的處理示意圖

在每個管線後面接的第一個資料必定是『指令』喔!而且這個指令必須要能夠接受 standard input 的資料才行,這樣的指令才可以是為『管線命令』,例如 less, more, head, tail 等都是可以接受 standard input 的管線命令啦。至於例如 ls, cp, mv 等就不是管線命令了!因為 ls, cp, mv 並不會接受來自 stdin 的資料。 也就是說,管線命令主要有兩個比較需要注意的地方:

  • 管線命令僅會處理 standard output,對於 standard error output 會予以忽略
  • 管線命令必須要能夠接受來自前一個指令的資料成為 standard input 繼續處理才行。

Tips澳门新濠3559 27想一想,如果你硬要讓 standard error 可以被管線命令所使用,那該如何處理?其實就是透過上一小節的資料流重導向即可! 讓 2>&1 加入指令中~就可以讓 2> 變成 1> 囉!了解了嗎? ^_^

多說無益,讓我們來玩一些管線命令吧!底下的咚咚對系統管理非常有幫助喔!

Top

相關程式設定指令

  1. Server 端以 ftp-data 埠口主動連線到 Client :收到命令之後的 Server 會『主動』的以 ftp-data 埠口(一般為 port 20)向 Client 端通知的那個高於 1024 的埠口進行連線,特別需要留意的是,此時是『Server 端主動向 Client 端的連線』喔,所以該連線的 TCP 封包會帶有一個 SYN 的標誌在;

澳门新濠3559 28

10.6.1 擷取命令: cut, grep

什麼是擷取命令啊?說穿了,就是將一段資料經過分析後,取出我們所想要的。或者是經由分析關鍵字,取得我們所想要的那一行! 不過,要注意的是,一般來說,擷取訊息通常是針對『一行一行』來分析的, 並不是整篇訊息分析的喔~底下我們介紹兩個很常用的訊息擷取命令:

  • cut

cut 不就是『切』嗎?沒錯啦!這個指令可以將一段訊息的某一段給他『切』出來~ 處理的訊息是以『行』為單位喔!底下我們就來談一談:

[dmtsai@study ~]$ cut -d'分隔字元' -f fields <==用於有特定分隔字元
[dmtsai@study ~]$ cut -c 字元區間            <==用於排列整齊的訊息
選項與參數:
-d  :後面接分隔字元。與 -f 一起使用;
-f  :依據 -d 的分隔字元將一段訊息分割成為數段,用 -f 取出第幾段的意思;
-c  :以字元 (characters) 的單位取出固定字元區間;

範例一:將 PATH 變數取出,我要找出第五個路徑。
[dmtsai@study ~]$ echo ${PATH}
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dmtsai/.local/bin:/home/dmtsai/bin
#      1      |    2   |       3       |    4    |           5           |      6         |

[dmtsai@study ~]$ echo ${PATH} | cut -d ':' -f 5
# 如同上面的數字顯示,我們是以『 : 』作為分隔,因此會出現 /home/dmtsai/.local/bin
# 那麼如果想要列出第 3 與第 5 呢?,就是這樣:
[dmtsai@study ~]$ echo ${PATH} | cut -d ':' -f 3,5

範例二:將 export 輸出的訊息,取得第 12 字元以後的所有字串
[dmtsai@study ~]$ export
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/home/dmtsai"
declare -x HOSTNAME="study.centos.vbird"
.....(其他省略).....
# 注意看,每個資料都是排列整齊的輸出!如果我們不想要『 declare -x 』時,就得這麼做:

[dmtsai@study ~]$ export | cut -c 12-
HISTCONTROL="ignoredups"
HISTSIZE="1000"
HOME="/home/dmtsai"
HOSTNAME="study.centos.vbird"
.....(其他省略).....
# 知道怎麼回事了吧?用 -c 可以處理比較具有格式的輸出資料!
# 我們還可以指定某個範圍的值,例如第 12-20 的字元,就是 cut -c 12-20 等等!

範例三:用 last 將顯示的登入者的資訊中,僅留下使用者大名
[dmtsai@study ~]$ last
root   pts/1    192.168.201.101  Sat Feb  7 12:35   still logged in
root   pts/1    192.168.201.101  Fri Feb  6 12:13 - 18:46  (06:33)
root   pts/1    192.168.201.254  Thu Feb  5 22:37 - 23:53  (01:16)
# last 可以輸出『帳號/終端機/來源/日期時間』的資料,並且是排列整齊的

[dmtsai@study ~]$ last | cut -d ' ' -f 1
# 由輸出的結果我們可以發現第一個空白分隔的欄位代表帳號,所以使用如上指令:
# 但是因為 root   pts/1 之間空格有好幾個,並非僅有一個,所以,如果要找出 
# pts/1 其實不能以 cut -d ' ' -f 1,2 喔!輸出的結果會不是我們想要的。

cut 主要的用途在於將『同一行裡面的資料進行分解!』最常使用在分析一些數據或文字資料的時候! 這是因為有時候我們會以某些字元當作分割的參數,然後來將資料加以切割,以取得我們所需要的資料。 鳥哥也很常使用這個功能呢!尤其是在分析 log 檔案的時候!不過,cut 在處理多空格相連的資料時,可能會比較吃力一點,所以某些時刻可能會使用下一章的 awk 來取代的!

  • grep

剛剛的 cut 是將一行訊息當中,取出某部分我們想要的,而 grep 則是分析一行訊息, 若當中有我們所需要的資訊,就將該行拿出來~簡單的語法是這樣的:

[dmtsai@study ~]$ grep [-acinv] [--color=auto] '搜尋字串' filename
選項與參數:
-a :將 binary 檔案以 text 檔案的方式搜尋資料
-c :計算找到 '搜尋字串' 的次數
-i :忽略大小寫的不同,所以大小寫視為相同
-n :順便輸出行號
-v :反向選擇,亦即顯示出沒有 '搜尋字串' 內容的那一行!
--color=auto :可以將找到的關鍵字部分加上顏色的顯示喔!

範例一:將 last 當中,有出現 root 的那一行就取出來;
[dmtsai@study ~]$ last | grep 'root'

範例二:與範例一相反,只要沒有 root 的就取出!
[dmtsai@study ~]$ last | grep -v 'root'

範例三:在 last 的輸出訊息中,只要有 root 就取出,並且僅取第一欄
[dmtsai@study ~]$ last | grep 'root' |cut -d ' ' -f1
# 在取出 root 之後,利用上個指令 cut 的處理,就能夠僅取得第一欄囉!

範例四:取出 /etc/man_db.conf 內含 MANPATH 的那幾行
[dmtsai@study ~]$ grep --color=auto 'MANPATH' /etc/man_db.conf
....(前面省略)....
MANPATH_MAP     /usr/games              /usr/share/man
MANPATH_MAP     /opt/bin                /opt/man
MANPATH_MAP     /opt/sbin               /opt/man
# 神奇的是,如果加上 --color=auto 的選項,找到的關鍵字部分會用特殊顏色顯示喔!

grep 是個很棒的指令喔!他支援的語法實在是太多了~用在正規表示法裡頭, 能夠處理的資料實在是多的很~不過,我們這裡先不談正規表示法~下一章再來說明~ 您先瞭解一下, grep 可以解析一行文字,取得關鍵字,若該行有存在關鍵字,就會整行列出來!另外, CentOS 7 當中,預設的 grep 已經主動加上 --color=auto 在 alias 內了喔!

Top

style="font-size: xx-small;">set

style="font-family: 宋体;">這是用來設定或是觀看目前系統的設定的指令,若只打入 set 則僅會列出目前系統的參數。

style="font-size: xx-small;">uname

style="font-family: 宋体;">這是用來觀看系統名稱的指令,可以打入 -a 參數來列出所有資訊。   

[root@tsai /root]# uname -a 
Linux vbird.adsldns.org 2.2.12-20 #1 Mon Sep 27 10:25:54 EDT 1999 i586 unknown

style="font-size: xx-small;">setup

style="font-family: 宋体;">這個是常常使用來設定系統的一個指令,執行之後會有一個視窗出現,較常使用的是 System services 這一項,可用來設定開機的時候要開放的服務!

style="font-size: xx-small;">lilo

style="font-family: 宋体;">這是用來設定多重開機,或是開機選項的指令,詳細的流程請到這裡來看看!

style="font-size: xx-small;">Xconfigurator

這是用來簡易的設定 X-Windows 的指令,當你的 X-Windows 確定是可以跑的,而你想要改變一些設定,例如:解析度、色彩度等等,就直接使用這個指令啦!

style="font-size: xx-small;">xf86config

這是用來設定 X-Windows 的指令!這個指令會比 Xconfigurator 麻煩,不過當你的 X-Windows 沒有辦法跑的時候,這個咚咚是很好用的!

 

10.6.2 排序命令: sort, wc, uniq

很多時候,我們都會去計算一次資料裡頭的相同型態的資料總數,舉例來說, 使用 last 可以查得系統上面有登入主機者的身份。那麼我可以針對每個使用者查出他們的總登入次數嗎? 此時就得要排序與計算之類的指令來輔助了!底下我們介紹幾個好用的排序與統計指令喔!

  • sort

sort 是很有趣的指令,他可以幫我們進行排序,而且可以依據不同的資料型態來排序喔! 例如數字與文字的排序就不一樣。此外,排序的字元與語系的編碼有關,因此, 如果您需要排序時,建議使用 LANG=C 來讓語系統一,資料排序比較好一些。

[dmtsai@study ~]$ sort [-fbMnrtuk] [file or stdin]
選項與參數:
-f  :忽略大小寫的差異,例如 A 與 a 視為編碼相同;
-b  :忽略最前面的空白字元部分;
-M  :以月份的名字來排序,例如 JAN, DEC 等等的排序方法;
-n  :使用『純數字』進行排序(預設是以文字型態來排序的);
-r  :反向排序;
-u  :就是 uniq ,相同的資料中,僅出現一行代表;
-t  :分隔符號,預設是用 [tab] 鍵來分隔;
-k  :以那個區間 (field) 來進行排序的意思

範例一:個人帳號都記錄在 /etc/passwd 下,請將帳號進行排序。
[dmtsai@study ~]$ cat /etc/passwd | sort
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
alex:x:1001:1002::/home/alex:/bin/bash
# 鳥哥省略很多的輸出~由上面的資料看起來, sort 是預設『以第一個』資料來排序,
# 而且預設是以『文字』型態來排序的喔!所以由 a 開始排到最後囉!

範例二:/etc/passwd 內容是以 : 來分隔的,我想以第三欄含後面資料來排序,該如何?
[dmtsai@study ~]$ cat /etc/passwd | sort -t ':' -k 3
root:x:0:0:root:/root:/bin/bash
dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash
alex:x:1001:1002::/home/alex:/bin/bash
arod:x:1002:1003::/home/arod:/bin/bash
# 看到特殊字體的輸出部分了吧?怎麼會這樣排列啊?呵呵!沒錯啦~若單純以第三欄位來處理則是:

[dmtsai@study ~]$ cat /etc/passwd | sort -t ':' -k 3,3
# 如果是以文字型態來排序的話,原本就會是這樣,想要使用數字排序:
# cat /etc/passwd | sort -t ':' -k 3,3 -n
# 這樣才行啊!用那個 -n 來告知 sort 以數字來排序啊!

範例三:利用 last ,將輸出的資料僅取帳號,並加以排序
[dmtsai@study ~]$ last | cut -d ' ' -f1 | sort

sort 同樣是很常用的指令呢!因為我們常常需要比較一些資訊啦! 舉個上面的第二個例子來說好了!今天假設你有很多的帳號,而且你想要知道最大的使用者 ID 目前到哪一號了!呵呵!使用 sort 一下子就可以知道答案咯!當然其使用還不止此啦!有空的話不妨玩一玩!

  • uniq

如果我排序完成了,想要將重複的資料僅列出一個顯示,可以怎麼做呢?

[dmtsai@study ~]$ uniq [-ic]
選項與參數:
-i  :忽略大小寫字元的不同;
-c  :進行計數

範例一:使用 last 將帳號列出,僅取出帳號欄,進行排序後僅取出一位;
[dmtsai@study ~]$ last | cut -d ' ' -f1 | sort | uniq

範例二:承上題,如果我還想要知道每個人的登入總次數呢?
[dmtsai@study ~]$ last | cut -d ' ' -f1 | sort | uniq -c
      1
      6 (unknown
     47 dmtsai
      4 reboot
      7 root
      1 wtmp
# 從上面的結果可以發現 reboot 有 4 次, root 登入則有 7 次!大部分是以 dmtsai 來操作!
# wtmp 與第一行的空白都是 last 的預設字元,那兩個可以忽略的!

這個指令用來將『重複的行刪除掉只顯示一個』,舉個例子來說, 你要知道這個月份登入你主機的使用者有誰,而不在乎他的登入次數,那麼就使用上面的範例, (1)先將所有的資料列出;(2)再將人名獨立出來;(3)經過排序;(4)只顯示一個! 由於這個指令是在將重複的東西減少,所以當然需要『配合排序過的檔案』來處理囉!

  • wc

如果我想要知道 /etc/man_db.conf 這個檔案裡面有多少字?多少行?多少字元的話, 可以怎麼做呢?其實可以利用 wc 這個指令來達成喔!他可以幫我們計算輸出的訊息的整體資料!

[dmtsai@study ~]$ wc [-lwm]
選項與參數:
-l  :僅列出行;
-w  :僅列出多少字(英文單字);
-m  :多少字元;

範例一:那個 /etc/man_db.conf 裡面到底有多少相關字、行、字元數?
[dmtsai@study ~]$ cat /etc/man_db.conf | wc 
    131     723    5171
# 輸出的三個數字中,分別代表: 『行、字數、字元數』

範例二:我知道使用 last 可以輸出登入者,但是 last 最後兩行並非帳號內容,那麼請問,
        我該如何以一行指令串取得登入系統的總人次?
[dmtsai@study ~]$ last | grep [a-zA-Z] | grep -v 'wtmp' | grep -v 'reboot' | 
> grep -v 'unknown' |wc -l 
# 由於 last 會輸出空白行, wtmp, unknown, reboot 等無關帳號登入的資訊,因此,我利用
# grep 取出非空白行,以及去除上述關鍵字那幾行,再計算行數,就能夠瞭解囉!

wc 也可以當作指令?這可不是上洗手間的 WC 呢!這是相當有用的計算檔案內容的一個工具組喔!舉個例子來說, 當你要知道目前你的帳號檔案中有多少個帳號時,就使用這個方法:『 cat /etc/passwd | wc -l 』啦!因為 /etc/passwd 裡頭一行代表一個使用者呀! 所以知道行數就曉得有多少的帳號在裡頭了!而如果要計算一個檔案裡頭有多少個字元時,就使用 wc -m 這個選項吧!

Top


  1. Client 端回應主機端,並繼續完成三向交握:在接到 Server 來的封包之後, Client 會回應一個帶有 ACK 確認的封包,並繼續來完成另一個三向交握的程序,此時,資料傳輸的通道才正式的建立。

10.6.3 雙向重導向: tee

想個簡單的東西,我們由前一節知道 > 會將資料流整個傳送給檔案或裝置,因此我們除非去讀取該檔案或裝置, 否則就無法繼續利用這個資料流。萬一我想要將這個資料流的處理過程中將某段訊息存下來,應該怎麼做? 利用 tee 就可以囉~我們可以這樣簡單的看一下:

澳门新濠3559 29

圖10.6.2、tee 的工作流程示意圖

tee 會同時將資料流分送到檔案去與螢幕 (screen);而輸出到螢幕的,其實就是 stdout ,那就可以讓下個指令繼續處理喔!

[dmtsai@study ~]$ tee [-a] file
選項與參數:
-a  :以累加 (append) 的方式,將資料加入 file 當中!

[dmtsai@study ~]$ last | tee last.list | cut -d " " -f1
# 這個範例可以讓我們將 last 的輸出存一份到 last.list 檔案中;

[dmtsai@study ~]$ ls -l /home | tee ~/homefile | more
# 這個範例則是將 ls 的資料存一份到 ~/homefile ,同時螢幕也有輸出訊息!

[dmtsai@study ~]$ ls -l / | tee -a ~/homefile | more
# 要注意! tee 後接的檔案會被覆蓋,若加上 -a 這個選項則能將訊息累加。

tee 可以讓 standard output 轉存一份到檔案內並將同樣的資料繼續送到螢幕去處理! 這樣除了可以讓我們同時分析一份資料並記錄下來之外,還可以作為處理一份資料的中間暫存檔記錄之用! tee 這傢伙在很多選擇/填充的認證考試中很容易考呢!

Top

X-Window內的設定指令

 

10.6.4 字元轉換命令: tr, col, join, paste, expand

我們在 vim 程式編輯器當中,提到過 DOS 斷行字元與 Unix 斷行字元的不同,並且可以使用 dos2unix 與 unix2dos 來完成轉換。好了,那麼思考一下,是否還有其他常用的字元替代? 舉例來說,要將大寫改成小寫,或者是將資料中的 [tab] 按鍵轉成空白鍵?還有,如何將兩篇訊息整合成一篇? 底下我們就來介紹一下這些字元轉換命令在管線當中的使用方法:

  • tr

tr 可以用來刪除一段訊息當中的文字,或者是進行文字訊息的替換!

[dmtsai@study ~]$ tr [-ds] SET1 ...
選項與參數:
-d  :刪除訊息當中的 SET1 這個字串;
-s  :取代掉重複的字元!

範例一:將 last 輸出的訊息中,所有的小寫變成大寫字元:
[dmtsai@study ~]$ last | tr '[a-z]' '[A-Z]'
# 事實上,沒有加上單引號也是可以執行的,如:『 last | tr [a-z] [A-Z] 』

範例二:將 /etc/passwd 輸出的訊息中,將冒號 (:) 刪除
[dmtsai@study ~]$ cat /etc/passwd | tr -d ':'

範例三:將 /etc/passwd 轉存成 dos 斷行到 /root/passwd 中,再將 ^M 符號刪除
[dmtsai@study ~]$ cp /etc/passwd ~/passwd && unix2dos ~/passwd
[dmtsai@study ~]$ file /etc/passwd ~/passwd
/etc/passwd:         ASCII text
/home/dmtsai/passwd: ASCII text, with CRLF line terminators  <==就是 DOS 斷行
[dmtsai@study ~]$ cat ~/passwd | tr -d 'r' > ~/passwd.linux
# 那個 r 指的是 DOS 的斷行字元,關於更多的字符,請參考 man tr
[dmtsai@study ~]$ ll /etc/passwd ~/passwd*
-rw-r--r--. 1 root   root   2092 Jun 17 00:20 /etc/passwd
-rw-r--r--. 1 dmtsai dmtsai 2133 Jul  9 22:13 /home/dmtsai/passwd
-rw-rw-r--. 1 dmtsai dmtsai 2092 Jul  9 22:13 /home/dmtsai/passwd.linux
# 處理過後,發現檔案大小與原本的 /etc/passwd 就一致了!

其實這個指令也可以寫在『正規表示法』裡頭!因為他也是由正規表示法的方式來取代資料的! 以上面的例子來說,使用 [] 可以設定一串字呢!也常常用來取代檔案中的怪異符號! 例如上面第三個例子當中,可以去除 DOS 檔案留下來的 ^M 這個斷行的符號!這東西相當的有用!相信處理 Linux & Windows 系統中的人們最麻煩的一件事就是這個事情啦!亦即是 DOS 底下會自動的在每行行尾加入 ^M 這個斷行符號!這個時候除了以前講過的 dos2unix 之外,我們也可以使用這個 tr 來將 ^M 去除! ^M 可以使用 r 來代替之!

  • col
[dmtsai@study ~]$ col [-xb]
選項與參數:
-x  :將 tab 鍵轉換成對等的空白鍵

範例一:利用 cat -A 顯示出所有特殊按鍵,最後以 col 將 [tab] 轉成空白
[dmtsai@study ~]$ cat -A /etc/man_db.conf  <==此時會看到很多 ^I 的符號,那就是 tab
[dmtsai@study ~]$ cat /etc/man_db.conf | col -x | cat -A | more
# 嘿嘿!如此一來, [tab] 按鍵會被取代成為空白鍵,輸出就美觀多了!

雖然 col 有他特殊的用途,不過,很多時候,他可以用來簡單的處理將 [tab] 按鍵取代成為空白鍵! 例如上面的例子當中,如果使用 cat -A 則 [tab] 會以 ^I 來表示。 但經過 col -x 的處理,則會將 [tab] 取代成為對等的空白鍵!

  • join

join 看字面上的意義 (加入/參加) 就可以知道,他是在處理兩個檔案之間的資料, 而且,主要是在處理『兩個檔案當中,有 "相同資料" 的那一行,才將他加在一起』的意思。我們利用底下的簡單例子來說明:

[dmtsai@study ~]$ join [-ti12] file1 file2
選項與參數:
-t  :join 預設以空白字元分隔資料,並且比對『第一個欄位』的資料,
      如果兩個檔案相同,則將兩筆資料聯成一行,且第一個欄位放在第一個!
-i  :忽略大小寫的差異;
-1  :這個是數字的 1 ,代表『第一個檔案要用那個欄位來分析』的意思;
-2  :代表『第二個檔案要用那個欄位來分析』的意思。

範例一:用 root 的身份,將 /etc/passwd 與 /etc/shadow 相關資料整合成一欄
[root@study ~]# head -n 3 /etc/passwd /etc/shadow
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

==> /etc/shadow <==
root:$6$wtbCCce/PxMeE5wm$KE2IfSJr...:16559:0:99999:7:::
bin:*:16372:0:99999:7:::
daemon:*:16372:0:99999:7:::
# 由輸出的資料可以發現這兩個檔案的最左邊欄位都是相同帳號!且以 : 分隔

[root@study ~]# join -t ':' /etc/passwd /etc/shadow | head -n 3
root:x:0:0:root:/root:/bin/bash:$6$wtbCCce/PxMeE5wm$KE2IfSJr...:16559:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:16372:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:16372:0:99999:7:::
# 透過上面這個動作,我們可以將兩個檔案第一欄位相同者整合成一列!
# 第二個檔案的相同欄位並不會顯示(因為已經在最左邊的欄位出現了啊!)

範例二:我們知道 /etc/passwd 第四個欄位是 GID ,那個 GID 記錄在 
        /etc/group 當中的第三個欄位,請問如何將兩個檔案整合?
[root@study ~]# head -n 3 /etc/passwd /etc/group
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

==> /etc/group <==
root:x:0:
bin:x:1:
daemon:x:2:
# 從上面可以看到,確實有相同的部分喔!趕緊來整合一下!

[root@study ~]# join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3
0:root:x:0:root:/root:/bin/bash:root:x:
1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:
2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:
# 同樣的,相同的欄位部分被移動到最前面了!所以第二個檔案的內容就沒再顯示。
# 請讀者們配合上述顯示兩個檔案的實際內容來比對!

這個 join 在處理兩個相關的資料檔案時,就真的是很有幫助的啦! 例如上面的案例當中,我的 /etc/passwd, /etc/shadow, /etc/group 都是有相關性的, 其中 /etc/passwd, /etc/shadow 以帳號為相關性,至於 /etc/passwd, /etc/group 則以所謂的 GID (帳號的數字定義) 來作為他的相關性。根據這個相關性, 我們可以將有關係的資料放置在一起!這在處理資料可是相當有幫助的! 但是上面的例子有點難,希望您可以靜下心好好的看一看原因喔!

此外,需要特別注意的是,在使用 join 之前,你所需要處理的檔案應該要事先經過排序 (sort) 處理! 否則有些比對的項目會被略過呢!特別注意了!

  • paste

這個 paste 就要比 join 簡單多了!相對於 join 必須要比對兩個檔案的資料相關性, paste 就直接『將兩行貼在一起,且中間以 [tab] 鍵隔開』而已!簡單的使用方法:

[dmtsai@study ~]$ paste [-d] file1 file2
選項與參數:
-d  :後面可以接分隔字元。預設是以 [tab] 來分隔的!
-   :如果 file 部分寫成 - ,表示來自 standard input 的資料的意思。

範例一:用 root 身份,將 /etc/passwd 與 /etc/shadow 同一行貼在一起
[root@study ~]# paste /etc/passwd /etc/shadow
root:x:0:0:root:/root:/bin/bash root:$6$wtbCCce/PxMeE5wm$KE2IfSJr...:16559:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin        bin:*:16372:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:16372:0:99999:7:::
# 注意喔!同一行中間是以 [tab] 按鍵隔開的!

範例二:先將 /etc/group 讀出(用 cat),然後與範例一貼上一起!且僅取出前三行
[root@study ~]# cat /etc/group|paste /etc/passwd /etc/shadow -|head -n 3
# 這個例子的重點在那個 - 的使用!那玩意兒常常代表 stdin 喔!
  • expand

這玩意兒就是在將 [tab] 按鍵轉成空白鍵啦~可以這樣玩:

[dmtsai@study ~]$ expand [-t] file
選項與參數:
-t  :後面可以接數字。一般來說,一個 tab 按鍵可以用 8 個空白鍵取代。
      我們也可以自行定義一個 [tab] 按鍵代表多少個字元呢!

範例一:將 /etc/man_db.conf 內行首為 MANPATH 的字樣就取出;僅取前三行;
[dmtsai@study ~]$ grep '^MANPATH' /etc/man_db.conf | head -n 3
MANPATH_MAP     /bin                    /usr/share/man
MANPATH_MAP     /usr/bin                /usr/share/man
MANPATH_MAP     /sbin                   /usr/share/man
# 行首的代表標誌為 ^ ,這個我們留待下節介紹!先有概念即可!

範例二:承上,如果我想要將所有的符號都列出來?(用 cat)
[dmtsai@study ~]$ grep '^MANPATH' /etc/man_db.conf | head -n 3 |cat -A
MANPATH_MAP^I/bin^I^I^I/usr/share/man$
MANPATH_MAP^I/usr/bin^I^I/usr/share/man$
MANPATH_MAP^I/sbin^I^I^I/usr/share/man$
# 發現差別了嗎?沒錯~ [tab] 按鍵可以被 cat -A 顯示成為 ^I 

範例三:承上,我將 [tab] 按鍵設定成 6 個字元的話?
[dmtsai@study ~]$ grep '^MANPATH' /etc/man_db.conf | head -n 3 | expand -t 6 - | cat -A
MANPATH_MAP /bin              /usr/share/man$
MANPATH_MAP /usr/bin          /usr/share/man$
MANPATH_MAP /sbin             /usr/share/man$
123456123456123456123456123456123456123456123456...
# 仔細看一下上面的數字說明,因為我是以 6 個字元來代表一個 [tab] 的長度,所以,
# MAN... 到 /usr 之間會隔 12 (兩個 [tab]) 個字元喔!如果 tab 改成 9 的話,
# 情況就又不同了!這裡也不好理解~您可以多設定幾個數字來查閱就曉得!

expand 也是挺好玩的~他會自動將 [tab] 轉成空白鍵~所以,以上面的例子來說, 使用 cat -A 就會查不到 ^I 的字符囉~此外,因為 [tab] 最大的功能就是格式排列整齊! 我們轉成空白鍵後,這個空白鍵也會依據我們自己的定義來增加大小~ 所以,並不是一個 ^I 就會換成 8 個空白喔!這個地方要特別注意的哩! 此外,您也可以參考一下 unexpand 這個將空白轉成 [tab] 的指令功能啊! ^_^

Top

style="font-size: xx-small;">startx

這是開始執行 X-Windows 的指令!

style="font-size: xx-small;">netconf

這是網路設定的指令!

style="font-size: xx-small;">netcfg

這也是網路設定的指令!

style="font-size: xx-small;">XF86Setup

這是在 X-Windows 下以圖形介面設定 解析度、色彩度 的設定指令。

 

10.6.5 分割命令: split

如果你有檔案太大,導致一些攜帶式裝置無法複製的問題,嘿嘿!找 split 就對了! 他可以幫你將一個大檔案,依據檔案大小或行數來分割,就可以將大檔案分割成為小檔案了! 快速又有效啊!真不錯~

[dmtsai@study ~]$ split [-bl] file PREFIX
選項與參數:
-b  :後面可接欲分割成的檔案大小,可加單位,例如 b, k, m 等;
-l  :以行數來進行分割。
PREFIX :代表前置字元的意思,可作為分割檔案的前導文字。

範例一:我的 /etc/services 有六百多K,若想要分成 300K 一個檔案時?
[dmtsai@study ~]$ cd /tmp; split -b 300k /etc/services services
[dmtsai@study tmp]$ ll -k services*
-rw-rw-r--. 1 dmtsai dmtsai 307200 Jul  9 22:52 servicesaa
-rw-rw-r--. 1 dmtsai dmtsai 307200 Jul  9 22:52 servicesab
-rw-rw-r--. 1 dmtsai dmtsai  55893 Jul  9 22:52 servicesac
# 那個檔名可以隨意取的啦!我們只要寫上前導文字,小檔案就會以
# xxxaa, xxxab, xxxac 等方式來建立小檔案的!

範例二:如何將上面的三個小檔案合成一個檔案,檔名為 servicesback
[dmtsai@study tmp]$ cat services* >> servicesback
# 很簡單吧?就用資料流重導向就好啦!簡單!

範例三:使用 ls -al / 輸出的資訊中,每十行記錄成一個檔案
[dmtsai@study tmp]$ ls -al / | split -l 10 - lsroot
[dmtsai@study tmp]$ wc -l lsroot*
  10 lsrootaa
  10 lsrootab
   4 lsrootac
  24 total
# 重點在那個 - 啦!一般來說,如果需要 stdout/stdin 時,但偏偏又沒有檔案,
# 有的只是 - 時,那麼那個 - 就會被當成 stdin 或 stdout ~

在 Windows 作業系統下,你要將檔案分割需要如何作?傷腦筋吧!在 Linux 底下就簡單的多了!你要將檔案分割的話,那麼就使用 -b size 來將一個分割的檔案限制其大小,如果是行數的話,那麼就使用 -l line 來分割!好用的很!如此一來,你就可以輕易的將你的檔案分割成某些軟體能夠支援的最大容量 (例如 gmail 單一信件 25MB 之類的!),方便你 copy 囉!

Top


 

10.6.6 參數代換: xargs

xargs 是在做什麼的呢?就以字面上的意義來看, x 是加減乘除的乘號,args 則是 arguments (參數) 的意思,所以說,這個玩意兒就是在產生某個指令的參數的意思! xargs 可以讀入 stdin 的資料,並且以空白字元或斷行字元作為分辨,將 stdin 的資料分隔成為 arguments 。 因為是以空白字元作為分隔,所以,如果有一些檔名或者是其他意義的名詞內含有空白字元的時候, xargs 可能就會誤判了~他的用法其實也還滿簡單的!就來看一看先!

[dmtsai@study ~]$ xargs [-0epn] command
選項與參數:
-0  :如果輸入的 stdin 含有特殊字元,例如 `, , 空白鍵等等字元時,這個 -0 參數
      可以將他還原成一般字元。這個參數可以用於特殊狀態喔!
-e  :這個是 EOF (end of file) 的意思。後面可以接一個字串,當 xargs 分析到這個字串時,
      就會停止繼續工作!
-p  :在執行每個指令的 argument 時,都會詢問使用者的意思;
-n  :後面接次數,每次 command 指令執行時,要使用幾個參數的意思。
當 xargs 後面沒有接任何的指令時,預設是以 echo 來進行輸出喔!

範例一:將 /etc/passwd 內的第一欄取出,僅取三行,使用 id 這個指令將每個帳號內容秀出來
[dmtsai@study ~]$ id root
uid=0(root) gid=0(root) groups=0(root)   # 這個 id 指令可以查詢使用者的 UID/GID 等資訊

[dmtsai@study ~]$ id $(cut -d ':' -f 1 /etc/passwd | head -n 3)
# 雖然使用 $(cmd) 可以預先取得參數,但可惜的是, id 這個指令『僅』能接受一個參數而已!
# 所以上述的這個指令執行會出現錯誤!根本不會顯示用戶的 ID 啊!

[dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | id
uid=1000(dmtsai) gid=1000(dmtsai) groups=1000(dmtsai),10(wheel)   # 我不是要查自己啊!
# 因為 id 並不是管線命令,因此在上面這個指令執行後,前面的東西通通不見!只會執行 id!

[dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs id
# 依舊會出現錯誤!這是因為 xargs 一口氣將全部的資料通通丟給 id 處理~但 id 就接受 1 個啊最多!

[dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
uid=0(root) gid=0(root) groups=0(root)
uid=1(bin) gid=1(bin) groups=1(bin)
uid=2(daemon) gid=2(daemon) groups=2(daemon)
# 透過 -n 來處理,一次給予一個參數,因此上述的結果就 OK 正常的顯示囉!

範例二:同上,但是每次執行 id 時,都要詢問使用者是否動作?
[dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id
id root ?...y
uid=0(root) gid=0(root) groups=0(root)
id bin ?...y
.....(底下省略).....
# 呵呵!這個 -p 的選項可以讓使用者的使用過程中,被詢問到每個指令是否執行!

範例三:將所有的 /etc/passwd 內的帳號都以 id 查閱,但查到 sync 就結束指令串
[dmtsai@study ~]$ cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id
# 仔細與上面的案例做比較。也同時注意,那個 -e'sync' 是連在一起的,中間沒有空白鍵。
# 上個例子當中,第六個參數是 sync 啊,那麼我們下達 -e'sync' 後,則分析到 sync 這個字串時,
# 後面的其他 stdin 的內容就會被 xargs 捨棄掉了!

其實,在 man xargs 裡面就有三四個小範例,您可以自行參考一下內容。 此外, xargs 真的是很好用的一個玩意兒!您真的需要好好的參詳參詳!會使用 xargs 的原因是, 很多指令其實並不支援管線命令,因此我們可以透過 xargs 來提供該指令引用 standard input 之用!舉例來說,我們使用如下的範例來說明:

範例四:找出 /usr/sbin 底下具有特殊權限的檔名,並使用 ls -l 列出詳細屬性
[dmtsai@study ~]$ find /usr/sbin -perm /7000 | xargs ls -l
-rwx--s--x. 1 root lock      11208 Jun 10  2014 /usr/sbin/lockdev
-rwsr-xr-x. 1 root root     113400 Mar  6 12:17 /usr/sbin/mount.nfs
-rwxr-sr-x. 1 root root      11208 Mar  6 11:05 /usr/sbin/netreport
.....(底下省略).....
# 聰明的讀者應該會想到使用『 ls -l $(find /usr/sbin -perm /7000) 』來處理這個範例!
# 都 OK!能解決問題的方法,就是好方法!

Top

本章問題討論:

使用到的 port:

10.6.7 關於減號 - 的用途

管線命令在 bash 的連續的處理程序中是相當重要的!另外,在 log file 的分析當中也是相當重要的一環, 所以請特別留意!另外,在管線命令當中,常常會使用到前一個指令的 stdout 作為這次的 stdin , 某些指令需要用到檔案名稱 (例如 tar) 來進行處理時,該 stdin 與 stdout 可以利用減號 "-" 來替代, 舉例來說:

[root@study ~]# mkdir /tmp/homeback
[root@study ~]# tar -cvf - /home | tar -xvf - -C /tmp/homeback

上面這個例子是說:『我將 /home 裡面的檔案給他打包,但打包的資料不是紀錄到檔案,而是傳送到 stdout; 經過管線後,將 tar -cvf - /home 傳送給後面的 tar -xvf - 』。後面的這個 - 則是取用前一個指令的 stdout, 因此,我們就不需要使用 filename 了!這是很常見的例子喔!注意注意!

  1. style="font-size: small;">Q:在 Linux 上面都是一些線上的英文說明,有沒有中文說明,或更詳細的說明資料呢?

    style="font-size: small;">A:

    其實在網路上已經有一票高手在進行 Linux how to 的翻譯工作,這是一個很有意義的事情,因為可以讓新手或者是一些有需要使用 Linux 的人,有一個很好的學習文件。你可以來下面的網址看看:

    style="font-family: 宋体;">中文How-to:

    style="font-family: 宋体;">英文How-to:

  2. style="font-size: small;">Q:在 Linux 中如何加入新硬碟?

    style="font-size: small;">A:

    style="font-family: 宋体;">其實加入新硬碟的方法也是很簡單的:

安裝硬碟:關掉 Linux 主機電源,調整 Hard Disk 的 Jump (master 或 slave),串接在 IDE 的介面,請注意,留意你增加的硬碟所串接的 IDE 介面為哪一個插槽,例如你插在 IDE2 的 Master ,則你的硬碟應為 hdc;

新增硬體於BIOS:開啟電腦後,按 del 鍵進入 BIOS,選擇 IDE Hard Disk Detector 字樣的選項,讓BIOS去捉硬碟,然後再選擇 Save and Exit;

Linux 安裝:開機進入 Linux 的時候,系統會告訴你有捉到一個新的硬體,你可以按 『configure』 由系統直接安裝即可;

格式化硬碟:以 root 的身份進入 Linux 後,執行以下兩個程式:

  • style="font-family: 宋体;">fdisk  /dev/hdc  <== hdc 與你的硬碟串接的IDE介面有關,關於這個指令的介紹請參考上面的指令說明;
  • style="font-family: 宋体;">mke2fs  -c  /dev/hdc1  <==假設硬碟全部配置成一個大硬碟,則硬碟應為 hdc1 ,以 mke2fs 將系統規劃為 Linux 的系統檔。

開機自動載入:再來則是以 vi 修改 /etc/fstab 檔案,讓每次開機把這個硬碟直接掛入系統中。例如 hdc1 這顆硬碟掛在 /mnt/hdc1 中,則 fstab 的檔案有點像這樣:(/dev/hdc1 那一行是新加入的!)

/dev/hda1               /                       ext2    defaults        1 1 
/dev/hda5               swap                    swap    defaults        0 0 
/dev/hdc1               /mnt/hdc1               ext2    defaults        1 1
  • style="font-family: 宋体;">安裝完成:然後再重新開機就可以啦!

    style="font-size: small;">Q:在 Linux 中如何增加新使用者呢?

    style="font-size: small;">A:

    style="font-family: 宋体;">無論是加入新使用者或者是加入新群組,都可以使用 /bin/userconf 這個程式來完成,使用這個程式,只要輸入 ID 及 pass word 就可以啦!(不過你必須是 root 的身份才可以執行!)詳細的執行請看上面的指令說明。

  1. style="font-size: small;">Q:在 Linux 中如何製作開機片?

    style="font-size: small;">A:

    style="font-family: 宋体;">無論何種系統,有個開機片總是比較安心的! Linux 也是一樣!雖然他很穩定,但是並不是說就不會有問題,因此製作可開機磁片以利解救 Linux 問題是一個好習慣!製作開機片的方法很簡單,只要下達:

  • style="font-family: 宋体;">mkbootdisk --device /dev/fd0 `uname -r`

就可以啦!

 

10.7 重點回顧

  • 由於核心在記憶體中是受保護的區塊,因此我們必須要透過『 Shell 』將我們輸入的指令與 Kernel 溝通,好讓 Kernel 可以控制硬體來正確無誤的工作
  • 學習 shell 的原因主要有:文字介面的 shell 在各大 distribution 都一樣;遠端管理時文字介面速度較快; shell 是管理 Linux 系統非常重要的一環,因為 Linux 內很多控制都是以 shell 撰寫的。
  • 系統合法的 shell 均寫在 /etc/shells 檔案中;
  • 使用者預設登入取得的 shell 記錄於 /etc/passwd 的最後一個欄位;
  • bash 的功能主要有:命令編修能力;命令與檔案補全功能;命令別名設定功能;工作控制、前景背景控制;程式化腳本;萬用字元
  • type 可以用來找到執行指令為何種類型,亦可用於與 which 相同的功能;
  • 變數就是以一組文字或符號等,來取代一些設定或者是一串保留的資料
  • 變數主要有環境變數與自訂變數,或稱為全域變數與區域變數
  • 使用 env 與 export 可觀察環境變數,其中 export 可以將自訂變數轉成環境變數;
  • set 可以觀察目前 bash 環境下的所有變數;
  • $? 亦為變數,是前一個指令執行完畢後的回傳值。在 Linux 回傳值為 0 代表執行成功;
  • locale 可用於觀察語系資料;
  • 可用 read 讓使用者由鍵盤輸入變數的值
  • ulimit 可用以限制使用者使用系統的資源情況
  • bash 的設定檔主要分為 login shell 與 non-login shell。login shell 主要讀取 /etc/profile 與 ~/.bash_profile, non-login shell 則僅讀取 ~/.bashrc
  • 在使用 vim 時,若不小心按了 [ctrl]+s 則畫面會被凍結。你可以使用 [ctrl]+q 來解除凍結
  • 萬用字元主要有: *, ?, [] 等等
  • 資料流重導向透過 >, 2>, < 之類的符號將輸出的資訊轉到其他檔案或裝置去;
  • 連續命令的下達可透過 ; && || 等符號來處理
  • 管線命令的重點是:『管線命令僅會處理 standard output,對於 standard error output 會予以忽略』 『管線命令必須要能夠接受來自前一個指令的資料成為 standard input 繼續處理才行。』
  • 本章介紹的管線命令主要有:cut, grep, sort, wc, uniq, tee, tr, col, join, paste, expand, split, xargs 等。

(1)命令通道的 ftp (預設為 port 21 ) 與
(2)資料傳輸的 ftp-data (預設為port 20)

10.8 本章習題

( 要看答案請將滑鼠移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )

  • 情境模擬題一:由於 ~/.bash_history 僅能記錄指令,我想要在每次登出時都記錄時間,並將後續的指令 50 筆記錄下來, 可以如何處理?

    • 目標:瞭解 history ,並透過資料流重導向的方式記錄歷史命令;
    • 前提:需要瞭解本章的資料流重導向,以及瞭解 bash 的各個環境設定檔資訊。
其實處理的方式非常簡單,我們可以瞭解 date 可以輸出時間,而利用
~/.myhistory 來記錄所有歷史記錄, 而目前最新的 50 筆歷史記錄可以使用
history 50 來顯示,故可以修改 ~/.bash_logout 成為底下的模樣:  
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr class="odd">
<td><pre><code>[dmtsai@study ~]$ vim ~/.bash_logout
date &gt;&gt; ~/.myhistory
history 50 &gt;&gt; ~/.myhistory
clear


簡答題部分:

  • 在 Linux 上可以找到哪些 shell(舉出三個) ?那個檔案記錄可用的 shell ?而 Linux 預設的 shell 是? 1) /bin/bash, /bin/tcsh, /bin/csh
    2) /etc/shells
    3) bash ,亦即是 /bin/bash。

  • 你輸入一串指令之後,發現前面寫的一長串資料是錯的,你想要刪除游標所在處到最前面的指令串內容,應該如何處理? 按下 [ctrl]+u 組合鍵即可!

  • 在 shell 環境下,有個提示字元 (prompt),他可以修改嗎?要改什麼?預設的提示字元內容是? 可以修改的,改 PS1 這個變數,這個 PS1 變數的預設內容為:『[u@h W]$』

  • 如何顯示 HOME 這個環境變數? echo $HOME

  • 如何得知目前的所有變數與環境變數的設定值? 環境變數用 env 或 export 而所有變數用 set 即可顯示

  • 我是否可以設定一個變數名稱為 3myhome ? 不行!變數不能以數字做為開頭,參考變數設定規則的內容

  • 在這樣的練習中『A=B』且『B=C』,若我下達『unset $A』,則取消的變數是 A 還是 B? 被取消的是 B 喔,因為 unset $A 相當於 unset B 所以取消的是 B ,A 會繼續存在!

  • 如何取消變數與命令別名的內容? 使用 unset 及 unalias 即可

  • 如何設定一個變數名稱為 name 內容為 It's my name ? name=It's my name 或 name="It's my name"

  • bash 環境設定檔主要分為哪兩種類型的讀取?分別讀取哪些重要檔案? (1)login shell:主要讀取 /etc/profile 及 ~/.bash_profile
    (2)non-logni shell:主要讀取 ~/.bashrc 而已。

  • CentOS 7.x 的 man page 的路徑設定檔案? /etc/man_db.conf

  • 試說明 ', ", 與 ` 這些符號在變數定義中的用途? 參考變數規則那一章節,其中, " 可以具有變數的內容屬性,' 則僅有一般字元,至於 ` 之內則是可先被執行的指令。

  • 跳脫符號 有什麼用途? 可以用來跳脫特殊字元,例如 Enter, $ 等等,使成為一般字元!

  • 連續命令中, ;, &&, || 有何不同? 分號可以讓兩個 command 連續運作,不考慮 command1 的輸出狀態, && 則前一個指令必需要沒有錯誤訊息,亦即回傳值需為 0 則 command2 才會被執行, || 則與 && 相反!

  • 如何將 last 的結果中,獨立出帳號,並且印出曾經登入過的帳號?  last | cut -d ' ' -f1 | sort | uniq

  • 請問 foo1 && foo2 | foo3 > foo4 ,這個指令串當中, foo1/foo2/foo3/foo4 是指令還是檔案? 整串指令的意義為? foo1, foo2 與 foo3 都是指令, foo4 是裝置或檔案。整串指令意義為:
    (1)當 foo1 執行結果有錯誤時,則該指令串結束;
    (2)若 foo1 執行結果沒有錯誤時,則執行 foo2 | foo3 > foo4 ;其中:
    (2-1)foo2 將 stdout 輸出的結果傳給 foo3 處理;
    (2-2)foo3 將來自 foo2 的 stdout 當成 stdin ,處理完後將資料流重新導向 foo4 這個裝置/檔案

  • 如何秀出在 /bin 底下任何以 a 為開頭的檔案檔名的詳細資料? ls -ld /bin/a*

  • 如何秀出 /bin 底下,檔名為四個字元的檔案? ls -ld /bin/????

  • 如何秀出 /bin 底下,檔名開頭不是 a-d 的檔案? ls -ld /bin/[^a-d]*

  • 我想要讓終端機介面的登入提示字元修改成我自己喜好的模樣,應該要改哪裡?(filename) /etc/issue

  • 承上題,如果我是想要讓使用者登入後,才顯示歡迎訊息,又應該要改哪裡? /etc/motd

 

10.9 參考資料與延伸閱讀

  • 註1:Webmin 的官方網站:
  • 註2:關於 shell 的相關歷史可以參考網路農夫兄所整理的優秀文章。不過由於網路農夫兄所建置的網站暫時關閉, 因此底下的連結為鳥哥到網路上找到的片段文章連結。若有任何侵權事宜,請來信告知,謝謝: 
  • 註3:使用 man bash,再以 PS1 為關鍵字去查詢,按下數次 n 往後查詢後,可以得到 PS1 的變數說明。
  • 在語系資料方面,i18n 是由一些 Linux distribution 貢獻者共同發起的大型計畫,目的在於讓眾多的 Linux distributions 能夠有良好的萬國碼 (Unicode) 語系的支援。詳細的資料可以參考:
    • i18n 的 wiki 介紹:
    • 康橋大學 Dr Markus Kuhn 的文獻:
    • Debian 社群所寫的文件:
  • GNU 計畫的 BASH 說明:
  • man bash

 

NAT

 

在 NAT 或者防火牆後端的 FTP Client 連線問題:

澳门新濠3559 30

  1. 由於目前的 NAT 主機可以記錄由內部電腦連線出去的資訊,因此,藉由 port 21 的連線可以順利的被建立起來;
  2. 當 Client 端由 port 21 下達資料傳輸的命令時,此時『個人PC』會告訴 FTP Server 說:『我開了一個 >1024 的埠口等你來連線喔』!
  3. 這個時候要特別留意的是,『個人PC』經過NAT主機連線後,在 FTP Server 看到的『個人PC』的 IP 其實是 NAT 那部主機的!所以,這個時候 FTP Server 會主動的由 port 20 向 NAT 主機的 >1024 那個 port 要求建立連線!(請翻閱NAT主機一章)

 

 

 

 

 

  1. 使用 Linux NAT 主機的 iptables 預設模組,亦即 ip_conntrack_ftp 與 ip_nat_ftp 這兩個核心模組!應用 modprobe 這個指令就可以將這兩個模組載入了!我們剛剛說過,既然 iptables (NAT 主機)可以記錄 client 端向外連線的資訊,而 client 端向 server 端要求資料傳輸時,會主動告知 Server 我(client) 要等你來連線的 port ,因此,這兩個聰明的模組可以透過檢查 NAT 主機內的資訊而加以應用,那就可以讓 Server 與 Client 端建立 ftp-data 的連線啦!不過,這兩個模組並不是萬能的,因為這兩個模組目前僅能針對預設的 ftp-data(port 20) 進行檢驗的工作,萬一您連線的是一個使用非 port 20 為 ftp-data 傳輸的主機時,那這兩個模組就沒有辦法發揮其效能了!

 

  1. 另一個方法就是使用被動式連線 (passive)!什麼是被動式連線呢?想一想,既然『主機主動』連線到我的 NAT 後面的 client 不能成功,那麼我反其道而行,如果以 client 來連到 server 呢?是否就變成如同 port 21 相似的連線方向,如此一來不就可以成功的建立連線了嗎?呵呵!沒錯,而且也不需要啟動上面兩個模組了,並且也不擔心 FTP Server 是否啟用非 port 20 的 ftp-data port 啦!這部份我們底下說明喔。

 

 


什麼是『被動, passive』的連線

 

 

  1. Client 端主動向 Server 端發送連線需求:

 

  1. Server 端接受後,回應給 Client 端:

 

  1. Client 端回應確認封包:上面這三個步驟與主動式連線一樣,同樣的完成三向交握後,建立命令通道了!底下說明被動式資料傳輸通道的建立。

 

  1. Client 端發送資料傳輸要求的命令給 Server:與主動式連線不一樣的是,在被動式連線時,Client 端在下達命令之後,並告訴 FTP Server 說『我要使用 PASV 模式(就是 passive 啦!)的方式來進行資料傳輸』;

 

  1. Server 端挑選 > 1024 的埠口等待連線:在接受 client 的 PASV 要求之後,如果沒有特別的設定時 (目前的 FTP 伺服器版本已經可以指定 passive port 來規定被動式連接的埠口號碼 ) ,Server 會隨機選取一個大於 1024 的埠口,並經由命令通道告訴 client 端說:『我已經開了一個 ftp-data 的埠口等妳連線喔!』並開始等待 client 端的連線;

 

  1. Client 端主動向 Server 端建立連線並繼續完成三向交握:經由命令通道得知 Server 的埠口之後, Client 端會隨機挑選另一個大於 1024 的埠口,並主動向 Server 端的等待連線的埠口進行連線動作,所以此連線封包是帶有 SYN 的標誌的喔!然後 Server 會回應一個帶有 ACK 確認的封包,並繼續來完成另一個三向交握的程序,此時,資料傳輸的通道就正式的建立。

 

 

 

 

 

 


FTP 的安全性問題與替代方案

 

Telnet

SSH

 

  1. 隨時更新到最新版本的 FTP 軟體,並隨時注意漏洞訊息;
  2. 善用 iptables 來規定可以使用 FTP 的網域;
  3. 善用 TCP_Wrappers 來規範可以登入的網域;
  4. 善用 FTP 軟體的設定來限制使用您 FTP 主機的使用者的不同權限啊;
  5. 使用 Super daemon 來進階管理您的 FTP 主機;
  6. 隨時注意使用者的家目錄、以及匿名使用者登入的目錄的『檔案權限』;
  7. 若不對外公開的話,或許也可以修改 FTP 的 port 。

 

 

 

 


什麼時候才要設定 FTP 啊!開放誰人連進來

 

 

開放的用戶身份與可能造成的危害 建議事項
實體用戶(Real user)
  • 在預設的條件下,開放 FTP 本來就提供了實體用戶登入之用。
  • 不過,需要瞭解的是,以實體用戶做為 FTP 登入者身份時,基本上,系統並沒有針對實體用戶來進行『限制』的,所以他可以針對整個檔案系統進行任何的工作。因此,如果您的 FTP 使用者沒能好好的保護自己的密碼,導致被入侵,那麼你的整個 Linux 系統將很有可能被毀滅啊!
  • 由於實體用戶本來就可以透過網路連接到主機來進行工作,因此實在沒有特別的需要開放 FTP 的服務啊!例如 sftp 本來就能達到傳輸檔案的功能囉!
  • 如果確定要讓實體用戶使用者利用 FTP 伺服器的話,那麼您就需要避免讓幾個系統用的帳號可以登入!這個時候可以將『不想讓他登入』的帳號寫入 /etc/ftpusrs 這個檔案當中啊!例如 root 就是個很好的例子!
訪客(Guest)
  • 通常會建立 guest 身份的案例當中,多半是由於主機提供了類似『個人 Web 首頁』的功能給一般身份使用者,那麼這些使用者總是需要管理自己的網頁空間吧?這個時候將使用者的身份壓縮成為 guest ,並且將他的可用目錄設定好,即可提供使用者一個方便的使用環境了!且不需要提供他 real user 的權限喔!
  • 僅提供需要登入的帳號即可,不需要提供系統上面所有人均可登入的環境啊!
  • 當然,我們在主機的設定當中,需要針對不同的訪客給他們不一樣的『家目錄』,而這個家目錄與使用者的權限設定需要相符合喔!例如要提供 test 這個人管理他的網頁空間,而他的網頁空間放置在 /home/test/www 底下,那我就將 test 在 FTP 提供的目錄僅有 /home/test/www 而已,比較安全啦!而且也方便使用者啊!
  • 針對這樣的身份者,需要設定較多的限制,包括:上下傳檔案數目與硬碟容量的限制、連線登入的時間限制、許可使用的指令要減少很多很多,例如 chmod 就不要允許他使用等等!
匿名者(anonymoust)
  • 提供匿名登入實在不是個好主意~因為畢竟你的系統為何要讓別人登入利用呢?
  • 不過,如果是提供整個學校單位來利用的話,那就另當別論了!
  • 無論如何,提供匿名登入都是一件相當危險的事情,因為,只要您一不小心,將重要的資料放置到匿名者可以讀取的目錄中時,那麼就很有可能會洩密!與其戰戰兢兢,不如就不要設定啊~
  • 果真要開放匿名登入時,很多限制都要進行的,這包括:(1)允許的工作指令要減低很多,幾乎就不許匿名者使用指令啦、(2)限制檔案傳輸的數量,盡量不要允許『上傳』資料的設定、(3)限制匿名者同時登入的最大連線數量,可以控制盜連喔!

套件安裝:

事實上,使用 Wu ftp 來架設你的 FTP 伺服器時,還是以 RPM 的方式來安裝比較好啦!另外,如果您的 Linux distribution 提供其他版本的 FTP 伺服器,呵呵!那麼就不要使用 wu ftp 也沒有關係啊!這是因為 wu ftp 實在是太古老了,所以很多的駭客軟體都是針對他來設計的,也因為如此啊,所以才會產生『Wu FTP 伺服器比較不安全』的情況啊!好了,底下我們以 Red Hat 7.x 的版本來進行說明吧。基本上,一個 FTP 伺服器包含 Server 與 Client 用途的套件至少要有:  

[root@test root]# rpm -qa | grep ftp
ncftp-3.0.3-6
ftp-0.17-12
wu-ftpd-2.6.1-20

 
其中:

  • wu-ftpd :這就是主要的 FTP 伺服器套件啦!
  • ftp :提供 ftp 指令,就是 client 端的工具啦!
  • ncftp :提供匿名登入的 FTP 網站的 client 端相當棒的另一套連線 FTP 軟體!

如果沒有安裝,請馬上安裝吧!如果不曉得怎麼安裝,那麼請拿出『鳥哥的 Linux 私房菜 -- 基礎學習篇』好好的將 mount CD 的指令、搜尋的指令,以及 RPM 的指令瞧一瞧先!


Server 端設定:

 

 


Wu FTP 的結構

 

 

設定檔

: Wu FTP 的設定檔主要有底下這幾個:

  • /etc/ftpaccess:這是最主要的設定檔了!所有跟 Wu FTP 有關的設定內容,都可以在這個檔案做修訂;
  • /etc/pam.d/ftp, 與 /etc/ftpusers:這兩個檔案與 PAM 模組關係較大!在預設的情況中,只要在 /etc/ftpusers 這個檔案內的使用者『都不能使用 FTP 的服務』
  • /etc/ftphosts:用來允許或拒絕(allow/deny)某部主機或者某位使用者是否能夠登入 FTP 主機的設定檔案,基本上,這檔案裡面的設定也可以直接在 /etc/ftpaccess 當中設定喔!
  • /etc/xinetd.d/wu-ftpd:這個是用來啟動 FTP 的 daemon 設定檔案~當然啦,主要是掛在 xinetd 這個 daemon 下的,如果是掛在 inetd 這個 daemon 時,就有可能是 /etc/inet.d 底下的檔案囉!

 

執行檔

:除了上面提到的這些設定檔之外,還有一些執行檔也需要瞭解一下:

  • ftpcount :主要用來計算『目前連線的人數』,可以計算出各種身份的連線人數啊!
  • ftpwho:可以顯示出『目前連線的使用者是那個 User ?使用那個 PID?動作多久了?』等等的資訊呢!
  • ftprestart:重新啟動 ftp 啊!
  • ftpshut:指定時候關閉 FTP 的一個指令喔!
  • in.ftpd:這個就是主要的 Wu FTP 的 daemon 囉!我們啟動的 wu ftp 就是他的工作呢!

 

用戶端的使用執行檔

:這個部分的指令並不是 wu ftp 所提供的,但是粉重要,所以先提出說明喔!

  • ftp:就是最陽春的 client 端軟體囉!
  • ncftp:可以使用在匿名 FTP 網站喔!相當棒的軟體!可以支援整個目錄的下載呢!

 

 

 

 


最簡單的 ftpaccess 設定檔

 

 

[root@test root]# vi /etc/ftpaccess
# 1. 設定人物群組名稱
#   設定這個 FTP 伺服器的人物身份設定,使用 class 來設定的!他的語法是:
#   class <人物群組名稱> <用戶身份1,用戶身份2,..> <允許連線的來源>
 
class   all   real,guest,anonymous  *
 
# 上面的意思是說,我設定一個類別群組為 all ,這個 all  裡面就包含了
# 三種身份的使用者,就是 FTP 預設的 real, guest 與 anonymous 這三個,
# 需要注意的是,這三個類別的使用者之間是以逗號『,』隔開的,並沒有空白字元
# 而這個 class 允許的來源來自任何地方『*』。
# 這個 class 可以多重設定,並且,萬一重複設定時,以第一個出現的 class 類別
# 為準!舉個例子,假如我的 FTP 裡面的 real 僅允許學術網路登入,至於其他
# 的 guest 與 anonymous 則雖然可以由任何地方登入,但是不可以由 chinait.com
# 這個網域以及 61.141.0.0/16 這個網域登入時,那我可以這樣設定兩個 class 喔:
# class allone real,guest,anonymous *.edu.tw
# class alltwo guest,anonymous  !*.chinait.com !61.141.0.0/16 *
# 請注意到,驚嘆號『!』有代表『否,不允許』的意思存在,而星號『*』則代表
# 任何地方的意思,則如上面所設定時,如此一來,學術單位可以連到我的 FTP ,
# 至於 guest 與 anonymous 則可以任何地方連進,當然,除了上面的兩個網域之外
# 所以說,經由這個 class 的設定,就可以輕易的將三種身份是否可以登入主機的
# 狀態搞定了! ^_^
 
# 2. 設定系統的 FTP 管理員的 e-mail 信箱位址,與主機名稱!
#   單純的就是顯示出系統當中 FTP 伺服器管理員的網址啦!預設的設定如下:
 
email root@localhost
hostname vbird.adsldns.org
 
# 一般來說,我會將這個 e-mail 後面的位址寫上可以被使用者發信的信箱,例如:
# email testing@test.adsldns.org
# 這樣的格式!這個 email 可能會出現在進出網站時的歡迎畫面當中!
# 最大的任務是:當使用者發現問題的時候,可以跟系統的管理員聯絡啊!
# 所以當然要寫下『可以收信』的正常 email 囉!
# 至於那個 hostname 則僅與歡迎畫面時的變數有關!
 
# 3. 允許同一次連線當中,錯誤登入的次數
#   為了避免被不明攻擊者的『暴力攻擊』法,所以在一次連線當中,
#   僅允許對方最多有 5 次的登入機會,如果密碼或 ID 一直發生錯誤,
#   則會將該連線『踢』掉的啦!
 
loginfails 5
 
# 當然囉!如果您想將登入的次數改小一點的話,也可以使用『loginfails 3』
 
# 4. 向使用者顯示『README, 讀我』檔案的內容訊息!
#  當使用者登入或者變換目錄時,若目的端目錄有 README 這個檔案時
#  (可以附加檔名),則向使用者顯示該檔案的內容!語法為:
#  <readme> <README*> <動作>
#  一般來說,動作有『登入』與『變換目錄』,代號為 login 與 cwd=*
 
readme  README*    login
readme  README*    cwd=*
 
# 舉個例子來說,我是 testing 這個身份的使用者,在我的家目錄內有個檔案:
# /home/testing/data/README.important
# 那麼當我使用 FTP 軟體連進我的家目錄 (/home/testing) 然後切換目錄到
# /home/testing/data 後,我的螢幕就會出現『請讀取 README.important』
# 的字樣囉!以提醒使用者之用!
 
# 5. 與 readme 的意義蠻相同的!不過這個 message 卻會將後面所接的檔案的
#  內容直接顯示在螢幕上面,而不僅是告知使用者去讀取而已~
 
message /welcome.msg            login
message .message                cwd=*
 
# 上面的意思是說,當我 login 或者切換到任何有檔名為 .message 的目錄時,
# 該檔案的內容就會顯示到螢幕上面!一般來說,那個 /welcome.msg 就是
# 『進站歡迎畫面』囉!這個等一下我們在底下會獨立出一小節來介紹他!
 
# 6. 是否提供使用者線上立即執行的指令!
#  一般的格式為:
#  <指令名稱> <是否允許/yes/no> <針對的對象是誰>
 
compress        yes             all
tar             yes             all
chmod           no              guest,anonymous
delete          no              anonymous
overwrite       no              anonymous
rename          no              anonymous
umask           no              all
 
# 以上面的例子來說,我允許任何成功登入我主機的使用者(all)使用我的
# FTP 主機來執行壓縮這個指令的動作!但是我不許匿名者(anonymous)
# 使用我的 FTP 主機進行刪除(delete)以及改名(rename)的動作!
# 你當然還可以增加自己所想要提供,或者減少提供使用者使用的指令!
# 當然啦,既然 FTP 主要是針對『檔案』,所以指令以檔案的刪除、移動、
# 更改與壓縮為主!
 
# 7. 將使用者執行的部分指令歷程記錄到 /var/log/xferlog 這個檔案
#  FTP 進行上傳、下載或者其他使用者動作時,可以將過程訊息記錄下來,
#  記錄的檔案就是 /var/log/xferlog 這個檔案囉!語法為:
#  <log> <欲登錄的項目> <記錄的使用者身份> <何種動作>
 
log transfers anonymous,guest,real inbound,outbound
 
# 上面說明的是『針對檔案傳輸(transfers)進行記錄,而針對所有人均紀錄,
# 分別記錄上傳與下載(inbound,outbound)』,請注意,身份如果有多種,要以
# 逗號『,』隔開,不要加空白喔!所以,當你的 FTP 使用者連上主機,
# 並且有任何檔案傳輸的動作時,則檔案大小以及檔案數等資訊,就會被紀錄
# 到 /var/log/xferlog 裡面去啦!而除了檔案傳輸之外,還有什麼可以紀錄的呢?
# 基本上,那個『欲登錄的項目』內容就包含了下面幾項資料:
# a. log commands <身份> :例如『log commands real,anonymous』,表示
#  real 與 anonymous 這兩種身份的人,在 FTP 上面所下達的任何指令君會
#  被紀錄在 /var/log/xferlog 裡面
# b. log security <typelist> :例如『log security guest,anonymous』
#  表示當 guest 與 anonymous 使用者『違反安全機制』時,則會將當時
#  使用者所下達的指令或者其他動作紀錄下來!
 
# 8. 關閉 FTP 的設定檔!
#  我們可以設定關閉 FTP 這個服務的時間,就利用 shutdown 後面接的檔案!
 
shutdown /etc/shutmsg
 
# 如果 /etc/shutmsg 不存在,則 FTP 服務就不會被關閉!所以不存在沒關係!
# 而如果 /etc/shutmsg 存在的話,他的內容包含有底下這些資料(注意:
# 第一行為時間參數,共有七個時間參數,用空白鍵分隔,而提示文字可以隨便
# 編寫內容喔!也可以使用變數啊!):
# <年> <月> <日> <時> <分> <抵擋新連線> <刪除已連線> 
# <提示文字>
# 年:任何大於 1970 年的年份;月:0-11!請注意啊!是由 0-11 喔!
# 0 代表 1 月、 1 代表 2 月!
# 日:當然就是 1-31 囉!  ;時:由 0-23 ;分:0-59
# 抵擋新連線與刪除已連線:格式是 HHMM 例如 90 分鐘則是 0130 ,在關機前的
# 設定時內,會拒絕新連線與將以連線之通道切除喔!例如:
# 『2003 5 30 12 0 0230 0030
#  I will shutdown my FTP server !sorry!』
# 在 2003/6/30 的 12:00 要關閉 FTP ,而 12:00 之前的兩小時30分內(09:30)
# 就不許新的嘗試登入的連線,而在 30 分鐘前(11:30)就切掉已經已經連線之
# 使用者連線!事實上,這個 shutdown 蠻有趣的!因為實際上,您的 FTP
# 服務並沒有關掉,僅只是讓他人無法使用 FTP 而已啊!那麼如何重新啟動呢?
# 很簡單啊!將 /etc/shutmsg 殺掉,或者裡面的時間更動一下即可!
 
# 9. 匿名者的密碼驗證:
#  如果您的 FTP 允許 anonymous 的話,那麼還是需要讓匿名者輸入密碼的,
#  不過就是密碼的設定比較鬆散就是了!目前的密碼格式為:
#  <passwd-check> <no|trivial|rfc822> <動作>
 
passwd-check rfc822 warn
 
# 上面說的是,以匿名者登入的使用者也需要輸入密碼,而密碼的格式為 rfc822,
# 如果使用者的密碼不合格,那麼就警告(warn)使用者,但仍允許使用者登入!
# 密碼的格式方面目前有兩種(no是不需要密碼確認,所以不討論!)
# trivial:密碼當中必須含有 @ 這個 e-mail 的字元;
# rfc822 :密碼必須符合 frc822 的規範!
# 通常我們使用的是 rfc822 即可!至於動作主要有兩種動作:
# warn   :使用者輸入錯誤的密碼時,僅顯示警告訊息,仍允許其登入;
# enforce:使用者若輸入錯誤密碼,儲顯示警告訊息,並中斷連線喔!
# 注意:
# 如果你不想讓某個 email 的型態通過認證時,可以使用 deny-email 這個
# 項目來抵擋!舉個例子來說,你不想讓 IE 的預設郵件地址通過認證,可使用
# deny-email IE?0User@
# deny-email mozilla@
# 上面這兩個項目可以同時存在,如果還有不想讓他通過的 email address 
# 可以持續上面的設定多行!這有什麼用途呢?如果您不想讓 web browsers 
# 通過密碼的確認,而僅想讓類似一般的 FTP client 來連線,那麼這個
# 限制項目就有用的很了!因為他可以將 IE 之類的 browsers 擋下來啊!
 
# 10. 設定允許與不許登入 FTP 伺服器的使用者與群組
 
deny-uid %-99 %65534-
deny-gid %-99 %65534-
allow-uid ftp
allow-gid ftp
 
# 這個是在 Red Hat 系統上面新增出來的設定啦!在一般正常的系統當中,
# UID 小於 100 通常是系統帳號,而 UID 大於 65534 可能有安全上的問題,
# 所以,我們就直接將這兩段 UID 與 GID 切掉啊!讓他們無法登入,也就可以
# 拒絕某些不當的入侵攻擊了!那就是 deny-uid 與 deny-gid 的功效!
# 所以,上面的意義是,小於99與大於65534 的UID/GID都予以抵擋連線;
# 而開放的 UID 與 GID 則僅有 ftp 這個群組與使用者喔!
# deny-uid 後面除了接數字外,也可以直接接帳號名稱,例如要擋住 testing 
# 與 testqq 這個用戶時,可以設定:
# deny-uid testing testqq 
# 後面可以接多個 UID 或帳號或者使用範圍,例如抵擋 100 到 1000 之間的 UID 
# deny-uid 100-1000
# 至於 allow-uid 則恰好相反啊!就是允許的意思~

 

 

 


使用 Super daemon 管理 FTP 的情況

 

super daemon

重新啟動 xinetd

 

[root@test root]# vi /etc/xinetd.d/wu-ftpd
service ftp
{
        disable = yes  <==就是他,將他改為 no 即可!
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/sbin/in.ftpd
        server_args             = -l -a
        log_on_success          += DURATION USERID
        log_on_failure          += USERID
        nice                    = 10
}

 

鳥哥的 Linux 私房菜 -- 基礎學習篇

認識服務

Telnet 伺服器

 

 

 

[root@test root]# /etc/rc.d/init.d/xinetd restart

[root@test root]# netstat -tl 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 *:ftp                   *:*                     LISTEN

[root@test root]# ftp localhost 
Connected to localhost (127.0.0.1).
220 localhost.localdomain FTP server (Version wu-2.6.1-20) ready.
Name (localhost:testing): testing  <==輸入登入者帳號
331 Password required for testing.
Password:  <==輸入你的密碼
230 User testing logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> exit<==離開 FTP

 

註:還是得注意一下你的防火牆機制與 /etc/hosts.deny 裡面是否將 in.ftpd 這個服務關掉了?!會造成無法連線的原因有很多都是因為沒有將防火牆的機制打開的緣故!請再回頭詳細看一下簡易防火牆設定一文

 

 


歡迎畫面的建立、 Readme 檔案與關閉 FTP 訊息內容

歡迎畫面的建立:

 

 

  • 如果您的使用者可以到達系統的根目錄,那麼他將取用 /welcome.msg 這個檔案;
  • 如果使用者只能在自己的家目錄內活動時,那麼此時他的『根目錄』會變成他的『家目錄』!因為這樣他才離不開自己目前所在的目錄啊!例如 test 這個使用者被限制在自己的家目錄內活動,那麼他的進站歡迎畫面則是取用 /home/test/welcome.msg 喔!
  • 至於如果是匿名者登入的話,由於匿名者一定都會被限制在匿名者登入的目錄,所以您也必需要將該檔案放置在他們的根目錄喔!

 

 

 

%T  本地端的主機時間(格式為 Fri Mar 21 11:28:50 2003)
%F  使用者目前所在目錄之 partition 所剩空間(不一定支援所有系統)
%C  使用者目前所在的目錄
%E  系統管理員的 email ,這個就是剛剛設定 ftpaccess 內的 email 值
%R  遠端主機的 IP 或 hostname !
%L  本地端主機的名稱或 IP
%U  使用者的登入帳號名稱
%M  FTP 主機所能允許的使用者最大連線數量
%N  FTP 主機目前已經連線的使用者數量
%B  關於硬碟容量的限額
%Q  目前的 block 數量
%I  最大的可用 inodes 
%i  針對 inodes 的限額
%H  當過度使用硬碟空間時的時間限制
%h  當使用過度檔案時的時間限制
%s  預計關閉 FTP 的時間(與 /etc/shutmsg 有關)
%r  預計關閉 FTP 前禁止再連線的時間(與 /etc/shutmsg 有關)
%d  預計關閉 FTP 前已連線的中斷時間(與 /etc/shutmsg 有關)

 

 

[root@test root]# vi /welcome.msg
Welcome to my FTP site.
Now is the time ==> %T
The host name is %L
You are %U and from %R
There are %N person in my site, now.
If you have any problem please call me
%E
 
是的!內容只要上面這樣即可!,馬上來測試一下設定的結果
 
[root@test root]# ftp localhost
Connected to localhost (127.0.0.1).
220 vbird.adsldns.org FTP server (Version wu-2.6.1-20) ready.
Name (192.168.1.100:test): test
331 Password required for test.
Password:  <==輸入密碼
230-Welcome to my FTP site.
230-Now is the time ==> Fri Mar 21 12:03:49 2003
230-The host name is vbird.adsldns.org
230-You are vbird and from 192.168.1.100
230-There are 1 person in my site, now.
230-If you have any problem please call me
230-root@localhost
230-
230 User test logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> bye

 

.message

 

關閉 FTP 喔!

註:某些情況當中,使用者可能會希望一天之中某些時候啟動 FTP 而某些時刻關閉 FTP ,例如 8-16 點啟動 FTP 而 16-隔天8點關閉 FTP ,這種情況下,您可以藉由 xinetd 這個 super daemon 的功能來達到這個目的!而不是使用這個 shutmsg 喔!切記

 

 

 

[root@test root]# vi /etc/shutmsg
2003 2 30 12 00 0100 0030
我將要關閉連線、請不要再進行連線啦!
即將關機的時間:%s
新連線失敗的時間:%r
已連線關閉的時間:%d

註:上面的內容格式為兩段,第一段就是時間的參數,分別是:
年 月 日 小時 分鐘 HHMM HHMM (最後兩個分別是新連線與已連線的斷線時間)
第二行以後則是一些文字的敘述!可以參考 message 裡面的變數!

 

特別留意:這個檔案並不會自動的消除,並且,如果設定錯誤,您可能無法連上 FTP ,因此,在過了那個關閉 FTP 的時間點之後,以上面的例子來說,就是 2003/03/30 ,您最好將該檔案刪除啊!不然可能會查不出來『到底是那個環節造成我的 FTP 無法連線』的窘境喔!

 

 


限制最大線上人數

 

 

[root@test root]# vi /etc/ftpaccess
# 規範的格式為:
# <limit> <人物群組名稱> <最大連線數> <時間> <被拒絕時顯示的文件檔案>
 
limit all       20 Any      /etc/ftpmaxnumber
limit guest     10 Any      /etc/ftpmaxnumber
limit anonymous 5  Any0800-2000 /etc/ftpmaxnumber
 
由上面的限制當中,我們知道,在 all 這個人物群組當中,最大的同時上線
人數為 20 人,並且,這個設定是任何時刻均有效(Any),如果你是第 21 個
連線進來我的 FTP 的人,那麼您的螢幕將會出現 /etc/ftpmaxnumber 這個檔案
的內容,並且『無法連線進入我的 FTP 』!請特別留意 Any 的大小寫,若
寫錯時,這個設定將不會生效!
 
[root@test root]# vi /etc/ftpmaxnumber
這裡已經太多人啦!請您等一下再進入! ^_^

[root@test root]# /etc/rc.d/init.d/xinetd restart

 

請注意,那個 Any 大小寫不要搞錯了!另外, Any 後面沒接資料,表示『任何時間』的意思,否則需要以 HHMM 的格式來書寫時間的樣式!

 

 


限制與取消使用者的家目錄規範

 

 

[root@test root]# vi /etc/ftpaccess
 
restricted-uid *
restricted-uid 200-400 test testing

[root@test root]# /etc/rc.d/init.d/xinetd restart

 

 

 

 

[root@test root]# vi /etc/ftpaccess
unrestricted-uid test testing

 

 

 


時間相關的設定項目

 

 

 

 

[root@test root]# vi /etc/ftpaccess
# 時間參數預設都是以 秒 為單位的!

timeout accept 120
# FTP 這個 daemon 會等待一個 PASV 的連線多久?由於 client 端的連線可能
# 受限於一些網路頻寬或者其他的因素,導致無法立即連上時,我們的 daemon
# 預設就會等待 120 秒來期待 client 端的連線成功!

timeout connect 120
# 與 accept 有點類似,不過 accept 是在等待 client 端的要求之回應,而 
# connect 則是在等待確認的回應!亦即三向交握內的 client 端回應 ACK 的
# 封包囉!

timeout data 2400
# 當我們下載檔案的時候,最多 FTP 可以讓我們下載或上傳一個檔案多久?
# 一般來說,由於目前大家都使用 ADSL 來傳輸,所以資料傳送不算慢,
# 不過,萬一您的檔案太大了,導致傳送速度很慢,那就比較麻煩啦!
# 通常這個設定的預設值是 1200 ,不過,建議可以大一點,例如 2400 可達 40
# 分鐘,對於傳輸速度較慢的使用者會比較好一點!

timeout idle 1800
# 就是我們上面提到的,多久沒有動作會被踢掉?預設是 900 ,你可以改大一點!

timeout maxidle 1800
# 與 idle 類似!不過由於 Client 端可以要求延長 idle 的時間,因此,
# 還會有所謂的 maxidle 喔!您大可將這兩個咚咚都設定一樣即可!

limit-time anonymous 30
limit-time guest    100
# 這個項目在設定『一次連線內,多久會被強制斷線?』以上面的例子來說,
# anonymous 每次登入之後,可以取得 30 分鐘的工作時間,如果超過 30 分鐘,
# 系統會主動的將他踢出去!(強制斷線!)這個項目對於 real user 沒有效果!

 

 

 


流量與上傳下載的限制項目

 

 

整體檔案數目與檔案容量的限額:

 

[root@test root]# vi /etc/ftpaccess
# 給予的限制情況:
# <file-limit> <in|out|total> <數目或 bytes 數> <身份群組>
 
file-limit out 32   alltwo
data-limit in  10240 alltwo
 
# 上面的設定說明是這樣的, alltwo 是一個 class 群組,這個在最前頭
# 規定出來的啦!而 in 代表上傳、out 代表下載, total 則代表總量!
# 第一個範例是說, alltwo 這個群組當中的任何使用者,在一次登入當中,
# 可以下載的檔案總數,這是以檔案數量來計算的!至於第二個範例,則是說
# 在 alltwo 這個群組中的任何使用者,均僅可『上傳 10KB 的容量』!
# 注意喔!那個數字代表的是 Bytes 的,要換算成 KBytes 則需要除以 1024 

 

 

限制流量的方法 throughput:

 

[root@test root]# vi /etc/ftpaccess
# 給予的限制情況:
# <throughput> <根目錄> <次目錄> <檔名> <bytes/s> <倍數> <位址>
 
throughput /var/ftp   *       * 10240 - *
throughput /home/test  /public_html  * 51200 - *
throughput /home/test  /realdown   * oo   - *.vbird.org
 
# 上面我設定了兩個有被限制的下載目錄,分別是 /var/ftp 這個目錄,以及
# /home/test/public_html 這個目錄,需要注意的是, 10240 代表 10Kbytes 
# 喔!設定錯誤會讓使用者下載到瘋掉啊!此外,那個 /home/test/realdown
# 則是『全速』開放給使用者下載喔!

 

這個指令對於想要優化自己主機網路頻寬的朋友真是太有用了!我們可以限制使用者(不論任何身份,均有效)在不同的目錄底下,具有不一樣的下載速 度,如此一來,可以讓主機的頻寬花在該花的地方,而不至於被其他不明使用者佔用了太多的頻寬去呢!我就蠻喜歡的說~一般來說,如果您將您所提供的檔案放置 在一個下載目錄,而這個目錄裡面又分為多個次目錄,那麼可以使用上面第二個範例的例子,將根目錄與次目錄分開來書寫,然後可以指定不同次目錄底下的傳輸速 度,例如第二與第三個範例的樣式啊!另外,特別留意的是:

  • 如果想要開放全部的頻寬 (就是全速、不限制下載的速度) 那就需要使用 oo 才行!注意喔!不是數字的零,而是英文字母小寫的 o 喔!
  • 那麼什麼是倍數呢?倍數就是下載的速度乘上的一個倍數值,舉個例子好了,如果我的下載速度是 51200 (50KBytes),而我想要開放到 1000KBytes ,那麼那個倍數的地方就寫上 20 就對了!但是,如果是 1.0 倍呢?這個時候可以寫 1 也可以寫『 - 』這個減號!
  • 最後一個是 Client 端的主機名稱或位址 (IP)。

 

上傳、下載的比例 ratio 設定:

 

[root@test root]# vi /etc/ftpaccess
# 給予的限制情況:
# ud-dl-rate <數字> <使用者身份群組>
 
ul-dl-rate 2 all
 
# 這表示 所有的人物 可以上傳 1M 下載 2M 的意思!

 

 

 

 

%xu  可上傳的 bytes 數
%xd  可下載的 bytes 數
%xR  上傳與下載的比例 (1:n)
%xc  剩下的可用 bytes 數
%xT  時間限制 (分鐘)
%xE  由開始登入到目前的時間預估(分鐘)
%xU  上傳限制 (與 file-limit 及 data-limit 的 in  有關)
%xD  下載限制 (與 file-limit 及 data-limit 的 out 有關)

 

 

[root@test root]# vi .message
您可以上傳/下載的比例為 1:%xR
您此次登入至目前剩下的時間:%xT
由登入到目前為止使用的時間:%xE
您可以上傳的最大容量(KBytes):%xU
您可以下載的最大容量(KBytes):%xD

 

 

 


創造 guest user 與 guest user 的家目錄問題

 

 

 

 

 

 

  1. 修改一下該帳號的 shell 部分欄位,舉個例子來說,假如我的帳號是 test ,那麼在 /etc/passwd 裡面應該就會變成:
[root@test root]# vi /etc/passwd
.... 略 ....
test:x:511:100:testacount:/home/test:/sbin/nologin
.... 略 ....

 

  1. 再來將上面使用的怪怪 shell 加入到 /etc/shells 當中:
[root@test root]# vi /etc/shells
/bin/sh
/bin/bash
/bin/tcsh
/bin/csh
/bin/zsh
/sbin/nologin

 

  1. 修改一下 ftpaccess 裡面相關的設定囉:
[root@test root]# vi /etc/ftpaccess
# 幾乎就是新增兩行即可: guestuser 與 guest-root 
 
guestuser test
guest-root /home/test/public_html test
 
# 第一行說的是要將 test 這個使用者變成 guest 啦!
# 第二行則是說, test 這個使用者的家目錄是在 /home/test/public_html 
  1. 重新啟動 xinetd 即可!

 

 

 

[root@test root]# vi /etc/ftpaccess
 
guestuser *
realuser  test1 test2
 
# test1 與 test2 中間用空格隔開!這樣就成功啦!

 

 

 


anonymous 的根目錄與建立可上傳目錄

 

 

[root@test root]# vi /etc/ftpaccess
 
anonymous-root /home/ftp/public

 

 

[root@test root]# vi /etc/ftpaccess
# 格式很簡單,就是:
# upload <家目錄> <次目錄> <yes|no> <檔案所屬人> <群組> <權限> <目錄>
 
anonymous-root /home/ftp/public
upload /home/ftp/public /upload  yes ftp sys 0666
upload /home/ftp/public /upfiles yes ftp sys 0666 nodirs

# 第二行顯示的是,我的 /home/ftp/public/upload 可以允許匿名者上傳資料,
# 並且上傳到主機的檔案所屬人與群組為 ftp/sys ,此外,檔案的權限為 0666 
# 至於 /home/ftp/public/upfiles 這個目錄當中則僅能上傳檔案,不能建立目錄

 

 

 


針對人物(real, guest, anonymous)的限制設定項目

 

權限有關

程序執行順序

基礎學習篇

 

[root@test root]# vi /etc/ftpaccess
# nice   <數值> <使用者群組或身份>
# defumask <數值> <使用者群組或身份>
 
nice 10 anonymous
nice -5 real
defumask 022 real
defumask 002 anonymous
 
# 請務必搞懂什麼是 nice 與 umask 喔!上面的 defumask 就是 default umask 
# 的意思!不難理解吧?!

 

 

 


拒絕某些使用者與開放某些使用者的登入

拒絕不良的 IP 或網域或 domain :

iptables

為何會被取消使用 FTP 的權力

 

[root@test root]# vi /etc/ftpaccess
# 準備抵擋囉!就以 <deny> <位址或主機名稱> <回覆給使用者訊息的文件>
 
deny 192.168.0.100  /etc/ftpdeny.msg
deny *.adsldns.org  /etc/ftpdeny.msg
 
# 上面的設定當中,當 192.168.0.100 這個 IP 來的 FTP 要求封包時,
# 不僅不提供其 FTP 的連線,並且會顯示 /etc/ftpdeny.msg 這個檔案的內容!
# 同樣的,只要來自 .adsldns.org 的網域的電腦也都會被抵擋啊!

[root@test root]# vi /etc/ftpdeny.msg
您無法直接登入這部主機,請與您的 FTP 管理員聯絡!
管理員 E-Mail 位址為: %E

 

 

拒絕某些危險的帳號:

 

[root@test root]# vi /etc/ftpaccess
# 就直接使用最初的設定 deny-uid <帳號、UID或範圍>
 
deny-uid %-499 %65000-
deny-gid %-499 %65000-
allow-uid ftp
allow-gid ftp

 

 

使用額外檔案來抵擋:/etc/ftphosts

 

[root@test root]# vi /etc/ftphosts
# 格式為 <deny> <使用者帳號> <不許連線的IP或主機名稱>
# 格式為<allow> <使用者帳號> <不許連線的IP或主機名稱>
 
deny test   192.168.0.0/24
allow testing 192.168.1.0:255.255.255.0
# 注意上面這兩種書寫方式的不同的!

deny test2    192.168.5.10 allow test2 *

 

deny  test *
allow test *

最後出現的那一條規則為預設的規則

 

使用 PAM 模組的機制來抵擋:

 

[root@test root]# vi /etc/pam.d/ftp
#%PAM-1.0
auth       required     /lib/security/pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed <==此行與上行為同一行
auth       required     /lib/security/pam_stack.so service=system-auth
auth       required     /lib/security/pam_shells.so
account    required     /lib/security/pam_stack.so service=system-auth
session    required     /lib/security/pam_stack.so service=system-auth

 

 

讓 root 可以使用 FTP 功能:

  1. 首先,請先將 /etc/ftpusers 裡面的 root 拿掉;
  2. 確認 /etc/ftphosts 沒有擋掉欲登入的主機的 IP 或者是 hostname;
  3. 確認 /etc/ftpaccess 裡頭關於 deny-uid 與 deny-gid 沒有 0 這個數字存在!
  4. 重新啟動 /etc/rc.d/init.d/xinetd 這個 daemon !

這樣大概就可以讓 root 登入啦!不過『強烈建議不要這麼做!』

 

 


目錄與連結檔的問題

 

 

[root@test root]# vi /etc/ftpaccess
# alias <你想要給這個目錄起的名字> <實際 Linux 系統的目錄>
 
alias  anonymousdir  /var/ftp

 

這個 alias 『僅針對 cd 這個指令有用』

很抱歉

 

 

 

[root@test root]# vi /etc/ftpaccess
# path-filter <群組> <訊息檔案> <允許字元> <不許字元1> <不許字元2> ...
 
paht-filter anonymous /etc/pathmsg ^[-A-Za-Z0-9._]*$ ^. ^-
 
[root@test root]# vi /etc/pathmsg
請注意,您的檔案名稱不符合本站的限制,請檢查:
1. 檔名起始字元需為英文或數字或底線;
2. 檔名起始字元不可為 . 或者減號 - 

 

基礎學習篇

正規表示法

 


建立 passive port 提供 client 端登入

 

 

[root@test root]# vi /etc/ftpaccess
# passive ports <CIDR 位址> <最小 port> <最大 port>
# pasv-allow   <人員身份> <位址>
 
passive ports 0.0.0.0/0 65501 65505
pasv-allow all *
 
# 這代表來自任何地方的 IP 在要求 passive 連線模式時,將以 65501 ~ 65505 
# 之間的 port 來做為他們 PASV 連線的要求啦!如此一來,則 passive ports
# 將僅會隨機選取 65501 ~ 65505 之間的 5 個 port 來做為 PASV 之用,
# 其他的 port 將不會使用到 FTP 的 passive 模式!如此一來還可以建置
# 防火牆上面的 port mapping 呢!很不錯吧! ^_^

 

 

 


修改 FTP 預設的 port 21 的連線

 

 

 

  • Xinetd 這個 Super daemon 的設定檔:/etc/xinetd.d/wu-ftpd
  • Port 對應 daemon 名稱的檔案:/etc/services

 

 

 

[root@test root]# vi /etc/xinetd.d/wu-ftpd
service ftp
{
        disable = no
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/sbin/in.ftpd
        server_args             = -l -a
        log_on_success          += DURATION USERID
        log_on_failure          += USERID
        nice                    = 10
}

 

 

1. 修改 wu-ftpd 這個裡面關於 daemon 的名稱:
 
[root@test root]# vi /etc/xinetd.d/wu-ftpd
service vbftp <==修改這裡就對啦!
{
        disable = no
        socket_type             = stream
        wait                    = no
        user                    = root
        server                  = /usr/sbin/in.ftpd
        server_args             = -l -a
        log_on_success          += DURATION USERID
        log_on_failure          += USERID
        nice                    = 10
}
 
2. 修改 /etc/services 的 daemon 相關設定內容
[root@test root]# vi /etc/services
 
vbftp    3366/tcp
 
# 上面這一行可以加在這個 /etc/services 裡面的最後一行!自己設定的啦!

3. 重新啟動 xinetd
 
[root@test root]# /etc/rc.d/init.d/xinetd restart

 

 

 


一個多樣化的實例

 

 

  1. 將群組設定成為 real, guest, anonymous 這三個群組分別控制!(用 class 來區分喔!);
  2. 用戶身份有 real, guest, anonymous,其中, real 僅允許來自 140.116.0.0/16 這個 B class 的網域,其他兩者雖可來自於所有網域,但不允許來自 61.141.0.0/16 這個 B Class 的網域;
  3. 允許使用 passive ports ,port number 設定為 65501 - 65510 這 10 個 ports ;
  4. 系統裡面小於 499 以及大於 65000 的 UID 與 GID 都被拒絕登入;
  5. 任何時刻,最大線上人數限制為 30 人,其中, guest 最多 10 人,而 anonymous 最多為 5 人;
  6. 實體用戶 mysiteuser 被限制他僅能在他的家目錄當中工作,無法離開其家目錄,至於其他實體用戶則不在此限;
  7. 我有兩個 WWW 的個人用戶 wwwuser1 與 wwwuser2 ,我將這兩個用戶訂為 guest 身份,為使他的網頁資料傳輸方便,將他的 FTP 主機的家目錄設定為他的 WWW 家目錄,亦即為 /home/wwwuser1/public_html ,並且設定傳輸速度最大為 100 Kbytes/second。注意,我的 ftp 使用者預設的群組為自行建立的 myftpusers;
  8. 我有一個 FTP 交換連結用戶 ftpuser,我與他交換連結,連上下傳都需要注意!上下傳比例為 1.0 ,並且限制他傳輸的速度為 64 Kbytes/second ;
  9. 其他的匿名登入者的家目錄設定為 /var/ftp 這個目錄當中,並且限制 anonymous 一次連線最久 10 分鐘,而且最多僅能下載 20 個文件,以及 10MB 的資料量,此外,傳輸速度最快僅能到達 32 Kbytes/second。至於上傳的設定方面,僅允許上傳到 /var/ftp/upload 這個檔案,此外,預設檔案擁有者為 ftp 群組是 sys,上傳速度最快為 16 Kbytes/second;

 

 

 

  1. 先設定使用者的帳號:

 

[root@test root]# groupadd myftpusers
[root@test root]# useradd -m -g myftpusers -s /sbin/nologin wwwuser1
[root@test root]# useradd -m -g myftpusers -s /sbin/nologin wwwuser2
[root@test root]# useradd -m -g myftpusers -s /sbin/nologin ftpuser
[root@test root]# passwd wwwuser1  <==不要忘記給三個人密碼!
  1. 開始設定我們的 /etc/ftpaccess 內容:

 

[root@test root]# vi /etc/ftpaccess
# 底下的資料為 VBird 的 FTP 主機設定範例
#
########################################################################
# 1.  針對 Server 的設定項目:
########################################################################
# 1.1 針對群組的設定項目
class           all             real,guest,anonymous    140.116.0.0/16
class           allreal         real                    140.116.0.0/16
class           allguest        guest                   !61.141.0.0/16  *
class           allanonymous    anonymous               !61.141.0.0/16  *

# 1.2 其他主機相關的設定項目
email           vbird@tsai.adsldns.org
hostname        tsai.adsldns.org
shutdown        /etc/shutmsg
loginfails      3
log             transfers       anonymous,guest,real    inbound,outbound
passwd-check    rfc822          warn

# 1.3 訊息管理
readme          README*         login
readme          README*         cwd=*
message         /welcome.msg    login
message         .message        cwd=*

# 1.4 指令管理
compress        yes             all
tar             yes             all
chmod           no              guest,anonymous
delete          no              anonymous
overwrite       no              anonymous
rename          no              anonymous

# 1.5 人物登入管理
deny-uid        %-499           %65000-
deny-gid        %-499           %65000-
allow-gid       myftpusers

# 1.6 時間相關的設定值
timeout data    2400
timeout idle    1800
timeout maxidle 1800

# 1.7 主機最大連線人數設定
limit   all             30      Any     /etc/ftpmaxnumber

# 1.8 被動的 port 設定
passive ports   0.0.0.0/0       65501   65510
 

########################################################################
# 2.  針對實體用戶的設定
########################################################################
restricted-uid  mysiteuser
 

########################################################################
# 3.  針對 guest 用戶的設定
########################################################################
limit           allguest        10      Any     /etc/ftpmaxnumber
guestuser       wwwuser1        wwwuser2        ftpuser

# 3.1 www users
guest-root      /home/wwwuser1/public_html      wwwuser1
guest-root      /home/wwwuser2/public_html      wwwuser2
throughput      /home/wwwuser1/public_html      *   *   102400  -       *
throughput      /home/wwwuser2/public_html      *   *   102400  -       *

# 3.2 FTP users
guest-root      /home/ftpuser                   ftpuser
ul-dl-rate      1       allguest
throughput      /home/ftpuser   *       *       64000   -       *
 

########################################################################
# 4.  針對 anonymous 用戶的設定
########################################################################
limit           allanonymous    5       Any     /etc/ftpmaxnumber
anonymous-root  /var/ftp
limit-time      anonymous       10
file-limit      out             20              allanonymous
data-limit      out             10000000        allanonymous
throughput      /var/ftp        *       *       32000   -       *
throughput      /var/ftp        /upload *       16000   -       *
upload          /var/ftp/upload yes ftp sys 0666 

  1. 建立可上傳目錄與使用者家目錄:

 

[root@test root]# mkdir /var/ftp/upload
[root@test root]# chown ftp:sys /var/ftp/upload
[root@test root]# mkdir /home/wwwuser1/public_html
[root@test root]# mkdir /home/wwwuser2/public_html
[root@tset root]# chown wwwuser1:myftpusers /home/wwwuser1/public_html
[root@tset root]# chown wwwuser2:myftpusers /home/wwwuser2/public_html
  1. 修訂一下 /etc/shells:

 

[root@test root]# vi /etc/shells
/bin/bash
....(略)...
/sbin/nologin
  1. 修改一下歡迎畫面檔案:

 

/welcome.msg
/home/wwwuser1/public_html/.message
/home/wwwuser2/public_html/.message
/var/ftp/welcome.msg如果想要一勞永逸,那麼將 /welcome.msg 這個檔案複製到 /etc/skel/welcome.msg 以及 /etc/skel/public_html/.message 則是一個不錯的主意!  

  1. 重新啟動 xinetd 囉!

 

 


Client 端的使用 FTP 軟體:

事實上,我們在網路常用指令那個章節當中已經介紹過了 ftp 與 ncftp 這兩個很好用的 client 端軟體了,在這裡我們再次的強調一下這兩個軟體,其中,比較重要的是強調傳輸的模式。在 Server 與 Client 傳輸的過程中,資料的流動主要分為 binary 與 ascii 兩種模式,需要注意的是:

  • Binary 的傳送方式當中,FTP Server 並不會去改變檔案的內容,所以資料得以完整的呈現;
  • 但在 ASCII 傳輸模式當中,主要將資料視為一般的純文字檔,例如:原始碼或者是設定檔等等,在這種傳輸模式當中,Server 會將檔案以一行一行來傳送,所以如果您以 ASCII 傳送經過編譯過的 binary program 時,將可能導致無法執行的問題(因為被轉成文字檔啦!)

底下我們就來介紹兩個軟體吧!  


  • style="color: #000099;">ftp

    style="color: #000099;">遠端傳送資料當中,速度最快的協定之一
    語法:

[root @test /root]# ftp [-p] host [port]
參數說明:
-p :啟動 PASSIVE 模式!
範例:
[root @test /root]# ftp localhost     <==預設是以 port 21 來進行連線
[root @test /root]# ftp localhost 1354   
如果你設定的 ftp 的 port 非正規的 21 ,則可以這樣!

[root @test /root]# ftp localhost  <==連接到遠端主機
Connected to localhost (127.0.0.1).
220 localhost FTP server (Version wu-2.6.1-20) ready.
Name (127.0.0.1:test): test
331 Password required for test.
Password: <==輸入密碼
230 User test logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> dir          <==顯示遠方主機的內容
ftp> cd           <==變換遠端主機的目錄
ftp> close or bye or exit <==離開遠端主機
ftp> get file       <==取得遠端主機的檔案
ftp> mget file       <==取得所有的檔案,例如 mget .bash* !
ftp> put file       <==將本地端檔案 file 丟到遠端主機上
ftp> mput file       <==與 mget 差不多意思啦!
ftp> delete file      <==殺掉遠端主機的 file 檔案
ftp> help         <==顯示求救指令!
ftp> mkdir dir       <==在遠端主機上面建立目錄
ftp> lcd          <==變換本地端路徑!
ftp> ascii or binary    <==重要的很!上面提過的!

 


  • style="color: #000099;">ncftp

    style="color: #000099;">登入匿名主機最好用的文字介面 FTP 軟體!
    語法:

[root @test /root]# ncftp [host]
[root @test /root]# ncftp [ftp://domain.name/path]
參數說明:
可以直接連接到 host 主機,也可以直接連接到主機的某個路徑之下,相當的方便
範例:
[root @test /root]# ncftp ftp.nsysu.edu.tw   <==連接到中山大學 FTP 站
[root @test /root]# ncftp ftp://ftp.nsysu.edu.tw/Linux
直接連接到 Linux 底下的 Linux 目錄下!

遠端主機的一些服務指令:
ncftp /pub/Linux > cd Redhat      <==變換目錄
ncftp /pub/Linux > dir         <==顯示目前目錄下的檔案與目錄資訊
ncftp /pub/Linux > get file1       <==將 file1 的資料存到本地端
ncftp /pub/Linux > get -z file1 file2  <==將 file1 存到本地改檔名為 fill2
ncftp /pub/Linux > get -A file1 file2  
將 file1 以累積的方式(append)增加到 file2 這個檔案
ncftp /pub/Linux > pub file       <==將檔案由本地端上傳至遠端!
ncftp /pub/Linux > rename file1 file2  <==將遠端的主機之 file1 更名為 file2
ncftp /pub/Linux > rm file       <==刪除檔案
ncftp /pub/Linux > rmdir directory   <==刪除目錄
ncftp /pub/Linux > mget directory  <==可以下載『整個目錄』的資料!很棒吧!

本地端主機的一些指令功能:
ncftp /pub/Linux > lcd      <==變更本地端目前所在的目錄
ncftp /pub/Linux > lls      <==顯示目前本地端所在目錄的檔案與目錄資訊
ncftp /pub/Linux > lmkdir    <==在本地端建立目錄
ncftp /pub/Linux > lpwd     <==顯示目前本地端主機的所在目錄
ncftp /pub/Linux > lrm     <==刪除本地端的檔案
ncftp /pub/Linux > lrmdir    <==刪除本地端的『目錄』


Server 端的安全設定項目:

 

  1. 除非真的必要,否則盡量將 FTP 的 port 21 關掉;
  2. 如果真的要架設 Wu FTP ,請『一定要』將 Wu FTP 更新到最新的版本;
  3. 更新完畢之後,在架設之前,一定要考慮清楚,是否要開放 anonymous 的連線?除非必要,否則僅開放 Real 以及 guest 使用者登入即可;
  4. 設定時,最好在 /etc/ftpaccess 就限制連線者的位址,以杜絕可能的入侵者的嘗試;
  5. 盡量將使用者限制在他們自己的家目錄內;
  6. 將不想讓他連線的帳號以 PAM 模組來抵擋,亦即將使用者帳號寫入 /etc/ftpusers 裡面即可;
  7. 可以的話,以 iptables 以及 TCP_Wrappers 架設兩層防火牆,限制住開放的網域即可。

 

 

 

 


iptalbes

 

 

/sbin/iptables -A INPUT -p TCP -i eth0 -s 140.116.0.0/16 --dport 20:21  
  -j ACCEPT
/sbin/iptables -A INPUT -p TCP -i eth0 -s 140.116.0.0/16 --dport 65501:65505
  -j ACCEPT 

 

簡易防火牆

 

 


TCP_Wrappers

 

 

[root@test /root]# vi /etc/hosts.allow
in.ftpd : 140.116.0.0/255.255.0.0

[root@test /root]# vi /etc/hosts.deny
in.ftpd : ALL : spawn (/bin/echo Security notice from host `/bin/hostname`;
/bin/echo; /usr/sbin/safe_finger @%h ) |
/bin/mail -s "%d -%h security" root@localhost &
: twist ( /bin/echo -e "nnWARNING connectin not allowed. Your attempt has been logged. nnn警告您尚未允許登入,您的連線將會被紀錄,並且作為以後的參考nn ". )

 

 

 


pam 模組與 /etc/ftpusers 的關係

 

要被抵擋的使用者帳號寫入到 /etc/ftpusers

 

 


FTP 本身提供的抵擋 username 或 host 的控制項目

 


重點回顧

  • FTP 是 File Transfer Protocol 的簡寫,主要的功能是進行 Server 與 Client 端的檔案管理、傳輸等事項;
  • Wu FTP 是很常見的一個 FTP 軟體,不過由於安全性,建議務必升級到最新版本,此外,他的主要設定檔是 /etc/ftpaccess 這一個;
  • 除了 Wu FTP 這個 FTP 軟體之外,其實可以使用 SSH 提供的 sftp 功能來取代 FTP;
  • FTP 這個 daemon 比較常以 super daemon 來管理,亦即 xinetd 或者是 inet 這兩個 super daemon ;
  • FTP 這個 daemon 所開啟的正規的 port 為 20 與 21 ,其中, 21 為指令通道, 20 為資料傳輸通道;
  • FTP 的傳輸路線主要分為主動與被動(Passive, PASV),如果是主動的話,則 ftp-data 以 20 傳送,否則則以 /etc/ftpaccess 規定的 passive ports 或者隨機選取大於 1024 的 port 來進行被動式連線模式;
  • 一般來說, FTP 上面共有三個群組,分別是實體用戶、訪客與匿名登入者(real, guest, anonymous);
  • 可以藉由修改 /etc/passwd 裡面的 Shell 欄位,來讓使用者僅能使用 FTP 而無法登入主機;
  • 可以使用 guestuser 及 guest-root 來限制實體用戶,使成為訪客用戶;
  • 需要以 upload 來設定可以讓 anonymous 上傳的目錄,並設定好其權限喔!
  • FTP 的指令、與使用者活動所造成的登錄檔是放置在 /var/log/xferlog 裡面;
  • 在 Client 端使用 ftp 這個程式時,可以加上『 ftp -p hostname』來讓連線變成 passive 模式。

參考資源

  • man ftpaccess
  • Study Area :http://www.study-area.org
  • Wu FTP 官方網站:http://www.wu-ftpd.org

本章習題練習 ( 要看答案請將滑鼠移動到『答:』底下的空白處,按下左鍵圈選空白處即可察看 )

  • FTP 在建立連線以及資料傳輸時,會建立哪些連線?
  • FTP 主動式與被動式連線有何不同?
  • 有哪些動作可以讓您的 FTP 主機更為安全 ( secure ) ?
  • 我們知道 ftp 會啟用兩個 ports ,請問這兩個 port 在哪裡規範的?而且,一般正規的 port 是幾號?
  • Wu FTP 的主要設定檔在哪裡?
  • 在 Wu FTP 的設定檔當中,那個 log transfer 是幹嘛用的?
  • 在 Wu FTP 的設定檔當中,那個 passive ports 是幹嘛用的?
  • 那一個檔案可以用來抵擋類似 root 這種系統帳號的登入 FTP?
  • 在 FTP 的 server 與 client 端進行資料傳輸時,有哪兩種模式?為何這兩種模式影響資料的傳輸很重要?

源自:
前往參考用解答

编辑:操作系统 本文来源:一定要先學會的指令,讀者們常常詢問使用USB直

关键词:

  • 上一篇:没有了
  • 下一篇:没有了