在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Linux/ layout: book-zh title: 自定制 shell 提示符
網(wǎng)絡系統(tǒng)
打印
重定向
使用命令
位置參數(shù)
權(quán)限
文本處理
疑難排解
layout: book-zh title: 自定制 shell 提示符
查找文件
layout: book-zh title: vi 簡介
shell 環(huán)境
什么是 shell
編譯程序
鍵盤高級操作技巧
流程控制:case 分支
流程控制:if 分支結(jié)構(gòu)
layout: book-zh title: 軟件包管理
進程
存儲媒介
格式化輸出
編寫第一個 Shell 腳本
啟動一個項目
流程控制:while/until 循環(huán)
文件系統(tǒng)中跳轉(zhuǎn)
字符串和數(shù)字
讀取鍵盤輸入
歸檔和備份
探究操作系統(tǒng)
流程控制:for 循環(huán)
自頂向下設計
數(shù)組
操作文件和目錄
奇珍異寶
從 shell 眼中看世界
正則表達式

layout: book-zh title: 自定制 shell 提示符


layout: book-zh title: 自定制 shell 提示符

在這一章中,我們將會看一下表面上看來很瑣碎的細節(jié)-shell 提示符。但這會揭示一些內(nèi)部 shell 和 終端仿真器的工作方式。

和 Linux 內(nèi)的許多程序一樣,shell 提示符是可高度配置的,雖然我們把它相當多地看作是理所當然的, 但是我們一旦學會了怎樣控制它,shell 提示符是一個真正有用的設備。

解剖一個提示符

我們默認的提示符看起來像這樣:

[me@linuxbox ~]$

注意它包含我們的用戶名,主機名和當前工作目錄,但是它又是怎樣得到這些東西的呢? 結(jié)果證明非常簡單。提示符是由一個環(huán)境變量定義的,叫做 PS1(是“prompt string one” 的簡寫)。我們可以通過 echo 命令來查看 PS1的內(nèi)容。

[me@linuxbox ~]$ echo $PS1
[\u@\h \W]\$

注意:如果你 shell 提示符的內(nèi)容和上例不是一模一樣,也不必擔心。每個 Linux 發(fā)行版 定義的提示符稍微有點不同,其中一些相當異乎尋常。


從輸出結(jié)果中,我們看到那個 PS1 環(huán)境變量包含一些這樣的字符,比方說中括號,@符號,和美元符號, 但是剩余部分就是個謎。我們中一些機敏的人會把這些看作是由反斜杠轉(zhuǎn)義的特殊字符,就像我們 在第八章中看到的一樣。這里是一部分字符列表,在提示符中 shell 會特殊對待這些字符:

表14-1: Shell 提示符中用到的轉(zhuǎn)義字符
序列 顯示值
\a 以 ASCII 格式編碼的鈴聲 . 當遇到這個轉(zhuǎn)義序列時,計算機會發(fā)出嗡嗡的響聲。
\d 以日,月,天格式來表示當前日期。例如,“Mon May 26.”
\h 本地機的主機名,但不帶末尾的域名。
\H 完整的主機名。
\j 運行在當前 shell 會話中的工作數(shù)。
\l 當前終端設備名。
\n 一個換行符。
\r 一個回車符。
\s shell 程序名。
\t 以24小時制,hours:minutes:seconds 的格式表示當前時間.
\T 以12小時制表示當前時間。
\@ 以12小時制,AM/PM 格式來表示當前時間。
\A 以24小時制,hours:minutes 格式表示當前時間。
\u 當前用戶名。
\v shell 程序的版本號。
\V Version and release numbers of the shell.
\w 當前工作目錄名。
\W 當前工作目錄名的最后部分。
\! 當前命令的歷史號。
\# 當前 shell 會話中的命令數(shù)。
\$ 這會顯示一個"$"字符,除非你擁有超級用戶權(quán)限。在那種情況下, 它會顯示一個"#"字符。
\[ 標志著一系列一個或多個非打印字符的開始。這被用來嵌入非打印 的控制字符,這些字符以某種方式來操作終端仿真器,比方說移動光標或者是更改文本顏色。
\] 標志著非打印字符序列結(jié)束。

試試一些可替代的提示符設計

參照這個特殊字符列表,我們可以更改提示符來看一下效果。首先, 我們把原來提示符字符串的內(nèi)容備份一下,以備之后恢復原貌。為了完成備份, 我們把已有的字符串復制到另一個 shell 變量中,這個變量是我們自己創(chuàng)造的。

[me@linuxbox ~]$ ps1_old="$PS1"

我們新創(chuàng)建了一個叫做 ps1_old 的變量,并把變量 PS1的值賦 ps1_old。通過 echo 命令可以證明 我們的確復制了 PS1的值。

