歷史命令:history
前面我們提過 bash 有提供指令歷史的服務!那麼如何查詢我們曾經下達過的指令呢?就使用 history 囉!當然,如果覺得 histsory 要輸入的字元太多太麻煩,可以使用命令別名來設定呢! 不要跟我說還不會設定呦! ^_^
alias h='history'
如此則輸入 h 等於輸入 history 囉!好了,我們來談一談 history 的用法吧!
[root@linux ~]# history [n]
[root@linux ~]# history [-c]
[root@linux ~]# history [-raw] histfiles
參數:
n :數字,意思是『要列出最近的 n 筆命令列表』的意思!
-c :將目前的 shell 中的所有 history 內容全部消除
-a :將目前新增的 history 指令新增入 histfiles 中,若沒有加 histfiles ,
則預設寫入 ~/.bash_history
-r :將 histfiles 的內容讀到目前這個 shell 的 history 記憶中;
-w :將目前的 history 記憶內容寫入 histfiles 中!
範例:
範例一:列出目前記憶體內的所有 history 記憶
[root@linux ~]# history
# 前面省略
1017 man bash
1018 ll
1019 history
1020 history
# 列出的資訊當中,共分兩欄,第一欄為該指令在這個 shell 當中的代碼,
# 另一個則是指令本身的內容喔!至於會秀出幾筆指令記錄,則與 HISTSIZE 有關!
範例二:列出目前最近的 3 筆資料
[root@linux ~]# history 3
1019 history
1020 history
1021 history 3
範例三:立刻將目前的資料寫入 histfile 當中
[root@linux ~]# history -w
# 在預設的情況下,會將歷史紀錄寫入 ~/.bash_history 當中!
[root@linux ~]# echo $HISTSIZE
1000
在正常的情況下,當我們以 bash 登入 Linux 主機之後,系統會主動的由家目錄的 ~/.bash_history 讀取以前曾經下過的指令,那麼 ~/.bash_history 會記錄幾筆資料呢?這就與你 bash 的 HISTSIZE 這個變數設定值有關了!在預設的 FC4 底下,是會記錄 1000 筆資料的! 那麼假設我這次登入主機後,共下達過 100 次指令,『等我登出時, 系統就會將 101~1100 這總共 1000 筆歷史命令更新到 ~/.bash_history 當中。』 也就是說,歷史命令在我登出時,會將最近的 HISTSIZE 筆記錄到我的紀錄檔當中啦! 當然,也可以用 history -w 強制立刻寫入的!那為何用『更新』兩個字呢? 因為 ~/.bash_history 記錄的筆數永遠都是 HISTSIZE 那麼多,舊的訊息會被主動的拿掉! 僅保留最新的!
那麼 history 這個歷史命令只可以讓我查詢命令而已嗎?呵呵!當然不止啊! 我們可以利用相關的功能來幫我們執行命令呢!舉例來說囉:
[root@linux ~]# !number
[root@linux ~]# !command
[root@linux ~]# !!
參數:
number :執行第幾筆指令的意思;
command :由最近的指令向前搜尋『指令串開頭為 command』的那個指令,並執行;
!! :就是執行上一個指令(相當於按↑按鍵後,按 Enter)
範例:
[root@linux ~]# history
66 man rm
67 alias
68 man history
69 history
[root@linux ~]# !66 <==執行第 66 筆指令
[root@linux ~]# !! <==執行上一個指令,本例中亦即 !66
[root@linux ~]# !al <==執行最近以 al 為開頭的指令(上頭列出的第 67 個)
經過上面的介紹,瞭乎?歷史命令用法可多了!如果我想要執行上一個指令, 除了使用上下鍵之外,我可以直接以『 !! 』 來下達上個指令的內容,此外, 我也可以直接選擇下達第 n 個指令,『 !n 』來執行,也可以使用指令標頭,例如 『 !vi 』來執行最近指令開頭是 vi 的指令列!相當的方便而好用!基本上 history 的用途很大的!但是需要小心安全的問題!尤其是 root 的歷史紀錄檔案,這是 Cracker 的最愛!因為不小心的 root 會將很多的重要資料在執行的過程中會被紀錄在 ~/.bash_history 當中,如果這個檔案被解析的話,後果不堪吶!無論如何,使用 history 配合『 ! 』曾經使用過的指令下達是很有效率的一個指令方法!
--------------------------------------------------------------------------------
Bash Shell 使用環境:
是否記得我們登入主機的時候,螢幕上頭會有一些說明文字,告知我們的 Linux 版本啊什麼的, 還有,登入的時候,我們還可以給予使用者一些訊息或者歡迎文字呢。此外, 我們習慣的環境變數、命令別名等等的,是否可以登入就主動的幫我設定好? 這些都是需要來注意的。另外,這些設定值又可以分為系統整體設定值與各人喜好設定值, 僅是一些檔案放置的地點不同啦!這我們後面也會來談一談的!
--------------------------------------------------------------------------------
絕對路徑與相對路徑
這個議題說到快要爛掉了~從一開始到現在,這個絕對路徑與相對路徑的問題我們就提到不知道多少次了, 因為他實在很重要~這與 PATH 這個變數關係很大!老實說, 萬一你的 PATH 沒有設定完整的時候,下達指令就必須要以『 一長列的指令連帶根目錄都要列出來 』,呵呵那就是絕對路徑的設定法啦! 基本上,這個『 絕對路徑』與『相對路徑 』的觀念是很重要的!否則你將常常會找不到檔案說! 所謂的『絕對路徑』就是以根目錄開始寫入到檔案的一種命令寫定方法,舉例來說,我目前在 /home/test 這個 test 使用者的家目錄中,我想要看看裡面的 .bashrc 這個檔案的資料,使用的是 more 這個指令,而這個指令在 /bin/more 當中,則正確的下達指令的方法為:
[root@linux ~]# /bin/more .bashrc
我在的目錄為 /home/test !這是絕對路徑寫法! 而如果你還記得我們在 Linux 檔案與目錄管理 那一篇文章中提到的觀念的話,那麼應該記得使用 ls -al 時會出現兩個一定存在的目錄,分別是『.』與『..』,分別代表是『這個路徑』,與『上一層路徑』!
[root@linux ~]# ls -al
drwxrwxr-x 2 root root 4096 Aug 15 11:05 .
drwxrwxr-x 2 root root 4096 Aug 14 23:26 ..
所以說,要執行上一層目錄中的命令,可以下達『../command 』那個 command 指的是存在的可執行檔!那麼我因為在 /home/test 裡面,距離 /bin 有兩層上層目錄,所以我要使用 /bin/more 這個執行檔,並且使用相對路徑的方法,就必須使用:
[root@linux ~]# ../../bin/more .bashrc
這種相對路徑的方法相當廣泛的被運用於 script 當中,這是因為如前面提到的, 每個人的安裝預設的目錄都不相同,則使用相對路徑的話, 很容易就可以找到套件之間相依軟體或者是設定檔案的相關性!
例題:關於路徑搜尋的問題!為何不執行目前所在目錄下的檔案?
答:
咦!剛剛不是提到『.』與『..』嗎?那麼那個『 . 』是幹嘛用的?!眼尖的朋友應該已經發現了,就是『我在執行檔案的時候,基本上,並不會主動搜尋目前目錄下的檔案』舉個例子來說,我安裝的 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 當中,不過並不這麼建議就是了!
好了,由於系統預設並不主動搜尋目前目錄下的執行檔,那麼你應該如何執行『目前目錄下的執行檔』呢? 很簡單呀!就是以相對路徑的觀念,由於『 .. 』是上層,而『 . 』是這一層,所以要執行這一層目錄的命令就使用『 ./command 』即可!例如你的 /usr/local/squid/bin 底下執行 squid 則可以寫成:
[root@linux ~]# ./squid
請特別留意這方面的問題!『新手特別容易犯這個錯誤呢!』
--------------------------------------------------------------------------------
登錄訊息顯示資料: /etc/issue, /etc/motd
還記得我們在終端機介面 (tty1 ~ tty6) 登入的時候,會有幾行提示的字串嗎? 那個字串寫在哪裡啊?呵呵!在 /etc/issue 裡面啊!先來看看:
[root@linux ~]# cat /etc/issue
Fedora Core release 4 (Stentz)
Kernel \r on an \m
在 FC4 裡面預設有三行,這個在我們本機登入時就會顯示在 title 的地方呢~ 咦!那麼那個 \r 及 \m 是啥?您可以使用 man issue 配合 man mingetty 就能夠知道:
issue 內的各代碼意義
\d 本地端時間的日期;
\l 顯示第幾個終端機介面;
\m 顯示硬體的等級 (i386/i486/i586/i686...);
\n 顯示主機的網路名稱;
\o 顯示 domain name;
\r 作業系統的版本 (相當於 uname -r)
\t 顯示本地端時間的時間;
\s 作業系統的名稱;
\v 作業系統的版本。
所以,如果您想要顯示終端機的號碼,就可以加上 \l 在 /etc/issue 檔案內囉~就能夠修改登入字元。 咦!但是還有個 /etc/issue.net 呢!這是啥?沒啥啦!這個是提供給 telnet 這個遠端登入程式用的。 當我們使用 telnet 連接到主機時,主機的登入畫面就會顯示 /etc/issue.net 而不是 /etc/issue 呢!
至於如果您想要讓使用者登入後取得一些訊息,例如您想要讓大家都知道的訊息, 那麼可以將訊息加入 /etc/motd 裡面去!例如:當登入後,告訴登入者, 系統將會在某個固定時間進行維護工作,可以這樣做:
[root@linux ~]# vi /etc/motd
Hello everyone,
Our server will be maintained at 2005/10/10 0:00 ~ 24:00.
Please don't login at that time. ^_^
那麼當你的使用者登入主機後,就會顯示這樣的訊息出來:
Last login: Mon Aug 15 10:17:10 2005 from 127.0.0.1
Hello everyone,
Our server will be maintained at 2005/10/10 0:00 ~ 24:00.
Please don't login at that time. ^_^
是否很方便啊!? ^_^
--------------------------------------------------------------------------------
環境設定檔: bashrc, ~/.bashrc, ~/.profile, profile...,/etc/inputrc, source
關於取得 bash 的環境變數等資料,其實可以有系統規劃與各人喜好, 一般來說,建議使用者直接修改個人設定值即可,不需要更動到系統啦~ 底下我們分別來談一談幾個有趣的設定檔喔!要注意的是,在指令列輸入的變數也好、命令別名也罷, 都是針對該次登入的設定而已,所以只要您一登出,那麼上次的設定值就會不見去! 因此,我們需要有幾個檔案來幫助我們,每次登入的時候,就已經幫我們搞定了環境的設定囉!
--------------------------------------------------------------------------------
系統設定值
所謂的系統設定值,也就是說每個使用者進入到 bash shell 之後,會先讀取的設定檔案! 預設的設定檔案有下列幾個:
/etc/sysconfig/i18n
記得我們在幾個重要變數內談到的語系資料嗎?! 那個語系是由 i18n 所維護的,而 FC4 預設的系統語系設定檔就在 /etc/sysconfig/i18n 當中。 這個檔案有點像這樣:
[root@linux ~]# cat /etc/sysconfig/i18n
LANG="zh_TW.UTF-8"
SYSFONT="latarcyrheb-sun16"
SUPPORTED="zh_TW.UTF-8:zh_TW:zh:en_US.UTF-8"
我預設使用 zh_TW.UTF-8 來作為我的整體語系,當然,我可以在這裡修改 LANG 以及其他相關的語系變數, 例如 LC_CTYPE 或者是 LC_TIME 等等的。不過,一般來說,使用者自己個人的設定不建議在這裡做更動啦! 他們可以自行設定他們自己的設定檔啊!
/etc/profile
這個檔案設定了幾個重要的變數,例如:『PATH、USER、MAIL、 HOSTNAME、HISTSIZE、umask』等等,也同時規劃出 /etc/inputrc 這個針對鍵盤熱建設定的檔案的資料內容。你可以在這裡設定總體的 PATH 等等的資訊! 同時,這個檔案也規劃出 /etc/profile.d 及 /etc/inputrc 這兩個目錄與檔案!
總之,你可以瞭解到剛剛我們學會的變數設定方式,在這個檔案中也可以設定呢! 但是設定上需要特別小心,因為所有的使用者皆會使用到這個檔案的資訊。通常我都喜歡將 /usr/local/bin 這個路徑加成最前面,這是因為通常自己安裝的套件自己最喜歡, 所以當然是最先搜尋囉! ^_^!此外,請注意一下,可以將 HISTSIZE 的大小改變一下,改成 50 就可以啦!比較安全!( 註:這個檔案不論在那個 Linux distributions 當中均存在 /etc/profile 當中,所以,請特別留意此一檔案即可! )。
/etc/bashrc
這個檔案在規劃 umask 的功能,也同時規劃出提示字元的內容 (就是裡頭那個 PS1 啦!) 。特別留意的是,這個檔案在不同的 Linux distribution 裡面,擺放的位置可能不太一樣呢! 所以需要查詢一下才行呦!
/etc/profile.d/*.sh
/etc/profile.d 是一個目錄,裡面針對 bash 及 C-shell 規範了一些資料。 以 FC4 為例,這個目錄裡面就針對了顏色、語系、vim 及 which 等指令進行一些額外的設定, 例如 alias 之類的規範值。我們的 vim 被用 alias 命名為 vi 就是在這個目錄下被設定好的。 當然啦,這個目錄的由來其實是在 /etc/profile 這個檔案內規範的啦! 你可以自行設定一些 *.sh 的檔名的檔案來書寫自己的系統設定值喔!
/etc/man.config
這個檔案乍看之下好像跟 bash shell 沒相關性,但是對於系統管理員來說, 卻也是很重要的一個檔案!這的檔案的內容『規範了使用 man 的時候, man page 的路徑到哪裡去尋找!』所以說的簡單一點,這個檔案規定了下達 man 的時候,該去哪裡查看資料的路徑設定!那麼什麼時候要來修改這個檔案呢?如果你是以 tarball 的方式來安裝你的資料,那麼你的 man page(指令說明檔案)可能會放置在 /usr/local/softpackage/man 裡頭,那個 softpackage 是你的套件名稱, 這個時候你就得以手動的方式將該路徑加到 /etc/man.config 裡頭,否則使用 man 的時候就會找不到相關的說明檔囉。
事實上,這個檔案內最重要的其實是 MANPATH 這個變數設定啦! 我們搜尋 man page 時,會依據 MANPATH 的路徑去分別搜尋啊!另外,要注意的是, 這個檔案在各大不同版本 Linux distributions 中,檔名都不太相同,例如 FC4 用的是 /etc/man.config ,而 SuSE 用的則是 /etc/manpath.config , 可以利用 [tab] 按鍵來進行檔名的補齊啦!
這就是系統在設定的時候常常會使用的檔案!需要特別留意的是,通常設定完了這幾個檔案之後,都需要先 logout 在 login 之後才會將設定整個啟動起來!
--------------------------------------------------------------------------------
個人設定值
那麼個人的喜好設定在哪裡?嘿嘿嘿嘿!那就是在個人家目錄的幾個隱藏檔當中囉! 分別會使用到底下的幾個檔案啦!( 注意!底下的檔案都是隱藏檔,需要使用 ls -al 方能顯示出來 ) ,另外,注意一下囉!底下那個『 ~ 』代表的是『家目錄』的意思:
~/.bash_profile, ~/.bash_login, ~/.profile
這三個檔案通常只要一個就夠了,一般預設是以 ~/.bash_profile 的檔名存在。 會有這麼多的檔案,其實是因應其他 shell 轉換過來的使用者的習慣而已。 這個檔案可以定義個人化的路徑 (PATH) 與環境變數等等。不過,還是有順位上的差異, bash 啟動時,會先去讀取 ~/.bash_profile,找不到時,就去讀取 ~/.bash_login ,然後才是 ~/.profile。
~/.bashrc
鳥哥一般都是將自己的需要輸入在這個檔案裡面的呢! 我的個人化設定值都會寫在這裡說~例如命令別名、路徑等等。
~/.bash_history
還記得我們在歷史命令提到過這個檔案吧?!呵呵!沒錯~預設的情況下, 我們的歷史命令就記錄在這裡啊!而這個檔案能夠記錄幾筆資料,則與 HISTSIZE 這個變數有關啊。每次登入 bash 後,bash 會先讀取這個檔案,將所有的歷史指令讀入記憶體, 因此,當我們登入 bash 後就可以查知上次使用過哪些指令囉。至於更多的歷史指令, 請自行回去參考喔!
~/.bash_logout
這個檔案則記錄了『當我登出 bash 後,系統再幫我做完什麼動作後才離開』的意思。 你可以去讀取一下這個檔案的內容,預設的情況下,登出時, bash 只是幫我們清掉螢幕的訊息而已。 不過,你也可以將一些備份或者是其他你認為重要的工作寫在這個檔案中(例如清空暫存檔), 那麼當你離開 Linux 的時候,就可以解決一些煩人的事情囉!
好了,我們知道在變數的設定規範當中,後輸入的設定值可以取代先輸入的設定值, 那麼在我們登入 bash 的時候,這些設定檔到底是如何讀取的呢?他是這樣讀取的:
先讀取 /etc/profile ,再根據 /etc/profile 的內容去讀取其他額外的設定檔, 例如 /etc/profile.d 與 /etc/inputrc 等等設定檔;
根據不同的使用者,到使用者家目錄去讀取 ~/.bash_profile 或 ~/.bash_login 或 ~/.profile 等設定檔;
根據不同使用者,到他家目錄去讀取 ~/.bashrc 。
所以囉,當我登入 bash 後,最終讀取的設定檔竟然是 ~/.bashrc 呢! 也就是說,在 ~/.bashrc 裡面的設定會是最終的設定值!所以囉, 通常鳥哥我喜歡將個人的一些常用 alias 或 PATH 等環境變數或自訂變數都寫到這個檔案去, 如此一來,不論原來系統幫我們做了什麼設定值,我都可以使用屬於自己熟悉的環境呢! 鳥哥的 ~/.bashrc 有點像這樣:
[root@linux ~]# vi ~/.bashrc
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# User specific aliases and functions
PATH="/bin:/sbin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
PATH="$PATH":/usr/X11R6/bin:/home/dmtsai/bin
LANG=zh_TW.big5
LC_TIME=C
export PATH LC_TIME LANG
umask 022
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias ll='ls -l'
alias lm='ls -al|more'
alias h='history'
仔細看到上頭這個檔案,會不會覺得奇怪啊!為什麼會有第五行的『 . /etc/bashrc 』呢? 那個小數點 (.) 代表什麼意思啊??其實 if [ ... ]; then .... fi 是 shell script 當中的程式寫法, 這個我們會在下一章當中介紹。不過,那個 . 則需要好好的談一談喔!一般來說,如果修改完了設定檔, 通常就是 logout 後再重新 login 到 bash 內,就能夠將環境設定檔重讀了!不過, 我們可以使用底下的方式來讓該設定檔立即生效:
[root@linux ~]# source file
範例:
[root@linux ~]# source ~/.bashrc
[root@linux ~]# . ~/.bashrc
利用 source 或小數點 (.) 都可以將設定檔的內容讀進來目前的 shell 環境中! 舉例來說,我修改了 ~/.bashrc ,那麼不需要登出,立即以 source ~/.bashrc 就可以將剛剛最新設定的內容讀進來目前的環境中!很不錯吧!此外,什麼時候會使用到不同的設定檔呢? 最常發生在一個人的工作環境分為多重的時候了!舉個例子來說,在我的大型主機中, 我常常需要負責兩到三個不同的案子,每個案子所需要處理的環境變數訂定並不相同, 那麼我就將這兩三個案子分別編寫屬於該案子的環境變數設定檔案,當我需要該環境時,就直接『 source 變數檔 』,如此一來,環境變數的設定就變的更簡便而靈活了!
login shell 與 non-login shell
事實上,這些環境設定檔在讀取時,還是有一些差異的,這就得要談到所謂的『login shell』與 『non-login shell』的差異了。基本上,就字面上的意義來解釋的話,所謂的 loign shell 指的就是當使用者登入 Linux 系統時,所取得的那個環境設定檔稱為 login shell。 當登入後,啟動其他的 bash 時所取用的環境設定檔就稱為 non-login shell 。
舉例來說,我以 dmtsai 這個使用者身份登入 Linux 後,然後為了要執行一些數值模擬的工作,而去執行 csh 這個 C shell , 那麼此時我就取得了 non-login shell 了。
另外一個例子是,當我以 X Window 的環境登入 Linux 時,我們不是可以使用『終端機』來開啟 shell 嗎?當登入 Linux 的時候所取得的那個 X 的環境也可以讀入 login shell 的。因此,在 X 環境下所啟動的終端機 (shell),那些 shell 所使用的環境設定檔都是 non-login shell 喔!
login 與 non-login shell 的差異除了取得的時機不同之外,其實他們讀取的環境設定檔也不相同。 我們上頭說過一些個人的環境設定檔案了吧?那麼這兩種類型的 shell 該讀取什麼檔案呢? 當登入 Linux ,亦即是取得 login shell 時,會讀取 ~/.bash_profile, ~/.bash_login, ~/.profile, 這三個檔案的優先順序已經在上面提過,自行參考一下。至於在取得 login shell 後繼續動作的其他 non-login shell ,讀取的就是僅有 ~/.bashrc 囉~。而大部分的 linux distributions 都會將 ~/.bash_profile 的內容指到 ~/.bashrc 去,這樣比較簡單囉~