Shell簡介
- Shell會執行用戶輸入的命令,并且在屏幕上顯示執行的結果。
- 單從字面的意思上理解,Shell的本意是“殼子”的意思,通俗的講就是內部核心與外部使用者發生聯系的介質。其實對于操作系統內核來說,Shell是與用戶打交道的,比如Windows的界面其實就是Windows內核的的Shell,只是他是圖形化的,而Linux開發常用的一般都是命令行的Shell界面,但其實Shell并不等于命令行。
Shell本身是一個解釋型的程序,也是一種編程語言,Shell程序設計語言支持絕大多數在高級語言中能見到的呈現元素,如函數、變量、數組和程序控制結構。
cat /ect/shells
命令可以用作查看計算機上安裝的shell
echo $SHELL
可以查看默認的shell
編寫Shell腳本
DOS操作系統的過程當中,會執行一些重復性的命令。因此常將這些大量的重復性命令寫成批處理命令,通過執行這個批處理命令來代替執行重復的命令。在Linux系統中也有類似的批處理命令,被稱為Shell腳本(Script)。比如系統腳本文件:/usr/bin/startx
- 建立腳本
- 建立Shell腳本程序的開始首先應該指明使用那種Shell來解釋縮寫的腳本,一般來說Bash腳本以
#!
開頭(文件的首行),而#!
后面同時要將所使用的Shell的路徑明確的指出,比如Bourne Shell的路徑為/bin/sh
,而C Shell的路徑為/bin/csh
,Linux下默認采用Bash。#! /bin/sh
- 建立Shell腳本程序的開始首先應該指明使用那種Shell來解釋縮寫的腳本,一般來說Bash腳本以
Shell腳本的執行
Shell腳本是以文本存儲的方式存儲的,而非二進制文件。所以Shell腳本必須在linux系統的Shell下解釋執行。如果已經寫好Shell腳本,運行該腳本可以有一下幾種方法。
- 設置好腳本的執行權限之后再執行腳本,可以使用一下的方式來設置執行權限。
- i.
$ chmod u+x Scriptname
只有自己可以執行,其他人不能執行 - ii.
$ chmod ug+x Scriptname
只有自己以及同一組的用戶可以執行,其他人不能執行 - iii.
$ chmod +x Scriptname
所有人都可以執行 - 使用bash內部指令
source
,例如,$ source MyScript
- 直接使用sh命令來執行
$ sh MyScript
注意:之后的兩種情況不必設置權限就可以執行。
說了這么多,還不如我來做一個簡單的示例吧。通過定義一個腳本來為自己的shell添加一個新的命令。
首先,大家都很熟悉一個命令ls -lh
,可以列出目錄下的詳細信息。
一般常用的是alias,但是對于很多嵌入式開發來說,alias是被裁減掉的,那么,其實可以用簡單的shell腳本來實現。
但是這個命令有些長,是否可以簡化一下呢,有的linux系統中可以使用ll
命令來實現這個功能,但是,我當前的系統并不支持這個命令。
那么,可以通過寫一個簡單的腳本來實現ls -lh
的功能,以后只要執行這個腳本就行了
編輯好腳本,發現沒法執行,主要原因還是權限不夠,添加權限,然后直接執行./ll
命令,來調用ls -hl
如果每次使用之前定義的ll
命令,都需要找到這個腳本,這是一件很麻煩的事,可以通過把這個腳本所在的文件夾添加到環境變量中(這個不是今天的話題),那么我就用粗暴的方式,直接把剛才的腳本放在/bin/
目錄下,無論在哪都能執行的到了。
Shell變量的使用
-
Shell編程中,可以使用變量,這充分體現了他的靈活性。對Shell來講,所有的變量的取值都是一個字符串。Shell腳本中主要有以下幾種變量:
- 系統變量
- 環境變量
- 用戶變量
-
Shell系統變量
以下是一些常用到的Shell系統變量以及其含義-
$#
:保存程序命令行參數的數目
-
$0
:當前的程序名 -
$*
:以("$1 $2"....)一個字符串(中間使用空格隔開)的形式保存所有輸入的命令行參數 -
$@
:以("$1" "$2"....)字符串數組的形式保存的所有輸入命令行參數 -
$n
:$1為命令行的第一個參數,$2 為命令行的第二個參數,以此類推
實際測試輸出結果
-
-
Shell環境變量
Shell環境變量是所有Shell程序都會接受的參數,Shell程序運行時,都會接受一組變量,這組變量就是環境變量,常用的Shell環境變量如下:- PATH:決定了Shell將到哪個目錄中尋找命令或程序(查看環境變量的配置)
HOME:當前用戶主目錄的完全路徑名
HISTSIZE:歷史紀錄條數
LOGNAME:當前用戶的登錄名
SHELL:主機名稱
LANGUGE:shell的路徑名
MAIL :當前用戶的郵件存放目錄
PWD:當前工作目錄的絕對路徑名
操作或查看環境變量的設置
顯示家目錄變量:$ echo $HOME
設置變量:$ export WELCOME = "HE"
(臨時設置,重啟后失效,需要在環境變量的配置文件中修改才能永久生效)
查看所有變量$ env
查看本地變量$ set
刪除變量$ unset
查詢變量$ env | grep WELCOME
(管道符)
用戶變量
Shell用戶變量是最常使用的變量,可以使用任何不包含空格字符的字符串來當作變量的名稱,在Linux支持的所有Shell中,都可以用賦值符號(=)為變量賦值,在使用Shell用戶變量的時候,通常是按照下面的語法規則來定義用戶變量的
變量名=變量值
例如:A=9
、B="Hello World!"
在定義變量時,變量目前不應加$符號,等號兩邊一定不能留空格,變量的引用,要在變量名前添加$符號。-
變量擴展
需要在某一句輸出中插入一個變量值作為替換的時候,可以使用之前的內容${變量}之后的內容
或者使用空格或制表符分隔開,來對變量進行擴展。
變量擴展
字符串截斷
-
符號
##
、#
:代表左截斷,其中,##
是按照通配符表示的字符串最長字符來截取,#
按照通配符表示字符串最小來截?。ɡ?fo表示xxxxfo會被截掉)
左截斷 -
符號
%%
和%
代表右截斷。其中%%
是按照通配符表示的最大字符串來截斷,%
是按照通配符表示的最小字符串來截斷
右截斷
Shell流程控制語句
和傳統的編程語言一樣,Shell提供了很多特性,如數據變量、參數傳遞、判斷、流程控制、數據輸入呃輸出、子程序以及中斷處理等等。
- 條件語句
同其他高級語言一樣,復雜的Shell程序中經常使用到分支和循環控制結構,主要有兩種不同的形式:if語句和case語句- if語句
if [ expression ] //expression與方括號有兩個空格,否則有錯誤
then //相當于C語言中的{
commands1 //expression為True時的動作
else
commands2 //expression為False時的動作
fi //結束符,相當于C語言的}
-
文件比較符
-
-e filename
如果filename存在,則為真[ -e /var/log/syslog ]
-
-d filename
如果filename為目錄,則為真[ -d /tmp/mydir ] -
-f filename
如果filename為常規文件,則為真[-f /user/bin/grep ] -
-L filename
如果filename為符號鏈接,則為真 [ -L /usr/bin/grep ] -
-w filename
如果filename可寫,則為真 [ -w /var/mytmp.txt ] -
-x filename
如果filename可執行,則為真 [ -x /usr/bin/grep ] -
filename1 -nt filename2
(new than)
如果filename1比filename2新,則為真 [ /tmp/install/etc/services -nt /etc/services ]
-
filename1 -ot filename2
(old then)
如果filename1比filename2舊則為真 [ /boot/bzImage -ot /arch/i386/boot/bzImage ]-
字符串標記符(注意引號和空格的問題)
-
-z string
如果string長度為零,則為真[ -z "$myvar" ]
-
-n string
如果string長度為非零,則為真 [ -n "$myvar" ] -
string1 = string2
如果string1與string2相同則為真[ "$myvar" = "one two three" ] -
string1 != string2
如果string1與string2不同,則為真[ "$myvar" != "one two three" ]
-
-
算數比較運算符
-
-num1 -eq num2
等于[ 3 -eq $mynum ]
-
num1 -ne num2
不等于[ 3 -ne $mynum ] -
num -lt num2
小于[ 3 -lt $mynum ] -
num -le num2
大于或等于[ 3 -le $mynum ] -
num -gt num2
大于[ 3 -gt $mynum ] -
num -ge num2
大于或等于[ 3 -ge $mynum ]
-
case語句
case 字符串 in
模式1) command;;
模式2) command;;
.....
esac
case語句是多分支語句,他按照")"左邊的模式對字符串的值匹配來執行相應的命令,匹配總是由上而下的進行,總hi執行首先匹配到的模式對應的命令表,如果模式中的每個匹配都匹配不到,則什么也不執行,所有一般會在最后,放一個“*)”,代表以上都不匹配的任意字符串。“;;’”表示該模式對應的命令部分程序。
#! /bin/sh
Test=$1
case "${Test##*.}" in
gz)
tar -zxvf Test;;
bz2)
tar -jxvf Test;;
*)
echo "error"
esac
- 循環語句
- while語句
在while語句中,當某一條為真,執行指定的命令。語句結構如下:
- while語句
while expression
do
command
.....
done
mynum=0
while [ $mynum -ne 10 ]
do
echo $mynumd
mynum=$(($mynum + 1)) //算數運算需要使用(())
done
- for循環語句
for循環語句對一個變量的可能的值都執行一個命令序列。賦給變量的幾個數值既可以在程序內以數值列表的形式提供,也可以在程序以外以位置參數的形式提供。一幫格式如下
for 變量名 [in 列表]
do
command 1
command 2
.....
done
for x in one two three four
do
echo number $x
done
for myfile in /etc/r*
do
if [ -d "$myfile" ]
then
echo "$myfile (dir)"
else
echo "$myfile"
fi
done