[me@linuxbox ~]$ echo $ps1_old
[\u@\h \W]\$

在終端會話中,我們能在任一時間復原提示符,只要簡單地反向操作就可以了。

[me@linuxbox ~]$ PS1="$ps1_old"

現(xiàn)在,我們準備開始,讓我們看看如果有一個空的字符串會發(fā)生什么:

[me@linuxbox ~]$ PS1=

如果我們沒有給提示字符串賦值,那么我們什么也得不到。根本沒有提示字符串!提示符仍然在那里, 但是什么也不顯示,正如我們所要求的那樣。我們將用一個最小的提示符來代替它:

PS1="\$ "

這樣要好一些。至少能看到我們在做什么。注意雙引號中末尾的空格。當提示符顯示的時候, 這個空格把美元符號和光標分離開。

在提示符中添加一個響鈴:

$ PS1="\a\$ "

現(xiàn)在每次提示符顯示的時候,我們應該能聽到嗡嗡聲。這會變得很煩人,但是它可能會 很有用,特別是當一個需要運行很長時間的命令執(zhí)行完后,我們要得到通知。

下一步,讓我們試著創(chuàng)建一個信息豐富的提示符,包含主機名和當天時間的信息。

$ PS1="\A \h \$ "
17:33 linuxbox $

試試其他上表中列出的轉(zhuǎn)義序列,看看你能否想出精彩的新提示符。

添加顏色

大多數(shù)終端仿真器程序支持一定的非打印字符序列來控制,比方說字符屬性(像顏色,黑體和可怕的閃爍) 和光標位置。我們會更深入地討論光標位置,但首先我們要看一下字體顏色。

混亂的終端時代

回溯到終端連接到遠端計算機的時代,有許多競爭的終端品牌,它們各自工作不同。 它們有著不同的鍵盤,以不同的方式來解釋控制信息。Unix 和類 Unix 的系統(tǒng)有兩個 相當復雜的子系統(tǒng)來處理終端控制領域的混亂局面(稱為 termcap 和 terminfo)。如果你 查看一下終端仿真器最底層的屬性設置,可能會找到一個關(guān)于終端仿真器類型的設置。

為了努力使所有的終端都講某種通用語言,美國國家標準委員會(ANSI)制定了 一套標準的字符序列集合來控制視頻終端。原先 DOS 用戶會記得 ANSI.SYS 文件, 這是一個用來使這些編碼解釋生效的文件。

字符顏色是由發(fā)送到終端仿真器的一個嵌入到了要顯示的字符流中的 ANSI 轉(zhuǎn)義編碼來控制的。 這個控制編碼不會“打印”到屏幕上,而是被終端解釋為一個指令。正如我們在上表看到的字符序列, 這個 [ 和 ] 序列被用來封裝這些非打印字符。一個 ANSI 轉(zhuǎn)義編碼以一個八進制033(這個編碼是由 退出按鍵產(chǎn)生的)開頭,其后跟著一個可選的字符屬性,在之后是一個指令。例如,把文本顏色 設為正常(attribute = 0),黑色文本的編碼如下:

