Shell基礎(二)

Shell命令

1. Shell命令基本格式

Shell 命令的基本格式如下:

command [選項] [參數]

[]表示可選的,也就是可有可無。有些命令不寫選項和參數也能執行,有些命令在必要的時候可以附帶選項和參數。

比如:ls 是常用的一個命令,它屬於目錄操作命令,用來列出當前目錄下的文件和文件夾。ls 可以附帶選項,也可以不帶,不帶選項的寫法爲:

[cuining@localhost ~]$ cd demo
[cuining@localhost demo]$ ls
demo.txt

先執行cd demo命令進入demo目錄,這是我在自己的主目錄下創建的文件夾,裏面創建了一個文本文件demo.txt。接着執行 ls 命令,列出了 demo 目錄下的所有文件,並且進行了格式對齊。

  • 使用選項

    ls 命令之後不加選項和參數也能執行,不過只能執行最基本的功能,即顯示當前目錄下的文件名。那麼加入一個選項,會出現什麼結果?如果加一個-l選項,則可以看到顯示的內容明顯增多了。-l是長格式(long list)的意思,也就是顯示文件的詳細信息。

    [cuining@localhost demo]$ ls -l
    總用量 4
    -rw-rw-r--. 1 cuining cuining 17 4月  8 17:56 demo.txt
    

    可以看到,選項的作用是調整命令功能。如果沒有選項,那麼命令只能執行最基本的功能;而一旦有選項,則能執行更多功能,或者顯示更加豐富的數據。

    短格式選項和長格式選項

    Linux 的選項又分爲短格式選項和長格式選項。

    短格式選項是長格式選項的簡寫,用一個減號-和一個字母表示,例如ls -l。長格式選項是完整的英文單詞,用兩個減號--和一個單詞表示,例如ls --all。一般情況下,短格式選項是長格式選項的縮寫,也就是一個短格式選項會有對應的長格式選項。當然也有例外,比如 ls 命令的短格式選項-l就沒有對應的長格式選項,所以具體的命令選項還需要通過幫助手冊來查詢。

  • 使用參數

    參數是命令的操作對象,一般情況下,文件、目錄、用戶和進程等都可以作爲參數被命令操作。但是爲什麼一開始 ls 命令可以省略參數?那是因爲有默認參數。命令一般都需要加入參數,用於指定命令操作的對象是誰。如果可以省略參數,則一般都有默認參數。例如 ls 命令後面如果沒有指定參數的話,默認參數是當前所在位置,所以會顯示當前目錄下的文件名。

    Shell 命令可以同時附帶選項和參數,例如:

    [cuining@localhost ~]$ echo "hello"
    hello
    [cuining@localhost ~]$ echo -n "hello"
    hello[cuining@localhost ~]$
    

    -n是 echo 命令的選項,"hello"是 echo 命令的參數,它們被同時用於 echo 命令。echo 命令用來輸出一個字符串,默認輸出完成後會換行;給它增加-n選項,就不會換行了。

  • 選項附帶的參數

    有些命令的選項後面也可以附帶參數,這些參數用來補全選項,或者調整選項的功能細節。例如,read 命令用來讀取用戶輸入的數據,並把讀取到的數據賦值給一個變量,它通常的用法爲:

    read str
    

    str 爲變量名。如果我們只是想讀取固定長度的字符串,那麼可以給 read 命令增加-n選項。比如讀取一個字符作爲性別的標誌,那麼可以這樣寫:

    read -n 1 sex
    

    1-n選項的參數,sex是 read 命令的參數。-n選項表示讀取固定長度的字符串,那麼它後面必然要跟一個數字用來指明長度,否則選項是不完整的。

2. Shell命令的本質

Shell 命令分爲兩種:

  • Shell 自帶的命令稱爲內置命令,它在 Shell 內部可以通過函數來實現,當 Shell 啓動後,這些命令所對應的代碼(函數體代碼)也被加載到內存中,所以使用內置命令是非常快速的。
  • 更多的命令是外部的應用程序,一個命令就對應一個應用程序。運行外部命令要開啓一個新的進程,所以效率上比內置命令差很多。

用戶輸入一個命令後,Shell 先檢測該命令是不是內置命令,如果是就執行,如果不是就檢測有沒有對應的外部程序:有的話就轉而執行外部程序,執行結束後再回到 Shell;沒有的話就報錯,告訴用戶該命令不存在。

  • 內置命令

    內置命令很少,因爲過多的內置命令會導致 Shell 程序本身體積膨脹,運行 Shell 程序後就會佔用更多的內存。Shell 是一個常駐內存的程序,佔用過多內存會影響其它的程序。只有那些最常用的命令纔有理由成爲內置命令,比如 cd、kill、echo 等;

  • 外部命令

    外部命令可能是令人比較疑惑的,一個外部的應用程序究竟是如何變成一個 Shell 命令的呢?一般而言,應用程序就是一個文件,只不過這個文件是可以執行的。既然是文件,那麼它就有一個名字,並且存放在文件系統中。用戶在 Shell 中輸入一個外部命令後,只是將可執行文件的名字告訴了 Shell,但是並沒有告訴 Shell 去哪裏尋找這個文件。難道 Shell 要遍歷整個文件系統,查看每個目錄嗎?這顯然是不能實現的。爲了解決這個問題,Shell 在啓動文件中增加了一個叫做 PATH 的環境變量,該變量就保存了 Shell 對外部命令的查找路徑,如果在這些路徑下找不到同名的文件,Shell 也不會再去其它路徑下查找了,它就直接報錯。具體什麼是啓動文件不需要太關心,只需要知道 PATH 變量保存了檢索路徑即可。可以通過 echo 命令輸出 PATH 變量的值,看看它保存了哪些檢索路徑:

    [cuining@localhost ~]$ echo $PATH
    /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/cuining/.local/bin:/home/cuining/bin
    

    不同的路徑之間以:分隔。Shell 只會在這幾個固定的路徑中查找外部命令。

