Chinaunix首页 | 论坛 | 博客
  • 博客访问: 495814
  • 博文数量: 78
  • 博客积分: 1771
  • 博客等级: 上尉
  • 技术积分: 944
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-25 10:20
文章分类

全部博文(78)

文章存档

2014年(2)

2013年(10)

2012年(9)

2011年(7)

2010年(11)

2009年(10)

2008年(12)

2007年(17)

我的朋友

分类:

2007-04-27 17:58:52

其他所有的變數說明: set
而除了這些環境變數之外,還有沒有什麼重要的變數呢?當然有啊! 我們在 bash 的環境下,其實還有一些挺重要的變數,這些變數是『在這個 shell 環境下有效』的, 如果是在『子程序』,這些變數值就不會相同了。 那麼如何觀察目前 shell 環境下的所有變數呢?很簡單啊,就用 set 即可!set 這個指令除了會將環境變數列出來之外,其他我們的自訂變數,與所有的變數,都會被列出來喔!資訊多好多。 底下僅列出幾個重要的內容。
[root@linux ~]# set
BASH=/bin/bash           <== bash 的主程式放置路徑
BASH_VERSINFO=([0]="3" [1]="00" [2]="16" [3]="1" [4]="release"
[5]="i386-redhat-linux-gnu")      <== bash 的版本啊!
BASH_VERSION='3.00.16(1)-release' <== bash 的版本啊!
COLORS=/etc/DIR_COLORS.xterm      <== 使用的顏色紀錄檔案
COLUMNS=115              <== 在目前的終端機環境下,使用的欄位有幾個字元長度
HISTFILE=/root/.bash_history      <== 歷史命令記錄的放置檔案,隱藏檔
HISTFILESIZE=1000        <== 存起來(與上個變數有關)的檔案之指令的最大紀錄筆數。
HISTSIZE=1000            <== 目前環境下,可記錄的歷史命令最大筆數。
HOSTTYPE=i386            <== 主機安裝的軟體主要類型。我們用的是 i386 相容機器軟體
IFS=$' \t\n'             <== 預設的分隔符號
LINES=35                 <== 目前的終端機下的最大行數
MACHTYPE=i386-redhat-linux-gnu    <== 安裝的機器類型
MAILCHECK=60             <== 與郵件有關。每 60 秒去掃瞄一次信箱有無新信!
OLDPWD=/home             <== 上個工作目錄。我們可以用 cd - 來取用這個變數。
OSTYPE=linux-gnu         <== 作業系統的類型!
PPID=20046               <== 父程序的 PID (會在後續章節才介紹)
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:${PWD/#$HOME/~}\007"'
                         <== 上面這個是命令提示字元!與底下也有關。
PS1='[\u@\h \W]\$ '      <== PS1 就厲害了。這個是命令提示字元,也就是我們常見的
                             [root@linux ~]# 或 [dmtsai ~]$ 的設定值啦!可以更動的!
RANDOM=13586             <== 亂數啊!上面已經提過囉~
SUPPORTED=zh_TW.UTF-8:zh_TW:zh:en_US.UTF-8 <== 本系統所支援的語系
name=VBird               <== 剛剛設定的自訂變數也可以被列出來喔!
$                        <== 目前這個 shell 所使用的 PID
?                        <== 剛剛執行完指令的回傳值。

一般來說,不論是否為環境變數,只要跟我們目前這個 shell 的操作介面有關的變數, 通常都會被設定為大寫字元,也就是說,『基本上,在 Linux 預設的情況中,使用{大寫的字母}來設定的變數一般為系統內定需要的變數』。
使用 set 除了會將系統的預設值秀出來之外,連帶的所有的你自己設定的變數也會被秀出來! 同時需要注意的是,若當時有相當多人同時在線上的話,那麼 你的變數只能給自己使用 ( 除非改的是系統的預設參數檔,如 /etc/profile ),而不會干擾到別人的!就如同前面所說的, 由於你登入 Linux 之後會取得一個 PID ,而你的設定將只對這個 PID 與子程序有關!此外, 這次登入所進行的變數設定,如果沒有更動到設定檔, 那麼這次設定的變數在下次登入時將被取消掉 ( 因為程序 PID 不見囉! ) !所以囉, 如果你想要你的變數每次都能在你登入的時候自動就設定好了,那麼就必須將你的設定寫入登入時載入的設定檔! ( 更多的程序相關的說明,不要急~我們會在後面的 程序與資源管理 當中好好的提一提的! )
OK!OK!那麼上頭那些變數當中,有哪些是比較重要的?大概有這幾個吧!
PS1:(提示字元的設定)
這是 PS1 (數字的 1 不是英文字母!),這個東西就是我們的『命令提示字元』啊! 當我們每次按下 [Enter] 按鍵去執行某個指令後,最後要再次出現提示字元時, 就會主動去讀取這個變數值了。上頭 PS1 內顯示的是一些特殊符號,每個版本 bash 的 PSI 變數內的特殊符號可能有些許的差異, 你應該主動的以 man bash 去查詢一下相關的變數。底下我列出 FC4 的環境下, 預設的 bash 的 PS1 變數內的特殊符號代表意義:

\d :代表日期,格式為 Weekday Month Date,例如 "Mon Aug 1"
\H :完整的主機名稱。舉例來說,鳥哥的練習機 linux.dmtsai.tw ,那麼這個主機名稱就是 linux.dmtsai.tw
\h :僅取主機名稱的第一個名字。以上述來講,就是 linux 而已, .dmtsai.tw 被省略。
\t :顯示時間,為 24 小時格式,如: HH:MM:SS
\T :顯示時間,12 小時的時間格式!
\A :顯示時間,24 小時格式, HH:MM
\u :目前使用者的帳號名稱;
\v :BASH 的版本資訊;
\w :完整的工作目錄名稱。家目錄會以 ~ 取代;
\W :利用 basename 取得工作目錄名稱,所以僅會列出最後一個目錄名。
\# :下達的第幾個指令。
\$ :提示字元,如果是 root 時,提示字元為 # ,否則就是 $ 囉~
OK!所以,由預設的 PS1 內容為: '\[\u@\h \W\]\$ ' 就可以瞭解為何我們的提示字元會是: [root@linux ~]# 了吧!好了,那麼假設我想要有類似底下的提示字元:
[root@linux /home/dmtsai 16:50 #12]#
,那個 # 代表第 12 次下達的指令。 那麼應該如何設定 PS1 呢?可以這樣啊:
[root@linux home]# PS1='[\u@\h \w \A #\#]\$ '
[root@linux /home 17:02 #85]#
# 看到了嗎?提示字元變了!變的很有趣吧!其中,那個 #85 比較有趣,
# 如果您按下 [Enter] 後,該數字就會增加喔!為啥?上面有說明ㄇㄟ!
 

$:(關於本 shell 的 PID)
其實這個咚咚代表的是『目前這個 Shell 的執行緒代號』,亦即是所謂的 PID (Process ID)。 更多的程序觀念,我們會在第四章的時候提及。想要知道我們的 shell 的 PID ,就可以: echo $$ 即可!
?:(關於上個執行指令的回傳碼)
蝦密?問號也是一個特殊的變數?沒錯!在 bash 裡面這個變數可重要的很! 這個變數是:『上個執行的指令所回傳的值』, 上面這句話的重點是『上一個指令』與『回傳值』兩個地方。當我們執行某些指令時, 這些指令都會回傳一個執行後的代碼。一般來說,如果成功的執行該指令, 則會回傳一個 0 值,如果執行過程發生錯誤,就會回傳『錯誤代碼』才對!一般就是以非為 0 的數值來取代。 我們以底下的例子來看看:
[root@linux ~]# echo $SHELL
/bin/bash
[root@linux ~]# echo $?
0
# 因為上個指令執行過程中,並沒有錯誤,為成功的執行完畢,所以回傳 0 。
[root@linux ~]# 12name=VBird
-bash: 12name=VBird: command not found
[root@linux ~]# echo $?
127
# 發生錯誤啦!所以 echo $? 時,就會出現錯誤的代碼!
# 我們可以利用這個代碼來搜尋錯誤的原因喔!
[root@linux ~]# echo $?
0
# 咦!怎麼又變成正確了?這是因為 "?" 只與『上一個執行指令』有關,
# 所以,我們上一個指令是執行『 echo $? 』,當然沒有錯誤,所以是 0 沒錯!
 

OSTYPE, HOSTTYPE, MACHTYPE:(主機硬體與核心的等級)
這幾個東西與程式的安裝有關。我們在『Linux 主機規劃』 裡面提到過關於主機的等級方面的問題,當我們在安裝軟體的時候, 需要透過編譯器來將原始碼編譯成為二進位的檔案 (binary file)。但是, 我們可以針對硬體的配備來進行編譯的最佳化,此時,這些參數就可以被用到了! 基本上,目前主要的 distribution 都是針對 i386 亦即最低等級的機器進行最佳化, 這樣才能夠安裝在較高階的機器上,如果以 686 的機型來最佳化, 那麼,可就無法向下相容的喔!(早期的 OpenLinux 是針對 686 機器來釋出軟體, 所以,當時的 OpenLinux 是無法安裝在 P-166 的機器上的。 )
--------------------------------------------------------------------------------
自訂變數轉成環境變數: export
好了,上面我們環境變數也提過了,一些自訂變數也提過了,那麼,這兩者有啥不同? 他的不同處,我們在 變數設定規則 當中稍微提過, 主要是由於變數可否被子程序所引用。
當你取得一個 bash 之後,亦即得到了一個程序了,但是若你再次的執行一次 bash ,那麼你將進入『子程序』,這個程序的概念我們在資源管理章節中再詳談,這裡您先有個概念即可。 那麼由於您已經進入了該子程序,所以在父程序中的自訂變數設定將不再繼續的存在。 會存在子程序中的,僅有『環境變數』。
換個角度來想,也就是說,如果我能將自訂變數變成環境變數的話,那不就可以讓該變數值繼續存在於子程序了? 呵呵!沒錯!此時,那個 export 指令就很有用啦! 如您想要讓該變數內容繼續的在子程序中使用,那麼就請執行:
export 變數
這個東西用在『引用他人的檔案或者其他程序』時,相當的重要的! 尤其像鳥哥常常兩三個檔案互相引用來引用去的,如果忘記設定 export 的話,那麼不同的檔案中的相同變數值,將需要一再地重複設定才行!所以,我只要在頭一個檔案使用 export 的話,那麼後續的檔案引用時,將會把該變數內容讀進來!好用的很,如果僅下達 export 而沒有接變數時,那麼此時將會把所有的『環境變數』秀出來喔!例如:
[root@linux ~]# export
declare -x ENV="/root/.bashrc"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="linux.dmtsai.tw"
declare -x INPUTRC="/etc/inputrc"
declare -x LANG="en_US.UTF-8"
declare -x MAIL="/var/spool/mail/root"
declare -x SHELL="/bin/bash"
# 很多都直接省略了!不然....重複性太高,浪費版面~ ^_^
 

--------------------------------------------------------------------------------
語系檔案的變數 (locale)
還記得我們在首次進入 Linux 那個章節裡面提到的,關於語系編碼的問題嗎? 就是當我們使用 man command 的方式去查詢某個資料的說明檔時,該說明檔的內容可能會因為我們使用的語系, 而產生一些亂碼。另外,利用 ls 查詢檔案的時間時,也可能會有亂碼出現在時間的部分。 那個問題其實就是語系的問題啦。
目前大多數的 Linux distributions 已經都是支援萬國碼,此外,也都支援大部分的語言語系了。 這有賴於 i18n 支援的幫助呢! 那麼我們的 Linux 到底支援了多少的語系呢?這可以由 locale 這個指令來查詢到喔!
[root@linux ~]# locale -a
aa_DJ
aa_DJ.iso88591
en_US
en_US.iso88591
en_US.iso885915
en_US.utf8
zh_TW
zh_TW.big5
zh_TW.euctw
zh_TW.utf8
# 其實輸出的內容有很多,鳥哥將一些資訊捨棄了~
# 從上面的輸出中,我們也不難看出,系統是有支援 big5, utf8 等中文語系資料的!

中文語系至少支援了兩種以上的編碼,一種是目前還是很常見的 big5 ,另一種則是越來越熱門的 utf-8 編碼。 那麼我們如何修訂這些編碼呢?其實可以透過底下這些變數的說:
[root@linux ~]# LANG         <==主語言的環境
[root@linux ~]# LC_CTYPE     <==字元辨識的編碼
[root@linux ~]# LC_NUMERIC   <==數字系統的顯示訊息
[root@linux ~]# LC_TIME      <==時間系統的顯示資料
[root@linux ~]# LC_COLLATE   <==字串的比較與排序等
[root@linux ~]# LC_MONETARY  <==幣值格式的顯示等
[root@linux ~]# LC_MESSAGES  <==訊息顯示的內容,如功能表、錯誤訊息等
[root@linux ~]# LC_ALL       <==語言環境的整體設定。

基本上,你可以逐一設定每個與語系有關的變數資料,但事實上,如果其他的語系變數都未設定, 且您有設定 LANG 或者是 LC_ALL 時,則其他的語系變數就會被這兩個變數所取代! 這也是為什麼我們在 FC4 當中,通常僅設定 LANG 這個變數而已!因為他是最主要的設定變數。 好了,那麼你應該要覺得奇怪的是,為什麼在 Linux 主機的終端機介面 (tty1 ~ tty6) 的環境下,如果 LANG=zh_TW.big5 這個設定值生效後,使用 man 或者其他訊息輸出時, 都會有一堆亂碼,尤其是使用 ls -l 這個參數時?
因為在 Linux 主機的終端機介面下,那個環境是無法顯示像中文這麼複雜的編碼的文字, 所以,就會產生亂碼了。也就是如此,所以,我們才會必須要在 tty1 ~ tty6 的環境下, 加裝一些中文化介面的軟體,才能夠看到中文啊!不過,如果您是在 Windows 主機以遠端連線伺服器的軟體連線到主機的話,那麼,嘿嘿!其實文字介面確實是可以看到中文的。 所以,此時反而您得要在 LANG 設定中文編碼才好呢!
無論如何,如果發生一些亂碼的問題,那麼設定系統裡面保有的語系編碼, 例如: en_US 或 en_US.utf8 等等的設定,應該就 OK 的啦!好了,那麼系統預設支援多少種語系呢? 當我們使用 locale 時,系統是列出目前 Linux 主機內保有的語系檔案, 這些語系檔案都放置在: /usr/lib/locale/ 這個目錄中。 但是,目前的這個 shell 環境所支援的語系,則是要看 SUPPORTED 這個變數才對喔!
那麼,如果我想要修訂系統的語系支援呢?可以修訂 /etc/sysconfig/i18n 這個檔案呢! 這個檔案的內容有點像這樣:
[root@linux ~]# vi /etc/sysconfig/i18n
LANG="en_US.UTF-8"
SYSFONT="latarcyrheb-sun16"
SUPPORTED="zh_TW.UTF-8:zh_TW:zh:en_US.UTF-8"

你可以在這個檔案當中加入 LC_TIME 或者其他語系相關變數的設定內容, 也可以直接修改 LANG 那個變數即可啊! ^_^ 但,事實上,我們還可以透過個人的環境設定檔來設定 LANG 呢! 如此一來,則不必修訂系統的語系檔案,比較安全啦!
Tips:
假設你用 vi 編輯一個純文字檔,這個純文字檔在編輯的時候,是在 Windows 上面編輯的, 那麼這個檔案的預設編碼應該是以 zh_TW.big5 所編輯的才對。但是,如果你的 shell 環境中, 卻是使用 LANG=en_US 時,則當你編輯該檔案時,就可能會看到『亂碼』, 或者輸入的中文可能會變成『亂碼』了。此時,只要你離開 vi ,然後執行 LANG=zh_TW.big5 , 然後再重新以 vi 編輯該檔案,呵呵!應該就能夠看到中文啦!但是請注意, 這個方法當然不適用 tty1 ~ tty6 的環境,原因上面已經提過囉~ 僅適合以類似 putty 軟體由 Windows 電腦連線到 linux 主機上的做業!  

--------------------------------------------------------------------------------
變數的有效範圍
蝦密??變數也有使用的『範圍』?沒錯啊~我們在上頭的 export 指令說明中,就提到了這個概念了。如果在跑程式的時候,有父程序與子程序的不同程序關係時, 則『變數』可否被引用是 export 有關。被 export 後的變數,我們可以稱他為『環境變數』! 環境變數可以被子程序所引用,但是其他的自訂變數內容就不會存在於子程序中。也就是說: 我們自行設定的變數,只在目前這個 shell 環境當中存在, 在子程序中將不會存在此一變數。除非使用 export 將自訂變數變成環境變數。
其實除了 shell 的父、子程序外,在腳本( scripts )的編寫當中,由於有的軟體會使用到 2 個以上的 scripts 做為一個完整的套件!也就是說,假如你有兩支程式,一支為 scripts1.sh 以及 scripts2.sh ,而 scripts2.sh 會去引用 scripts1.sh 的變數,這個時候,嘿嘿!你在 scripts1.sh 當中設定的變數請『千萬記得以 export 設定』, 否則你的變數將無法在兩個 scripts 之間互相被引用喔!當這個 scripts 執行完畢之後,剛剛在 scripts 當中設定的變數也就『失效了!』。
其實,要瞭解不同程序之間變數的變換,應該要先瞭解『程序』的概念比較好, 但是我們還沒有講到.....沒關係~等你念到程序章節後,還可以再回來好好的看一看。 基本上,環境變數可以讓子程序繼續引用的原因,是因為:
當啟動一個 shell ,作業系統分配一記憶區塊給 shell 使用,此區域之變數可以讓子程序存取;
利用 export 功能,可以讓變數的內容寫到上述的記憶區塊當中(環境變數);
當載入另一個 shell 時 (亦即啟動子程序,而離開原本的父程序了),子 shell 可以將父 shell 的環境變數所在的記憶區塊導入自己的環境變數區塊當中。
透過這樣的關係,我們就可以讓某些變數可以在相關的程序之間存在,以幫助自己更方便的操作環境喔!

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

--------------------------------------------------------------------------------
read
要讀取來自鍵盤輸入的變數,就是用 read 這個指令了。這個指令最常被用在 shell script 的撰寫當中, 以跟使用者進行對談。關於 script 的寫法,我們會在後面章節介紹,底下先來瞧一瞧 read 的相關語法吧!
[root@linux ~]# read [-pt] variable
參數:
-p  :後面可以接提示字元!
-t  :後面可以接等待的『秒數!』這個比較有趣~不會一直等待使用者啦!
範例:
範例一:讓使用者由鍵盤輸入一內容,將該內容變成 atest 變數
[root@linux ~]# read atest
This is a test
[root@linux ~]# echo $atest
This is a test
範例二:提示使用者 30 秒內輸入自己的大名,將該輸入字串做成 named 變數
[root@linux ~]# read -p "Please keyin your name: " -t 30 named
Please keyin your name: VBird Tsai
[root@linux ~]# echo $named
VBird Tsai

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

上一篇:Bash学习(二)

下一篇:Bash学习(四)

给主人留下些什么吧!~~