\033[0;30m

這里是一個可用的文本顏色列表。注意這些顏色被分為兩組,由應用程序粗體字符屬性(1) 分化開來,這個屬性可以描繪出“淺”色文本。

表14-2: 用轉(zhuǎn)義序列來設置文本顏色
序列 文本顏色 序列 文本顏色
\033[0;30m 黑色 \033[1;30m 深灰色
\033[0;31m 紅色 \033[1;31m 淺紅色
\033[0;32m 綠色 \033[1;32m 淺綠色
\033[0;33m 棕色 \033[1;33m 黃色
\033[0;34m 藍色 \033[1;34m 淺藍色
\033[0;35m 粉紅 \033[1;35m 淺粉色
\033[0;36m 青色 \033[1;36m 淺青色
\033[0;37m 淺灰色 \033[1;37m 白色

讓我們試著制作一個紅色提示符。我們將在開頭加入轉(zhuǎn)義編碼:

<me@linuxbox ~>$ PS1='\[\033[0;31m\]<\u@\h \W>\$'
<me@linuxbox ~>$

我們的提示符生效了,但是注意我們在提示符之后輸入的文本也是紅色的。為了修改這個問題, 我們將添加另一個轉(zhuǎn)義編碼到這個提示符的末尾來告訴終端仿真器恢復到原來的顏色。

<me@linuxbox ~>$ PS1='\[\033[0;31m\]<\u@\h \W>\$\[\033[0m\]'
<me@linuxbox ~>$

這看起來要好些!

也有可能要設置文本的背景顏色,使用下面列出的轉(zhuǎn)義編碼。這個背景顏色不支持黑體屬性。

表14-3: 用轉(zhuǎn)義序列來設置背景顏色
\033[0;40m 藍色 \033[1;44m 黑色
\033[0;41m 紅色 \033[1;45m 粉紅
\033[0;42m 綠色 \033[1;46m 青色
\033[0;43m 棕色 \033[1;47m 淺灰色

我們可以創(chuàng)建一個帶有紅色背景的提示符,只是對第一個轉(zhuǎn)義編碼做個簡單的修改。

<me@linuxbox ~>$ PS1='\[\033[0;41m\]<\u@\h \W>\$\[\033[0m\] '
<me@linuxbox ~>$

試試這些顏色編碼,看看你能定制出怎樣的提示符!


注意:除了正常的 (0) 和黑體 (1) 字符屬性之外,文本也可以具有下劃線 (4),閃爍 (5), 和反向 (7) 屬性。為了擁有好品味,然而,許多終端仿真器拒絕使用這個閃爍屬性。


移動光標

轉(zhuǎn)義編碼也可以用來定位光標。這些編碼被普遍地用來,每次當提示符出現(xiàn)的時候,會在屏幕的不同位置 比如說上面一個角落,顯示一個時鐘或者其它一些信息。這里是一系列用來定位光標的轉(zhuǎn)義編碼:

表14-4: 光標移動轉(zhuǎn)義序列
轉(zhuǎn)義編碼 行動
\033[l;cH 把光標移到第 l 行,第 c 列。
\033[nA 把光標向上移動 n 行。
\033[nB 把光標向下移動 n 行。
\033[nC 把光標向前移動 n 個字符。
\033[nD 把光標向后移動 n 個字符。
\033[2J 清空屏幕,把光標移到左上角(第零行,第零列)。
\033[K 清空從光標位置到當前行末的內(nèi)容。
\033[s 存儲當前光標位置。
\033[u 喚醒之前存儲的光標位置。

使用上面的編碼,我們將構(gòu)建一個提示符,每次當這個提示符出現(xiàn)的時候,會在屏幕的上方畫出一個 包含時鐘(由黃色文本渲染)的紅色長條。提示符的編碼就是這個看起來令人敬畏的字符串:

PS1='\[\033[s\033[0;0H\033[0;41m\033[K\033[1;33m\t\033[0m\033[u\]
<\u@\h \W>\$ '

讓我們分別看一下這個字符串的每一部分所表示的意思:

序列 行動
\[ 開始一個非打印字符序列。其真正的目的是為了讓 bash 能夠正確地計算提示符的大小。如果沒有這個轉(zhuǎn)義字符的話,命令行編輯 功能會弄錯光標的位置。
\033[s 存儲光標位置。這個用來使光標能回到原來提示符的位置, 當長條和時鐘顯示到屏幕上方之后。當心一些 終端仿真器不推崇這個編碼。
\033[0;0H 把光標移到屏幕左上角,也就是第零行,第零列的位置。
\033[0;41m 把背景設置為紅色。
\033[K 清空從當前光標位置到行末的內(nèi)容。因為現(xiàn)在 背景顏色是紅色,則被清空行背景成為紅色,以此來創(chuàng)建長條。注意雖然一直清空到行末, 但是不改變光標位置,它仍然在屏幕左上角。
\033[1;33m 把文本顏色設為黃色。
\t 顯示當前時間。雖然這是一個可“打印”的元素,但我們?nèi)园阉谔崾痉姆谴蛴〔糠郑?因為我們不想 bash 在計算可見提示符的真正大小時包括這個時鐘在內(nèi)。
\033[0m 關(guān)閉顏色設置。這對文本和背景都起作用。
\033[u 恢復到之前保存過的光標位置處。
\] 結(jié)束非打印字符序列。
\$ 提示符字符串。

保存提示符

顯然地,我們不想總是敲入那個怪物,所以我們將要把這個提示符存儲在某個地方。通過把它 添加到我們的.bashrc 文件,可以使這個提示符永久存在。為了達到目的,把下面這兩行添加到.bashrc 文件中。

PS1='\[\033[s\033[0;0H\033[0;41m\033[K\033[1;33m\t\033[0m\033[u\]<\u@\h \W>\$ '
export PS1

總結(jié)歸納

不管你信不信,還有許多事情可以由提示符來完成,涉及到我們在這里沒有論及的 shell 函數(shù)和腳本, 但這是一個好的開始。并不是每個人都會花心思來更改提示符,因為通常默認的提示符就很讓人滿意。 但是對于我們這些喜歡思考的人們來說,shell 卻提供了許多制造瑣碎樂趣的機會。

拓展閱讀