總而言之,Shell 內置命令的本質是一個自帶的函數,執行內置命令就是調用這個自帶的函數。因爲函數代碼在 Shell 啓動時已經被加載到內存了,所以內置命令的執行速度很快。而Shell 外部命令的本質是一個應用程序,執行外部命令就是啓動一個新的應用程序。因爲要創建新的進程並加載應用程序的代碼,所以外部命令的執行速度很慢。

3. Shell命令提示符

啓動 Linux 桌面環境自帶的終端模擬包,或者從 Linux 控制檯登錄後,便可以看到 shell 命令提示符。看見命令提示符就意味着可以輸入命令了。命令提示符不是命令的一部分,它只是起到一個提示作用。不同的 Linux 發行版使用的提示符格式大同小異,例如在 CentOS 中,默認的提示符類似下面這樣:

[cuining@localhost ~]$

各個部分的含義如下:

  • []是提示符的分隔符號,沒有特殊含義。
  • cuining表示當前登錄的用戶,我現在使用的是 cuining 用戶登錄。
  • @是分隔符號,沒有特殊含義。
  • localhost表示當前系統的簡寫主機名(完整主機名是 localhost.localdomain)。
  • ~代表用戶當前所在的目錄爲主目錄(home 目錄)。如果用戶當前位於主目錄下的 bin 目錄中,那麼這裏顯示的就是bin
  • $是命令提示符。Linux 用這個符號標識登錄的用戶權限等級:如果是超級用戶(root 用戶),提示符就是#;如果是普通用戶,提示符就是$

總結起來,Linux Shell 默認的命令提示符的格式爲:

[username@host directory]$

或者

[username@host directory]#

Linux 系統是純字符界面,用戶登錄後,要有一個初始登錄的位置,這個初始登錄位置就稱爲用戶的主目錄(home 目錄)。超級用戶的主目錄爲/root/,普通用戶的主目錄爲/home/用戶名/。用戶在自己的主目錄中擁有完整權限。

  • Shell修改命令提示符

    shell通過PS1PS2這兩個環境變量來控制提示符的格式,修改PS1PS2的值就能修改命令提示符的格式。

    • PS1 控制最外層的命令提示符格式。
    • PS2 控制第二層的命令提示符格式。

    在修改 PS1 和 PS2 之前,先用 echo 命令輸出它們的值,看看默認情況下是什麼樣子的:

    [cuining@localhost ~]$ echo $PS1
    [\u@\h \W]\$
    [cuining@localhost ~]$ echo $PS2
    >
    

    Linux使用以\爲前導的特殊字符來表示命令提示符中包含的要素,這使得 PS1 和 PS2 的格式看起來可能有點奇怪。下表展示了可以在 PS1 和 PS2 中使用的特殊字符。

    字符 描述
    \a 鈴聲字符
    \d 格式爲“日 月 年”的日期
    \e ASCII 轉義字符
    \h 本地主機名
    \H 完全合格的限定域主機名
    \j shell 當前管理的作業數
    \1 shell 終端設備名的基本名稱
    \n ASCII 換行字符
    \r ASCII 回車
    \s shell 的名稱
    \t 格式爲“小時:分鐘:秒”的24小時制的當前時間
    \T 格式爲“小時:分鐘:秒”的12小時制的當前時間
    @ 格式爲 am/pm 的12小時制的當前時間
    \u 當前用戶的用戶名
    \v bash shell 的版本
    \V bash shell 的發佈級別
    \w 當前工作目錄
    \W 當前工作目錄的基本名稱
    \! 該命令的 bash shell 歷史數
    \# 該命令的命令數量
    \$ 如果是普通用戶,則爲美元符號$;如果超級用戶(root 用戶),則爲井號#
    \nnn 對應於八進制值 nnn 的字符
    \\ 斜槓
    \[ 控制碼序列的開頭
    \] 控制碼序列的結尾

    注意,所有的特殊字符均以反斜槓\開頭,目的是與普通字符區分開來。可以在命令提示符中使用以上任何特殊字符的組合。

    【實例】通過修改 PS1 變量的值來修改命令提示符的格式:

    [cuining@localhost ~]$ PS1="[\t][\u]\$ "
    [12:51:43][mozhiyan]$
    

    修改後可以顯示當前的時間和用戶名,遺憾的是,通過這種方式修改的命令提示符只在當前的 Shell 會話期間有效,再次啓動 Shell 後將重新使用默認的命令提示符。如果希望持久性地修改 PS1,讓它對任何 Shell 會話都有效,那麼就得把 PS1 變量的修改寫入到 Shell 啓動文件中,具體操作關注後續文章。
    在這裏插入圖片描述

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