《Linux系統》之"深入淺出"(三)shell概述

一、什麼是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

-------------------------------------------------------如有疑問,留言必答---------------------------------------------------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章