一、什麼是shell
到底什麼是shell呢?我相信,這個問題,應該困擾過很多人吧?那麼今天,我們就來好好捋一下這個概念。
首先,從英文單詞上來理解,是“殼”的意思,用於區別“核”的概念,有“殼”保護“核”的涵義;這就好比“雞蛋殼”與“雞蛋黃”。然後我們再從計算機的角度來理解一下,計算機由一組硬件組成,,而內核(kernel)是用來管理和操縱這些硬件讓其工作的。那麼內核總不能讓用戶隨意操作吧!對於公司來說,總會有菜鳥入職的,讓他們隨意操作內核,很容易造成系統崩潰。๑乛◡乛๑
因此,在內核之上又開發了一層應用程序。用戶可以通過這樣的應用程序來指揮內核,讓內核管理相應的硬件來完成我們的任務。這樣可以與內核進行直接交互的程序,我們就可以稱之爲shell。
Linux系統上的shell,實際上就是用戶與Linux系統內核之間的接口程序,一種交互性命令解釋器。用戶在提示符界面輸入的每一個命令,都要經由shell這個解釋器來解釋,然後傳給內核,內核再繼續往下工作。同樣shell也能接收內核的輸出信息,展示給用戶。shell獨立於操作系統,這種設計讓用戶可以靈活選擇適合自己的shell。
Linux系統下存在多個shell,可以查看 /etc/shells文件來知曉系統內安裝的shell,不過,最常用的shell還是/bin/bash。這個也是系統默認使用的shell。
[michael@master ~]$ cat /etc/shells
/bin/sh <==Bourne Shell,已經被Bourne Again Shell取代
/bin/bash <==Bourne Again Shell,系統默認使用的shell,兼容了Bourne Shell,功能更強大
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
既然系統下有多個shell,我們應該有這樣的問題需要思考:用戶什麼時候使用shell?用戶使用的是哪一種shell呢?這兩個問題,其實我們在講解用戶管理時,已經說到過了。還記得登錄驗證的工作流程嗎?當輸入密碼後,會先驗證/etc/passwd文件裏是否有此用戶名,如果有的話,就會讀取uid和gid,再讀取用戶主目錄和要使用的shell,密碼校驗成功後,就會獲得這個shell開始工作了。
二、/bin/bash的簡介
Linux系統下雖然有很多種shell,但是最常用的還是/bin/bash這個shell,同時也是市場上衆多流行Linux版本默認使用的shell。/bin//bash在兼容/bin/sh的所有功能的同時,也有一些自己獨特的功能。甚至可以說成bash已經完全取代了sh。那麼bash都有哪些好用的功能呢,我來介紹一下吧。
1、命令記憶功能
這個功能真是非常的好用呢?因爲bash能記住我們輸入過的命令,因此,我們就可以通過“上、下鍵”來找到前一個或者是後一個命令。而bash記住命令的數量多達1000個,可以理解成你輸入的命令bash幾乎全都記錄了下來。
這些命令暫時保存在內存中,當你成功註銷當前用戶時,這些命令就會存在主目錄下的.bash_history文件中。
2、命令和文件名補全功能
正因爲有了這個功能,用戶少打了很多字母,同時也提高了書寫的正確率,進而提高了工作效率。
在命令行的相應位置上,按兩下Tab鍵,會有不同的效果,
第一個詞後連按兩下Tab鍵,是對命令進行查看或者補全
第二個詞後連按兩下Tab鍵,是對文件名進行查看或補全
3、命令別名設置功能
某些命令串或許經常使用,你是否因這些命令串的字符比較多而鬧心呢?我相信應該是有的。bash中提供了別名的設置,這樣就方便了用戶對命令的使用。在bash下,通過alias對命令串進行起別名,然後我們使用別名就相當於使用命令串。
如 'ls -al'這樣的命令串,當alias lm='ls -al'後,我們使用lm就相當於使用了 'ls -al'了,特別方便。
4、作業控制、前臺、後臺切換功能
我們可以將前臺正在執行的任務,切換到後臺運行,然後前臺再開啓一個新的任務,這樣就可以達到一個窗口多任務的目的。
5、通配符功能
在bash中,也支持*這樣的通配符,可以讓用戶更方便的來進行作業。如:ls ~/c*,表示查看主目錄下c開頭的文件。
6、編程語言功能
bash這個shell,本身就是一個編程語言,這個應該是bash中最強大的功能了。它支持多種編程語言裏常見的特徵,比如分支和循環結構,函數,變量和數組等。並且一旦掌握後它將成爲你的得力工具。只要能在提示符界面上輸入的命令都能放到一個可執行的shell程序裏,這意味着用shell語言能簡單地重複執行某一任務。
三、shell中的變量
學過編程語言的人,都應該知道變量的概念及其使用變量的優勢所在。這裏就不再累述了。我們來學習一下shell中變量的使用規範。
1、變量的命名規則
- 命名只能使用英文字母,數字和下劃線。首個字符不能以數字開頭。
- 字母習慣使用大寫。
- 中間不能有空格。
- 不能使用標點符號。
- 不能使用bash裏的關鍵字(可用help命令查看保留關鍵字)
2、變量的使用規則
- 直接定義變量名稱,沒有類型需要強調(類似於數學中:x=1,y=2,z=x+y)
- 賦值時,"="前後不能有空格
- 命令的執行結果賦值給變量時,使用反單引號 如:TIME=`date`
- 使用變量時,必須使用$ 格式: $變量名 或 ${變量名}
應用案例1:我們藉助echo命令,來讀取變量的值
[michael@master ~]$ MYNAME=kitty <==定義變量MYNAME,同時賦值kitty
[michael@master ~]$ echo $MYNAME <==藉助echo命令,讀取變量的值
kitty
[michael@master ~]$ echo $YOURNAME
<==爲空,因爲YOURNAME這個變量尚未定義。
[michael@master ~]$ ADDR=長春;echo $ADDR <==一個命令行中,使用分號(;)隔開
長春
應用案例2:變量多次賦值
[michael@master ~]$ ADDR="上海"
[michael@master ~]$ echo $ADDR
上海
[michael@master ~]$ ADDR='北京'
[michael@master ~]$ echo $ADDR
北京
3、只讀變量和刪除變量
使用readonly 可以將變量設置成只讀形式,這樣的變量就不可以再次被賦值了,從而防止變量的值被不經意的修改。
[michael@master ~]$ MYNAME=kitty
[michael@master ~]$ echo $MYNAME
kitty
[michael@master ~]$ readonly MYNAME
[michael@master ~]$ MYNAME=world
bash: MYNAME: readonly variable
使用unset 就可以將變量進行刪除。注意,不能刪除只讀變量
[michael@master ~]$ ADDR='北京'
[michael@master ~]$ echo $ADDR
北京
[michael@master ~]$ unset ADDR
[michael@master ~]$ echo $ADDR
<==此時,變量ADDR就被刪除了,所以爲空
[michael@master ~]$
附加:一組快捷鍵
組合鍵 | 功能 |
---|---|
ctrl+u / ctrl+k | 刪除光標前所有的字符 /刪除光標後所有的字符 |
ctrl+a / ctrl+e | 讓光標移動到命令串的最前端 /讓光標移動到命令串的最後端 |
4、環境變量
環境變量,可以讓我們更方便的在系統上作業,提高我們的工作效率。那麼如何查看Linux系統下的環境變量呢?我們可以通過env和export這兩個指令來查詢系統上默認的環境變量:
[hyxy@master ~]$ env
HOSTNAME=master <== 主機名稱
SHELL=/bin/bash <== shell的種類
TERM=xterm <== 終端使用的環境
HISTSIZE=1000<==記錄指令的條數
...........................
USER=hyxy <== 用戶名
............................
USERNAME=hyxy
PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/hyxy/bin <==path環境變量
MAIL=/var/spool/mail/hyxy <== 用戶使用的mailbox位置
PWD=/home/hyxy <== 當前用戶的主目錄
LANG=zh_CN.UTF-8 <== 語言
GDM_LANG=zh_CN.UTF-8
HOME=/home/hyxy <== 主目錄
LOGNAME=hyxy <== 登錄名稱
OLDPWD=/home/hyxy/桌面
_=/usr/bin/env <== 剛剛執行完的指令的返回值
export命令下的顯示,我就不給大家看了,你們自行測試吧。
還有另外一個命令set,這個命令會將當前shell的所有變量都顯示出來,包含環境變量、接口變量及其用戶自定義的變量。在這裏我不做顯示了,僅僅介紹幾個有意思的變量
PS1 :命令提示字符變量。當我們每次回車執行某一個命令後,最後還是要顯示命令提示字符的,這個時候就會讀取變量PS1,然後按照設置的格式進行顯示。我們來看看系統默認的PS1的值:PS1='[\u@\h \W]\$ '。按照這個格式,就顯示如下:
[hyxy@master ~]$ <==這玩意就是命令提示字符
常用的格式字符有:
\u :當前用戶的賬號名稱,如:hyxy
\h :主機名全稱的第一個單詞,單詞以點(.)作爲分隔符
\H :主機名全稱
\w:完整的工作目錄名稱,以絕對路徑的形式顯示,不過主目錄會以~的形式顯示
\W:只顯示最後一個目錄名稱
\d:時間顯示,按照【星期 月 日】的日期格式顯示,如“六 12月 29”
\A:時間顯示,按照24小時制的【HH:MM】顯示
\@:時間顯示,按照12小時制的【am/pm】顯示 如"11:43 上午"
\#:當前窗口下達的第幾個命令
\$:提示符,root用戶顯示 #,其他用戶顯示$
應用案例1:
[hyxy@master ~]$ PS1='[\u@\h \w \@ #\#]\$ '
[hyxy@master ~ 11:47 上午 #24]$ <==24是指第24個指令
應用案例2:
[hyxy@master sysconfig]$ PS1='[\u@\h \w \A]\$ '
[hyxy@master /ect/sysconfig 11:53]$
$變量:也是一個變量。返回當前進程的PID
[hyxy@master ~]$ echo $$
2857
?變量:返回上一個命令的退出狀態。 0表示成功退出。1~255,表示退出出現錯誤。
[hyxy@master ~]$ nihao
bash: nihao: command not found
[hyxy@master ~]$ echo $?
127 <==錯誤代碼 127
[hyxy@master ~]$ find -name
find: 遺漏“-name”的參數
[hyxy@master ~]$ echo $?
1 <==錯誤代碼 1
5、環境變量與自定義變量的區別
使用了env和set兩個指令後,你們應該知道什麼是環境變量和自定義變量了吧。那麼環境變量和自定義變量到底有什麼差別呢?其實差別就在於是否可以被子程序能繼續使用?
那麼什麼是父程序和子程序呢?
當我們使用命令界面進行登錄後,就會獲取對應的bash進行工作。這個bash是獨立的程序,我們在這個bash下,可以使用任意命令進行其他任務,而每個命令就是一個程序,這些程序都是由bash這個獨立的程序啓動的。bash就是父程序,命令程序就是子程序。比如我們在bash程序中,再次輸入bash這個命令,就會開啓一個新的子程序。
[hyxy@master ~]$ ADDR='上海'
[hyxy@master ~]$ echo $ADDR
上海 <==當前程序中,可以使用自定義變量,有輸出
[hyxy@master ~]$ bash <==使用bash 開啓一個新的子程序
[hyxy@master ~]$ echo $ADDR
<==子程序中,自定義變量失效
[hyxy@master ~]$
如何將自定義變量轉成環境變量呢?那就是export命令的工作了。很簡單,只需要使用export命令來導出,輸出自定義變量
格式:export 變量名
[hyxy@master ~]$ echo $$
4300 <==當前進程的PID
[hyxy@master ~]$ ADDR='長春'
[hyxy@master ~]$ echo $ADDR
長春
[hyxy@master ~]$ export ADDR <==轉成環境變量
[hyxy@master ~]$ bash <==開啓一個子程序
[hyxy@master ~]$ echo $$
4341 <==子程序的的PID
[hyxy@master ~]$ echo $ADDR
長春 <==有輸出
[hyxy@master ~]$ bash <==再開啓一個子程序
[hyxy@master ~]$ echo $$
4354 <==另外一個子程序的的PID
[hyxy@master ~]$ echo $ADDR
長春 <==有輸出
6、read命令
在這之前,變量的值都是直接被指定的。而read命令,可以讓變量接收鍵盤錄入的數據。這就好比Java語言的Scanner類型,可以開啓鍵盤錄入功能。read功能常用與shell script中。
格式:[hyxy@master ~]$ read [選項] variable
常用選項介紹:
- -p:用於指定提示信息
- -n:規定錄入字符串長度,達到此長度,自動結束
- -t :對錄入進行時間限制,後面是秒數
- -s:隱藏輸入的數據
應用案例1
[hyxy@master ~]$ read -p "請輸入用戶名:" username
請輸入用戶名:hyxy
[hyxy@master ~]$ echo $username
hyxy
應用案例2
[hyxy@master ~]$ read -p "請輸入密碼:" -s pass
請輸入密碼:
[hyxy@master ~]$ echo $pass
1234
-------------------------------------------------------如有疑問,留言必答---------------------------------------------------