鳥哥的第一本書籍的主要內容,內容稍微與書籍不太一樣了!
鳥哥的第一本書大約是在 2002 年的年底左右出版的,內容幾乎都是 Linux 基礎學習,一點也沒有談到伺服器的部份!這也是後來的雛型! 不過內容錯誤的地方很多,導致在 2003 年的年底推出了『基礎學習篇增訂版』的內容,大致上就是處理掉一些比較有嚴重錯誤的部份。 不過,因為 Linux 的版本變化非常快速,因此,寫完了這些文件之後,鳥哥還是持續在網站上更新文件內容,導致原本書籍內容的資料與網站資料差異太大! 這個問題直到鳥哥在 2008 年左右才發現!糟糕了!舊版的文件資料已經遺失~覺得相當扼腕~
因此,在底下的文件內容與當初的書籍內容雖然大同小異,不過章節的編排卻是有所不同!再花時間去一個一個處理,似乎也不太符合成本效益! 鳥哥僅是想要將自己以前的文件記錄下來而已,同時將過時的 big5 編碼改回 utf8 編碼,再加上可以支援 RWD 的樣式而已啦! 內容已經不多做編排~因此,如果內容文件你看不懂,那也是應該的! ^_^
建議您前往本站查詢最新版本的 Linux distribution 文章來閱讀,比較不會浪費時間。最新文章請前往鳥站首頁查閱囉!
這應該是個蠻有趣的話題:『什麼是 Shell ?』相信只要摸過電腦,對於作業系統(不論是 Linux 、 Unix 或者是 Windows )有點概念的朋友們大多聽過這個名詞,因為只要有『作業系統』那麼就離不開 Shell 這個東西。不過,在討論 Shell 之前,我們先來瞭解一下電腦的運作狀況吧!舉個例子來說:當你要電腦傳輸出來『音樂』的時候,你的電腦需要什麼東西呢?這就是基本的一個輸出聲音的需要的步驟!那麼也就是說,你必須要『輸入』一個指令之後,『硬體』才會透過你下達的指令來工作!嘿嘿!那麼硬體如何知道你下達的指令呢?那就是 kernel (核心)的控制工作了!瞭解了嗎?沒錯!也就是說,我們必須要透過『 Shell 』將我們輸入的指令與 Kernel 溝通,好讓 Kernel 可以控制硬體來正確無誤的工作!基本上,我們可以透過底下這兩張圖來說明一下:
- 當然就是需要你的硬體有『音效卡晶片』這個硬體配備,否則怎麼會有聲音;
- 作業系統的核心可以支援這個晶片組,當然還需要提供晶片的驅動程式囉;
- 需要使用者(就是你)輸入發生聲音的指令囉!
基本上,替我們工作的是『硬體』,而控制硬體的是『核心』,再來,我們使用者乃是利用『Shell』控制一些 kernel 提供的 『工具 Utility』來操控硬體替我們正確的工作。再進一步來說,由於 kernel 聽不懂人類的語言,而人類也沒有辦法直接記得 kernel 的語言,所以兩者的溝通就得藉由 shell 來支援了!(其實早期的 DOS 的文字介面也是使用 shell 來溝通呀!那個 shell 的名稱就叫做 command.com ,還記得嗎? ^_^)
以字面上的意思來說, kernel 是『核心』的意思,而 Shell 是『殼』的意思,呵呵!也就是說, shell 是最外頭的咚咚!而 kernel 乃是最內層的的咚咚啦!核心是作業系統的最底層的東西!這個核心裡頭包括了各種的支援硬體的工具!當然囉,如果你的硬體太新,而你的 kernel 並沒有支援的話,那麼很抱歉,你的 Shell 能力再怎麼強,也沒有辦法使硬體工作的!這樣可以瞭解了嗎?呵呵!沒錯!使電腦主機工作的正是核心的任務,但是操作核心來替使用者工作的,卻是 shell 喔!因此,有時候你的 shell 搞了老半天,硬體卻不能工作的時候,請注意,您的『核心』是否正確呢?阿!扯遠了!這是 kernel 章節才要說的東西??
- 我幹嘛要學習 Shell 呢?
常常聽到這個問題:『我幹嘛要學習 shell 呢?不是已經有很多的工具可以提供我設定我的主機了?我為何要花這麼多時間去學指令呢?不是以 X-Window 按一按幾個按鈕就可以搞定了嗎?為什麼要這麼麻煩?』唉?還是得一再地強調,X-Window 還有 Web 介面的設定工具例如 webmin 是真的好用的傢伙,他真的可以幫助我們很簡易的設定好我們的主機,甚至是一些很進階的設定都可以幫我們搞定。但是 VBird 在序章裡面也已經提到過相當多次了, X-Window 的介面雖然親善,功能雖然強大,而 web 介面的工具也可以提供我們很友善的服務,但是畢竟他是整合的一個套件而已,並非是一個完整的套件,所以某些時候當你升級或者是使用其他套件管理模組( 例如 tarball 而非 rpm 檔案等等 )時,就會造成設定的困擾了,此外,遠端連線時,文字介面的傳輸速度一定比較快,而且,較不容易出現斷線或者是資訊外流的問題,因此, shell 真的是得學習的一項工具。而且,他可以讓您更深入 Linux ,更瞭解他,而不是只會按一按滑鼠而已!所謂『天助自助者!』多摸一點文字模式的東西,會讓你與 Linux 更親近呢!
有些朋友也很可愛,常會說:『我學這麼多幹什麼?又不常用,也用不到!』嘿嘿!有沒有聽過『書到用時方恨少?』當你的主機一切安然無恙的時候,您當然會覺得好像學這麼多的東西一點幫助也沒有呀!萬一,某一天真的不幸給他中標了,您該如何是好?是直接重新安裝?還是先追蹤入侵來源後進行漏洞的修補?或者是乾脆就關站好了?這當然涉及很多的考量,但就以 VBird 的觀點來看,多學一點總是好的,尤其我們可以有備而無患嘛!甚至學的不精也沒有關係,瞭解概念也就 OK 啦!畢竟沒有人要您一定要被這麼多的內容啦!瞭解概念就很了不起了!
此外,如果您真的有心想要將您的主機管理的好,那麼良好的 shell 程式編寫是一定需要的啦!就 VBird 來說,我管理的主機雖然還不算多,只有區區不到十部,但是如果每部主機都要花上幾十分鐘來查閱他的 log file 以及相關的資訊,那麼我可能會瘋掉!基本上,也太沒有效率了!這個時候,如果能夠藉由 shell 提供的命令重導向( 或稱資料流重導向 ),以及管線命令,呵呵!那麼我分析 log file 只要花費不到十分鐘就可以看完所有的主機之重要資訊了!相當的好用呢!
由於學習 shell 的好處真的是多多啦!所以,如果您是個系統管理員,或者有心想要管理系統的話,那麼 shell 這個東西與 shell scripts 這個東西,真的真的有必要看一看!
知道什麼是 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 的簡單歷史吧:第一個流行的 shell 是由 Steven Bourne 發展出來的,為了紀念他所以就稱為 Bourne shell ,或直接簡稱為 sh !而後來另一個廣為流傳的 shell 是由柏克萊大學的 Bill Joy 設計依附於 BSD 版的 Unix 系統中的 shell ,這個 shell 的語法有點類似 C 語言,所以才得名為 C shell ,簡稱為 csh !由於在學術界 Sun 主機勢力相當的龐大,而 Sun 主要是 BSD 的分支之一,所以 C shell 也是另一個很重要而且流傳很廣的 shell 之一(因為太多的程式設計師使用的就是 C 語言啦!)!
好了,那麼 BASH 是怎麼一回事呢?這個 shell 是 GNU 計畫中重要的工具軟體之一,目前也是 GNU 作業系統中標準的 shell ,他主要相容於 sh ,並且依據一些使用者需求,而加強的 shell 版本,可以說目前幾乎所有的 Linux distribution 都是使用 bash 作為管理核心的主要 shell !因此,不論您使用的是那個 distribution ,你都難逃需要學習 bash 的宿命啦!那麼這個 shell 有什麼好處,幹嘛 Linux 要使用他作為預設的 shell 呢? BASH 主要的優點有底下幾個:
- 命令編修能力(類似 DOS 的 doskey 功能):
使用 bash 裡頭,個人認為相當棒的一個功能就是『他能記憶使用過的指令!』這功能真的相當的棒!因為我只要在指令列按『上下鍵』就可以找到前一個輸入的指令!而在 Mandrake 9.0 預設的指令記憶功能可以到達 1000 個!也就是說,你曾經下達過的指令都被記錄下來了,記錄的檔案在你的家目錄內的 .bash_history !不過,需要留意的是, ~/.bash_history 記錄的是前一次登入以前所執行過的指令,而至於這一次登入所執行的指令都被暫存在暫記憶體中,當您成功的登出系統後,該指令記憶才會記錄到 .bash_history 當中!這有什麼功能呢?最大的好處就是可以『查詢曾經做過的舉動!』,如此可以知道你的執行步驟,那麼就可以追蹤您曾下達的指令,以作為除錯的工具!但如此一來也有個煩惱,就是如果被駭客入侵了,那麼他只要翻你曾經執行過的指令,剛好你的指令又跟系統有關(例如直接輸入 MySQL 的密碼在指令列上面)那麼很容易就被破解你的 Linux 主機!所以,最好是將記錄的指令數目減小一點較好!
- 檔案比對補全功能(比對資料正確性):
這個功能也相當的棒!主要分為指令補全與檔案名稱補全:
- 指令補全:如果在執行命令的時候不想按下太多的按鍵,例如指令 pcprofiledump 夠長吧!好了,那麼如果你輸入了 pcprofile 之後,再按下 [Tab] 按鍵的話,那麼 bash 馬上會自動的將後面的 dump 接上來!那如果有重複的指令呢?那麼按下兩次 [Tab] 將會把所有重複的指令給他列出來囉!那麼就有個特殊的案例啦,就是『直接在提示字元後面連按兩次 <tab> 鍵,則系統會將所有可以使用的指令都列出來!』那麼如果我想要知道目前系統裡面,所以 b 開頭的指令呢?呵呵!就是按下 b 之後,連按兩次 <tab> 就可以知道啦!
- 檔案名稱補全:此外,如果你用 vi 來讀取某個檔案時,例如 /etc/man.config 這個檔案好了,那麼您可以輸入 vi /etc/man. 之後,直接按下 <tab> 按鍵,那麼該檔案名稱就會被自動的補齊囉!呵呵!很方便,而且對於檔案名稱或者指令名稱的正確性上面,幫助還蠻大的吧!是的!真的是很方便的功能,所以,有事沒事,在 bash shell 底下,多按幾次 <tab> 是一個不錯的習慣啦!
- 命令別名(alias)設定功能:
假如我需要知道這個目錄底下的所有檔案(包含隱藏檔)及所有的檔案屬性,那麼我就必須要下達 ls -al 這樣的指令列,唉!真麻煩,有沒有更快的取代方式?呵呵!就使用命令別名呀!例如我最喜歡直接以 lm 這個自訂的命令來取代上面的命令,也就是說, lm 會等於 ls -al 這樣的一個功能,嘿!那麼要如何作呢?就使用 alias 即可!你可以在指令列輸入 alias 就可以知道目前的命令別名有哪些了!也可以直接下達命令來設定別名呦:alias lm='ls -al'
- 工作控制(jobs)、前景背景控制:
這部分我們在之後的資源管理章節中會再提及!使用前、背景的控制可以讓工作進行的更為順利!至於工作控制(jobs)的用途則更廣,可以讓我們隨時將工作丟到背景中執行!而不怕不小心使用了 [Ctrl] + C 來停掉該程序!真是好樣的!此外,也可以在單一登入的環境中,達到多工的目的呢!
- Shell scripts 的強大功能:
在 DOS 年代還記得將一堆指令寫在一起的所謂的『批次檔』吧?在 Linux 底下的 shell scripts 則發揮的更為強大的功能,可以將您日常生活當中常需要下達的連續指令寫成一個檔案,該檔案並且可以透過對談互動式的方式來進行主機的偵測工作!也可以藉由 shell 提供的環境變數及相關指令來進行設計,哇!整個設計下來幾乎就是一個小型的程式語言了!該 scripts 的功能真的是超乎我的想像之外!以前在 DOS 底下需要程式語言才能寫的東西,在 Linux 底下使用簡單的 shell scripts 就可以幫你達成了!真的利害!!這部分我們在後續章節再來談!
在瞭解了 BASH 的優點之後,再來我們要來討論的是:那如何在 Shell 提供的環境中下達指令呢?其實很簡單的,下達指令的方式為:很簡單吧!OK!那麼再來一個問題:『Shell 是什麼時候開始接管 Linux 主機的!?』我們在後面會再提到『開機流程』的介紹,這裡先跳過去,假設你的機器已經開機成功了,那麼主機便進入等待使用者 login 的狀態。當使用者輸入了帳號與密碼,並且順利的 pass 之後,經過了 shell 的環境變數檔案讀取功能,最後,使用者進入自己的『家目錄』之後,例如 root 的家目錄在 /root 底下,一般使用者的家目錄則在 /etc/passwd 這個檔案裡面規定,那麼主機就已經丟了一個程序稱為 bash 的給你操作囉!
[root@test /root]# command [-options] parameter1 parameter2 ...
指令 選項 參數(1) 參數(2)1. command 為指令的名稱,例如變換路徑的指令為 cd 等等;
2. 中刮號[]並不存在於實際的指令中,而加入參數設定時,通常為 - 號,有時候完整名稱會輸入 -- 符號;
3. parameter1 parameter2.. 為依附在 option 後面的參數,或者是 command 的參數;
4. command, -options, parameter1.. 這幾個咚咚中間以空格來區分,不論空幾格 shell 都視為一格;
5. 指令太長的時候,可以使用 \ 符號來跳脫 [Enter] 符號,使指令連續到下一行。實例:
[root@test /root]# ls -al /root <==以 ls 列出 /root 這個目錄中的隱藏檔與相關的屬性參數;
[root@test /root]# ./configure --prefix=/usr/local --with-tcp_wrappers \
> --with-pam <==這兩行實際上是同一行的指令,但是加上 \ 跳脫符號後,指令可以連續到下一行!
[root@test /root]# ls -al /root <==這個指令與第一個相同,空白字元不論幾個,僅視為一個來處理。
再繼續研究 BASH 之前,我們要就變數這個東西來討論一番,因為在主機裡面有太多的資料需要進行存取了,而這些資料都是一些服務所必須的,例如 mail 的存取路徑在 /var/spool/mail 、家目錄預設在 /home/useraccount 等等,當然我們可以改變這些個變數,但是如果該變數是直接深植於套件當中,那麼當你修改了某些參數之後,嘿嘿!你的套件就必須要『由原始碼直接更新再編譯』才行!這樣似乎很麻煩,所以囉,就會有變數這個好東西出來了!此外,例如我們在執行程式的時候,系統怎麼知道你的 ls 這個指令放在哪裡?原來是有 PATH 這個變數,系統會透過這個變數裡面所設定的路徑去依序尋找該指令系統,如果找不到的話,那麼才在螢幕上顯示『 command not found 』字樣!這些還都只是系統預設的變數的目的,如果是個人的設定方面:例如你要寫一個大型的 script (批次檔)時,有些資料因為可能由於使用者習慣的不同而有差異,比如說路徑好了,由於該路徑在 script 被使用在相當多的地方,如果下次換了一部主機,都要修改 script 裡面的所有路徑,那麼我一定會瘋掉!這個時候如果使用變數,而將該變數的定義寫在最前面,後面相關的路徑名稱都以變數來取代,嘿嘿!那麼你只要修改一行就等於修改整篇 script 了!方便的很!所以,良好的程式設計師都會善用變數的定義!(這個部分我們在底下還會再提到!)
舉個簡單的例子來說, sendmail 的 smtp 存放 mail 路徑是經由 /etc/profile 裡頭的 MAIL="/var/spool/mail/$USER"來設定的,而當我修改了上面這一個咚咚,然後重新開機之後,嘿嘿嘿嘿!我的郵件就可以存放到不同的路徑去了!而且不會有問題!可以順利的『在 Linux 主機上面』收發。然而問題發生在 pop3 這個服務上面,由於 pop3 的預設路徑是在 source code 裡頭,而且就正是 /var/spool/mail 這個路徑,也就是說,不論我怎麼修正我的『變數』, pop3 都不為所動!唉~真慘,所以就無法直接以 pop3 來收信了(例如 OutLook 就不能工作了)!會發生密碼不接受的問題呢!
如果說的學理一點,那麼由於在 Linux System 下面,所有的執行續都是需要一個執行碼,而就如同上面提到的,你『真正以 shell 來跟 Linux 溝通,是在正確的登入 Linux 之後!』這個時候你就有一個 bash 的執行程序,也才可以真正的經由 bash 來跟系統溝通囉!而在進入 shell 之前,也正如同上面提到的,由於系統需要一些變數來提供他資料的存取(或者是一些環境的設定參數值,例如是否要顯示彩色等等的),所以就有一些所謂的『環境變數』需要來讀入系統中了!這些環境變數例如 PATH、HOME、MAIL、SHELL等等,都是很重要的,為了區別與自訂變數的不同,環境變數通常以大寫字元來表示呢!
說了那麼久,那麼到底『什麼是變數』呢?簡單的說,『變數就是以一組文字或符號等,來取代一些設定或者是一串保留的資料!』,例如:『VBird』就是『鳥哥』,所以當你讀取 VBird 的時候,系統自然就會知道!哈!那就是鳥哥!最簡單的例子可以取 PATH 來說明!如果你對於『相對路徑與絕對路徑』還有點印象的話,那麼應該曉得『要下達正確的指令,應該需要指定路徑與檔名』才行!例如你的 ls 指令應該需要以『/bin/ls』來下達指令才對,那麼為何你在任意的路徑下都可以執行 ls 呢?而不需要指定路徑呢?這是因為系統已經預設了一些『搜尋路徑(PATH)』了,所以當你需要執行一些指令的時候,系統就會依照該 PATH 的設定來進行指令的搜尋!而這個 PATH 就是所謂的變數了!那麼如何『顯示變數』呢?這就需要使用到 echo 這個指令啦!
- echo
顯示變數內容
語法:就如同上面的範例,當我們要顯示目前的 PATH 這個變數時,使用了 echo ,而為了要分辨是否為變數,那麼 Linux 系統預設變數名稱前面會加上一個『 $ 』符號,所以就必須要寫成 echo $PATH 囉!
[test @test test]# echo $variable
參數說明:
範例:
[test @test test]# echo $PATH
/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/loc
al/bin:/bin:/usr/bin:/usr/X11R6/bin
例題:請在螢幕上面顯示出您的環境變數 PATH, HOME 與 MAIL:
答:[root@test root]# echo $PATH
/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin
[root@test root]# echo $HOME
/root
[root@test root]# echo $MAIL
/var/spool/mail/root
有多少的環境變數呀?使用 env 與 set 來看看:
嗯!既然環境變數是挺重要的,那麼到底有多少的環境變數在 Linux 系統中呢?呵呵!你可以簡單的使用 env 就可以知道囉!『基本上,在 Linux 預設的情況中,使用{大寫的字母}來設定的變數一般為系統內定需要的變數』,底下列出 Linux 系統中 預設的變數內容:
- env
顯示目前系統中主要的預設變數內容
語法:env environment 的簡寫,所以說,這個指令主要在將目前系統中的主要變數讀出來!但是,不是說我們還可以自訂變數嗎?因此,除了 env 這個讀取環境變數的指令之外,還有一個可以將目前系統中所有的變數資料都讀出來的指令,稱為 set !set 除了會將上面的資料都給他讀出來之外,還會有額外的這些資訊也一起讀入(通常都與使用者的設定有關!)
[test @test test]# env
ENV=/root/.bashrc <==使用者自訂環境變數的設定檔案
HISTSIZE=1000 <==目前的指令記憶數量
HOME=/home/test <==登入者的家目錄
HOSTNAME=test.adsldns.org <==這部主機的主機名稱
HOSTTYPE=i386 <==這部主機的硬體等級大致狀態(i386, i686..)
INPUTRC=/etc/inputrc <==一些 shell 載入的資料檔案設定處
LANGUAGE=C <==預設語系的資料
LANG=zh_TW.Big5
與 LANGUAGE 類似,這個則是各個 linux distribution 常用的預設語系變數,由於我的 Mandrake 使用中文安裝,所以預設語系是中文,亦即 zh_TW.Big5 ,如果我要修改這個變數,可以到 /etc/sysconfig/i18n 去修改!底下的 LC_xxx 均是與預設的表示語系有關的變數,其中比較有趣的是 LC_TIME ,如果在文字介面下,最好將 LC_TIME 改成美規日期的顯示方式,才不會有亂碼!
LC_COLLATE=zh_TW.Big5
LC_CTYPE=zh_TW.Big5
LC_MESSAGES=zh_TW.Big5
LC_MONETARY=zh_TW.Big5
LC_NUMERIC=zh_TW.Big5
LC_TIME=en
LESSOPEN=|/usr/bin/lesspipe.sh %s <==用來設定 less 使用的一支 script 檔案
LOGNAME=test <==登入者的帳號MACHTYPE=i586-mandrake-linux-gnu
主機的硬體配備等級 i586 為 P MMX 等級,至於 K7 及 PIII 之後的,就是 i686 等級囉!MAIL=/var/spool/mail/test <==登入者的郵件預設放置地點
OSTYPE=linux-gnu <==作業系統的形式(linux-gnu)
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/test/bin
PWD=/home/test <==目前登入者所在的目錄(當下的目錄)
SHELL=/bin/bash <==登入者使用的 shell 類型
USER=test <==目前這個登入者的使用者名稱
- set
顯示目前系統中全部的變數內容
語法:set 的輸入就是直接輸入 set 即可!他除了會顯示出目前的『環境變數』之外,也會顯示出您的『自訂變數』呢!那麼有哪些與使用者較有相關性的自訂變數呢?我們上面僅列出部分常見的變數值囉!
[test @test test]# set
BASH=/bin/bash <==BASH 的主程式放置路徑
BASH_VERSINFO=([0]="2" [1]="05" [2]="8" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu") <==BASH 版本資訊
BASH_VERSION=$'2.05.8(1)-release' <==BASH 的版本
COLORS=/etc/DIR_COLORS <==使用顏色
COLUMNS=100 <==目前這個終端機使用的欄位有幾個字元距離
HISTFILE=/home/vbird/.bash_history <==目前用來存過往指令的檔案,為一個隱藏檔
HISTFILESIZE=1000 <==存起來的檔案中,指令的最大數(只紀錄 1000 個指令)
IFS=$' \t\n' <==預設的分隔符號
langfile=/home/vbird/.i18n <==語系選擇的檔案
LINES=40 <==目前游標所在的位置為第幾行
MAILCHECK=60 <==每隔多久檢查一次有無新信件(秒數)
PPID=24572 <==目前 bash 這個父程序的 ID !
PROMPT_COMMAND=$'echo -ne "\\033]0;${USER}@${HOSTNAME%%.*}:${PWD/$HOME/~}\\007"' <==提示字元顯示的內容
SHELLOPTS=braceexpand:hashall:histexpand:monitor:history:interactive-comments:emacs
SUPPORTED=zh_TW.Big5:zh_TW:zh:en_US:en <==支援的語系
TERM=xterm <==終端機形式
UID=500 <==登入者的使用者 ID (UID)
$ <==目前 shell 的 PID
?
最後一個命令的回傳值,若之前的命令被正確的執行會傳回 0 ,否則會傳為 1 或其他錯誤代碼。
使用 set 除了會將系統的預設值秀出來之外,連帶的所有的你自己設定的變數也會被秀出來!同時需要注意的是,若當時有相當多人同時在線上的話,那麼你的變數只能給自己使用(除非改的是系統的預設參數檔,如 /etc/profile ),而不會干擾到別人的!就如同前面所說的,由於你登入 Linux 之後會取得一個 PID ,而你的設定將只對這個 PID 與子程序有關!此外,這次登入所進行的變數設定,如果沒有更動到設定檔,那麼這次設定的變數在下次登入時將被取消掉(因為程序 PID 不見囉!)!所以囉,如果你想要你的變數每次都能在你登入的時候自動就設定好了,那麼就必須將你的設定寫入登入時載入的設定檔!
上面的變數中,比較有趣的是 $ 與 ? 這兩個咚咚,尤其是 ? 這個變數,如果您上一個命令執行的過程中沒有錯誤,那麼這個變數就會被設定為 0 ,如果您的上個命令有錯誤訊息,那麼這個變數會變成 1 或其他的錯誤代碼!現在馬上動手試看看您的上個指令執行成果為何?
echo $?
- 變數設定規則:
好了,我們知道了一些系統的預設變數了,但是如果是我自己想要設定一些我自己的變數,該如何設定呢?有什麼規則需要遵守?呵呵!在說明之前,可能要來讓大家瞭解一下為什麼自己會想來設定變數?
底下我們舉幾個例子來說明一下:
一般變數設定:
[tets @test test]# 12name=VBrid <==錯誤的!因為變數開頭不能是數字! [test @test test]# name = VBird <==錯誤的!因為等號兩邊不能直接接空白! [test @test test]# name=VBird <==正確的!echo $name 顯示 VBird [test @test test]# name=VBird name <==錯誤的!需要加上雙引號!不然會顯示錯誤! [test @test test]# name="VBird name" <==正確的!echo $name 顯示 VBird name [test @test test]# name="VBird's name" <==正確的! 變數累加設定:
變數延伸到下一個子程序:
指令中的指令:
取消變數設定:
|
例題:在變數的設定中,單引號與雙引號有什麼不同呢?
答: 單引號與雙引號的最大不同在於雙引號仍然可以保有變數的內容,但單引號內僅能是一般字元,而不會有特殊符號。我們以底下的例子做說明:假設您定義了一個變數, name=VBird ,現在想以 name 這個變數定義出 myname 顯示 VBird its me 這個內容,要如何訂定呢?[root @test root]# name=VBird發現了嗎?沒錯!使用了單引號的時候,那麼 $name 將失去原有的變數內容,僅為一般字元的顯示型態而已!這裡必需要特別小心在意! |
例題:在指令下達的過程中, quote ( ` ) 這個符號代表的意義為何?
答: 在一串指令中,在 ` 之內的指令將會被先執行,而其執行出來的結果將做為外部的輸入資訊!例如 uname –r 會顯示出目前的核心版本,而我們的核心版本在 /lib/modules 裡面,因此,你可以先執行 uname –r 找出核心版本,然後再以『 cd 目錄』到該目錄下,當然也可以執行cd /lib/modules/`uname –r`直接到該目錄下去! |
- export
當你取得一個 bash 之後,亦即得到了一個程序了,但是若你再次的執行一次 bash ,那麼你將進入『子程序』,這個程序的概念我們在資源管理章節中再詳談,這裡您先有個概念即可。那麼由於您已經進入了該子程序,所以在父程序中的變數設定將不再繼續的存在。如您想要讓該變數內容繼續的在子程序中使用,那麼就請執行:
export 變數
!這個東西用在『引用他人的檔案或者其他程序』時,相當的重要的!尤其像我常常兩三個檔案互相引用來引用去的,如果忘記設定 export 的話,那麼不同的檔案中的相同變數值,將需要一再地重複設定才行!所以,我只要在頭一個檔案使用 export 的話,那麼後續的檔案引用時,將會把該變數內容讀進來!好用的很?而,如果僅下達 export 而沒有接變數時,那麼此時將會把所有的『環境變數』秀出來喔!也就是說, export 可以將一般自訂的變數變成環境變數!
[root @test root]# export
declare -x BASH_ENV="/root/.bashrc"
declare -x CVSROOT="/usr/local/cvs/src/master"
declare -x HISTSIZE="50"
declare -x HOME="/root"
declare -x HOSTNAME="test.adsldns.org"
declare -x HOSTTYPE="i386"
declare -x INPUTRC="/etc/inputrc"
declare -x LANG="en_US"
declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="root"
declare -x LS_COLORS="no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:
bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=
01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh
=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.z
ip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;
31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=
01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:"
declare -x MACHTYPE="i386-redhat-linux-gnu"
declare -x MAIL="/var/spool/mail/root"
declare -x MANPATH=":/usr/local/netcdf/man"
declare -x OSTYPE="linux-gnu"
declare -x PATH="/usr/local/pgi/linux86/bin:/bin:/sbin:/usr/sbin:/usr/bin:
/usr/local/sbin:/usr/local/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin
:/usr/local/netcdf/bin"
declare -x PGI="/usr/local/pgi"
declare -x PWD="/root"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="xterm"
declare -x USER="root"
- unset
就是直接將該變數的內容拿掉:
unset 變數
- 變數的有效範圍:
由前面的 export 以及相關的說明,你可以很清楚的知道一件事情,那就是,『變數的設定只在目前這個 shell 環境當中存在,在下個或者是在子程序中 ( 子 shell ) 將不會存在!』要讓變數在下個程序也可以繼續的使用,大概就是使用 export 這個咚咚啦!此外,其實除了 shell 的父、子程序外,在腳本( scripts )的編寫當中,由於有的軟體會使用到 2 個以上的 scripts 做為一個完整的套件!也就是說,假如你有兩支程式,一支為 scripts1.sh 以及 scripts2.sh ,而 scripts2.sh 會去引用 scripts1.sh 的變數,這個時候,嘿嘿!你在 scripts1.sh 當中設定的變數請『千萬記得以 export 設定』,否則你的變數將無法在兩個 scripts 之間互相被引用喔!當這個 scripts 執行完畢之後,剛剛在 scripts 當中設定的變數也就『失效了!』。
- 其他的注意事項:
乍看之下變數似乎沒有什麼值得我們來留意的地方,其實不然,變數可以讓我們的系統管理變的更加的簡單,舉個例子來說,剛剛我們提到 HISTSIZE 可以控制歷史指令的多寡,那麼太多的話,可能會有安全的顧慮之虞,那麼是否需要改小一點呢?當然需要~此外,關於路徑的設定方面,當您使用一般身份使用者登入系統,再以 su 轉換成 root 身份時,基本上,一堆環境變數仍是以當初的一般身份者為主的,因此,您常常會發現 root 使用的指令會『找不到!』那就是環境變數的錯誤設定啦!這個時候,如果您能夠將該一般身份使用者的路徑設定成為 root 能用的指令的樣子,嗯!那麼轉換身份的時候,將可以免除相當多的困擾呢!提供給你做為參考了!
- read:
上面我們談到的『變數』都是由『指令列』直接設定好的!那麼可不可以隨時來提供使用只以鍵盤隨時輸入變數內容?也就是說,變數內容是由使用者由鍵盤輸入的哩!呵呵!可以使用 read 來達成喔!這個東西在『 script 』裡面比較重要啦!所以我們在 shell script 裡面會再次的提到喔!
語法:
[test @test test]# read name
testing <==這個時候螢幕會等待使用者由鍵盤輸入喔!
[test @test test]# echo $name
testing <==剛剛輸入的資料變成了變數的內容啦!
- array:
談完了一些基本的變數之後,再接下來我們可以聊一聊關於『陣列, Array』這東西了!學過數學應該知道有所謂的陣列吧!他可以使用一個『函數』來包含一些內容!例如 A(1)=1, A(2)=4, A(3)=8 等等的樣子,那個 A(n) 就是函數, n 就是 index(索引),而在等號的右邊就是這個函數對應索引所得到的『內容』啦!在 Bash 裡頭提供了『一維陣列』給大家來使用,他的設定格式是:
語法:注意一下喔!在設定陣列的時候,他主要是以 『字母及中刮號, abc[]』的樣式來設定的!其他的規則則與 變數設定規則 相同!不過,在讀取陣列的時候就需要比較注意了!讀取的時候,是以 ${陣列函數} 的方式來讀取的!這部份特別容易搞錯!請大家特別留意呢!當然啦,陣列不止可以進行數字的型態,也可以是字串的類型喔!都可以的啦!
[test @test test]# a[索引]=內容
[test @test test]# echo ${a[索引]}
例:
[test @test test]# a[1]=4
[test @test test]# a[2]=8
[test @test test]# echo ${a[1]} ${a[2]}
4 8
- $RANDOM:
有聽過『隨機取亂數』這個玩意兒吧!?呵呵!那麼在 BASH 裡面的亂數是那個變數來的?亂數在英文的寫法為 RANDOM 啦,所以囉, BASH 當中針對亂數的變數名稱就是 $RANDOM 囉!來給他秀一下吧!
語法:亂數對於程式設計師比較重要,對於我們一般使用者,重要性就沒有這麼大啦!只是提出來讓大家知道一下就是了!
[test @test test]# echo $RANDOM
xxxx <==每次都會出現不同的數字喔!
- eval:
語法:這個指令也是頗有趣的!他主要是用來做為變數的『疊代』用的!以上面的例子來看,起先, \$$year 會變成為 $days ,而這個 $days 其實是一般字元喔!並不是變數!不過,加上了 eval 之後,這個字串就會被變成變數內容咯!所以說, eval 是用來做為『二次疊代』的功能的!
[test @test test]# eval variable
例題:
[test @test test]# days=365
[test @test test]# year=days
[test @test test]# echo \$$year
$days <==第一個 $ 被 \ 改變成為一般字元,而 \$ 後面接的 $year 就成為 days 啦!
[test @test test]# eval echo \$$year
365
加上 eval 之後, \$$year 變成的 $days 的『變數內容』會顯現出來喔!
[test @tset test]# alias lm='ls -al | more' |
要注意的是:『alias 的定義規則與變數定義規則幾乎相同』,所以你只要在
alias 後面加上你的{『別名』='指令 參數'},以後你只要輸入
lm 就相當於輸入了 ls -al|more 這一串指令!很方便吧!另外,我們知道 root
可以移除( rm )任何資料!所以當你以 root 的身份在進行工作時,需要特別小心,但是總有失手的時候,那麼
rm 提供了一個參數來讓我們確認是否要移除該檔案,那就是 -i 這個參數!所以,你可以這樣做:
[test @tset test]# alias rm='rm -i' |
[test @tset
test]# alias
alias l.='ls -d .[a-zA-Z]* --color=tty' alias ll='ls -l' alias lm='ls -al' alias ls='ls --color=tty' alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde' |
至於如果要取消命令別名的話,那麼就使用 unalias 吧!
那麼命令別名與變數有什麼不同呢?基本上,他們的意義就不太一樣了! alias
這種命令別名,你可以將他想成是建立一個新的指令名稱,至於變數則僅是將一個數值或者字串存在某個代表意義當中!舉個例子好了,我們知道以前的
DOS 年代,列出目錄與檔案就是 dir ,而清除螢幕就是 cls ,那麼如果我想要在
linux 裡面也使用相同的指令呢?那就以 alias 來進行指令的別名設定:
[test @test
test]# history
[test @test test]# [!number] [!command] [!!] 參數說明: number :第幾個指令的意思; command :指令的開頭幾個字母 ! :上一個指令的意思! 範例: [test @test test]# history <==底下列出的就是(1)歷史指令的編號;(2)指令的內容 66 man rm 67 alias 68 man history 69 history [test @test test]# !66 <==執行第 66 個歷史指令 [test @test test]# !! <==執行上一個指令(在本例中,就是 !66 那一個指令!) [test @test test]# !al <==執行最近一次以 al 為開頭的指令內容,就是第 67 個指令囉! |
[test @test
test]# more .bashrc
# User specific aliases and functions PATH="/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/sbin:/usr/bin:$PATH" Export PATH Alias rm='rm
-i'
# Source global
definitions
|
[test @test test]# source 變數設定檔 |
這個使用的情況在什麼時候呢?最常發生在一個人的工作環境分為多重的時候了!舉個例子來說,在我的大型主機中,我常常需要負責兩到三個不同的案子,每個案子所需要處理的環境變數訂定並不相同,那麼我就將這兩三個案子分別編寫屬於該案子的環境變數設定檔案,當我需要該環境時,就直接 source 變數檔,如此一來,環境變數的設定就變的更簡便而靈活了!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
上面的萬用字元當中,最常用的就屬 *, ?, [] 及 ` 了!我們提幾個簡單的例子:
[test @test
test]# ls test* <==那個 * 代表後面不論接幾個字元都予以接受(沒有字元也接受!)
[test @test test]# ls test? <==那個 ? 代表後面『一定』要接『一個』字元 [test @test test]# ls test??? <==那個 ??? 代表『一定要接三個』字元! [test @test test]# cp test[1-5] /tmp <==將 test1, test2, test3, test4, test5 若存在的話,就拷貝到 /tmp 下 [test @test test]# cd /lib/modules/`uname -r`/kernel/drivers <==被 ` ` 括起來的內容『會先執行』! |
- 連續指令的下達方式:
這裡需要再提幾個重要的資訊,我們剛剛上面提過說,兩個指令先後寫在一起,可以這樣寫:
command1; command2
利用分號『 ; 』來分隔,這個分號的意思,代表不論 command1 執行結果為何,command2 都會被執行!那麼如果我是兩個相關的指令,第一個 command1 如果執行結果有錯誤,第二個就不被執行,可以這樣做嗎?當然可以,就使用下面兩個連結的咚咚:
command1 && command2
command1 || command2
還記得我們之前的變數內容中,那個 ? 代表什麼嗎?沒錯,就是代表前一個執行的指令內容有沒有錯誤,如果有錯誤就回傳為 1 ,沒有錯誤就回傳為 0 ,你可以經由 echo $? 來查詢得知!那麼 && 就是代表,當 command1 執行結果傳回值為 0 的時候,也就是沒有錯誤訊息時,則 command2 才會開始執行,而 || 恰恰相反,當 command1 有錯誤訊息時, command2 才會執行!舉個例子來說,我的系統中並沒有 /vbird 這個目錄,所以執行 ls /vbird 應該會有錯誤訊息才對,所以,底下三個指令串會顯示什麼呢?
[root @test root]# ls /vbird ; ls /
[root @test root]# ls /vbird && ls /
[root @test root]# ls /vbird || ls /試看看呦!
[test @tset test]# /bin/more .bashrc<==我在的目錄為 /home/test !這是絕對路徑寫法! |
[test @tset
test]# ls -al
total 728 drwx------ 3 vbird vbird 4096 May 19 14:53 . <==這一層路徑的屬性說明 drwxr-xr-x 3 root root 4096 May 5 16:50 .. <==上一層路徑的屬性說明 以下略! |
[test @tset test]# ../../bin/more .bashrc <==一層一層回到根目錄,在進入 /bin 的寫法!相對路徑 |
咦!剛剛不是提到『.』與『..』嗎?那麼那個『 . 』是幹嘛用的?!眼尖的朋友應該已經發現了,就是『我在執行檔案的時候,基本上,並不會主動搜尋目前目錄下的檔案』舉個例子來說,我安裝的 squid 這個執行檔在 /usr/local/squid/bin/squid 這個檔案,然而我在 /usr/local/squid/bin 下達 squid 的時候,系統會告訴你『查不到這個檔案!』真是見鬼了!明明有這個檔案的呀!這是因為系統預設的 PATH (路徑)並沒有執行目前目錄下的設定,也就是『.』這個路徑!你可以使用『 echo $PATH 』看看,就可以知道為什麼了!那麼為何不要設定這個路徑呢?這是因為『安全』的考量。由於系統預設是允許任何人在 /tmp 底下寫入任何檔案的,那麼萬一有居心不良的使用者或者是 Cracker 入侵你的電腦,並在你的 /tmp 裡頭埋了一個小木馬,並取名為 ls ,好了,改天你以 root 身份登入後,到 /tmp 底下,並執行 ls ,你看會有什麼結果?!這個 /tmp/ls 由其他身份的人來執行或許沒有問題,但是由 root 來執行卻可能會導致 Cracker 所樂意見到的結果!那曉得為何了吧?! 當然囉!您還是可以選擇在 ~/.bashrc 當中設定你的 . 在你的 PATH 當中,不過並不這麼建議就是了! |
[test @tset bin]# ./squid <==以相對路徑的觀念來看!在本目錄下達的指令寫法! |
|
1>> 2> 2>> < |
|
左邊一定是指令,至於右邊則可能是裝置或者是檔案!注意了!那個
1> 與 2> 之間並沒有空白字元!而相關的使用說明可以舉例如下:
[test @test
test]# ls -al > list.txt
將顯示的結果輸出到 list.txt 檔案中,若該檔案以存在則予以取代! [test @test test]# ls -al >> list.txt 將顯示的結果累加到 list.txt 檔案中,該檔案為累加的,舊資料保留! [test @test test]# ls -al 1> list.txt 2> list.err 將顯示的資料,正確的輸出到 list.txt 錯誤的資料輸出到 list.err [test @test test]# ls -al 1> list.txt 2>&1 將顯示的資料,不論正確或錯誤均輸出到 list.txt 當中! [test @test test]# ls -al 1> list.txt 2> /dev/null 將顯示的資料,正確的輸出到 list.txt 錯誤的資料則予以丟棄! 注意!錯誤與正確檔案輸出到同一個檔案中,則必須以上面的方法來寫! 不能寫成其他格式! |
這個觀念相當的重要,尤其是在 /etc/crontab 當中執行的時候,如果我們已經知道錯誤的訊息為何,又不想要讓錯誤的訊息一直填滿 root 的信箱,就必須以 2> 搭配 /dev/null 這個垃圾桶黑洞裝置,來將資料丟棄!這個相當的重要!
好了,對於『 > , >> 』這兩個東西有一定的概念之後,我們來深入的談一談『命令輸出重導向』的觀念吧!如前所述,基本上, Linux 執行的結果中,可以約略的分成『正確輸出』與『錯誤輸出』兩種方式。例如,當你以一般身份執行 find 這個指令時,例如執行『 find / -name testing 』時,由於你是一般身份,又有些資料夾是不允許一般身份者進入的,所以囉,當你使用 find 時,就會有錯誤訊息發生了!但同時如果有 testing 這個檔案在你可以進入的資料夾當中,那麼螢幕也會輸出到給你看!因此,就具有正確的與錯誤的輸出兩種囉!(分別稱為 Stdout 與 Stderror)例如下面為執行結果:裡面的『 find: /home/root: Permission denied 』就告訴你該資料夾你沒有權限進入,這就是錯誤的輸出了,那麼『 /home/test/tseting 』就是正確的輸出了!
[test @test test]# find / -name testing
find: /home/test1: Permission denied <==這是錯誤的輸出
find: /home/root: Permission denied <==這是錯誤的輸出
find: /home/masda: Permission denied <==這是錯誤的輸出
/home/test/testing <==這是『正確』的輸出
[test @test test]#好了,那麼假如我們想要將資料輸出到 list 這個檔案中呢?執行『 find / -name testing > list 』會有什麼結果?呵呵,你會發現 list 裡面存了剛剛那個『正確』的輸出資料,至於螢幕上還是會有錯誤的訊息出現呢!傷腦筋!如果想要將正確的與錯誤的資料分別存入不同的檔案中需要怎麼做?!呵呵!其實在資料的重導向方面,正確的寫法應該是『 1> 』與『 2> 』才對!但是如果只有 > 則預設是以 1> 來進行資料的!那個 1> 是輸出正確資料, 2> 則是錯誤資料輸出項目。也就是說:
好了,那麼上面的例子中,我們如何將資料輸出到不同的地方去呢?可以這麼寫:
- 1> :是將正確的資料輸出到指定的地方去
- 2> :是將錯誤的資料輸出到指定的地方去
[test @test test]# find / -name testing 1> list_right 2> list_error 這樣一來,剛剛執行的結果中,有 Permission 的那幾行錯誤資訊都會跑到 list_error 這個檔案中,至於正確的輸出資料則會存到 list_right 這個檔案中囉!這樣可以瞭解了嗎?如果有點混亂的話,去休息一下再來看看吧!!
[test @test test]# find / -name testing 1> list_right 2> /dev/null |
很神奇呦! error message 就會『不見了!』呵呵!真高興!另外,如果我要將資料都寫到同一個檔案中呢?這個時候寫法需要用到特殊寫法,請注意底下的寫法呦!
[test @test
test]# find / -name testing 1> list 2> list<==錯誤寫法
[test @test tset]# find / -name testing 1> list 2>&1 <==正確寫法 |
請特別留意這一點呢!同時寫入同一個檔案需要使用 2>&1 才對呦!
1. 完全由鍵盤輸入資料:
[root @test test]# mail -s "test" root <== -s 表示標題, root 為收件者 I am root! <==以下的資料都是由鍵盤輸入的 That's OK . <==要結束鍵盤的輸入時,需要在一行的最前面加上 . 即可! CC. <==是否需要有密件副本?不需要的話,直接按下 Enter ! EOF <==表示送出的提示字元而已! 2. 由檔案代替輸入
|
很有趣吧! ^_^ 這樣就可以將信寄出去囉!所以說,熟悉命令重導像的話,對您可是相當的有幫助的呦!
[test @test
bin]# last
[test @test bin]# last | grep root [test @test bin]# last | grep root | wc -l |
- cut
語法:說明:
[root @test /root ]# cut -d "分隔字元" [-cf] fields
參數說明:
-d :後面接的是用來分隔的字元,預設是『空白字元』
-c :後面接的是『第幾個字元』
-f :後面接的是第幾個區塊?
範例:
[root @test /root]# cat /etc/passwd | cut -d ":" -f 1
將 passwd 這個檔案裡面,每一行裡頭的 : 用來作為分隔號,
而列出第一個區塊!也就是姓名所在啦![root @test /root]# last | cut -d " " -f1
以空白字元為分隔,並列出第一個區間![root @test /root]# last | cut -c1-20
將 last 之後的資料,每一行的 1-20 個字元取出來!
這個 cut 實在很好用!不過,說真的,除非你常常在分析 log 檔案,否則使用到 cut 的機會並不多!好了! cut 主要的用途在於將『同一行裡面的資料進行分解!』,最常使用在分析一些數據或文字資料的時候!這是因為有時候我們會以某些字元當作分割的參數,然後來將資料加以切割,以取得我們所需要的資料。我也很常使用這個功能呢!尤其是在分析 log 檔案的時候!
- sort
語法:說明:
[root @test /root ]# sort [-t 分隔符號] [(+起始)(-結束)] [-nru]
參數說明:
-t 分隔符號:使用分隔符號來隔開不同區間,預設是 tab
+start -end:由第 start 區間排序到 end 區間
-n :使用『純數字』排序(否則就會以文字型態來排序)
-r :反向排序
-u :相同出現的一行,只列出一次!
範例:
[root @test /root]# cat /etc/passwd | sort
將列出來的個人帳號排序![root @test /root]# cat /etc/passwd | sort -t: +2n
將個人帳號中,以使用者 ID 來排序(以 : 來分隔,第三個為 ID ,
但第一個代號為 0 之故)[root @test /root]# cat /etc/passwd | sort -t: +2nr
反相排序囉!
sort 同樣是很常用的指令呢!因為我們常常需要比較一些資訊啦!舉個上面的第二個例子來說好了!今天假設你有很多的帳號,而且你想要知道最大的使用者 ID 目前到哪一號了!呵呵!使用 sort 一下子就可以知道答案咯!當然其使用還不止此啦!有空的話不妨玩一玩!
- wc
語法:說明:
[root @test /root ]# wc [-lmw]
參數說明:
-l :多少行
-m :多少字元
-w :多少字?
範例:
[root @test /root]# cat /etc/passwd | wc -l
這個檔案裡頭有多少行?[root @test /root]# cat /etc/passwd | wc -w
這個檔案裡頭有多少字!?
wc 也可以當作指令?呵呵!這可不是上洗手間的 WC 呢!這是相當有用的計算檔案內容的一個工具組喔!舉個例子來說,當你要知道目前你的帳號檔案中有多少個帳號時,就使用上面的 wc -l 啦!因為 /etc/passwd 裡頭一行代表一個使用者呀!所以知道行數就曉得有多少的帳號在裡頭了!而如果要計算一個檔案裡頭有多少個字元時,呵呵!就使用 wc -w 這個參數吧!
[root @test
/root ]# last | tee last.list | cut -d " "
-f1
參數說明: 範例: [root @test /root]# last | tee last.list | cut -d " " -f1 |
[root @test
/root ]# tr [-ds] SET1
參數說明: -d :刪除 SET1 這個字串 -s :取代掉重複的字元! 範例: [root @test /root]# last | tr '[a-z]' '[A-Z]' <==將小寫改成大寫 [root @test /root]# cat /etc/passwd | tr -d : <==嘿嘿! : 這個符號在 /etc/passwd 中不見了! [root @test /root]# cat /home/test/dostxt | tr -d '\r' > dostxt-noM <==將 DOS 檔案的字尾符號 ^M 的符號去除! |
[root @test
/root ]# split [-bl] 輸入檔案 輸出檔案前導字元
參數說明: -b :以檔案 size 來分 -l :以行數來分 範例: [root @test /root]# split -l 5 /etc/passwd test <==會產生 testaa, testab, testac... 等等的檔案 |