命令集構成的shell與變量賦予其的靈活性
一.shell腳本的基本構成和調用方式
shell腳本由基本文件構成,調用shell文件有兩種方式:bash+file.sh或source+file.sh的絕對路徑,其中后一種需要對文件添加用戶執行權限。這兩種調用方式都能執行shell文件,但是所執行的位置不同,有時會對當前操作造成影響。bash+file.sh相當于打開了一個子shell環境,所以在其中的操作不會影響當前shell環境的變量。而使用source或.調用shell的話,相當于在當前shell中執行,所以會影響變量。廢話不多說,直接上例子:
編寫chlid.sh文件如下,賦予執行權限:
[root@localhost bin]# cat child.sh #!/bin/bash num1=1 num2=20 num3=$[$num1+$num2] echo $num3
其內容為賦予變量num1=1,num2=20,num3=num1+num2等于20+1=21,所以執行這個shell的結果應該是21。退出文件作如下操作:
[root@localhost bin]# num3=30 [root@localhost bin]# echo $num3 30
這里將num3賦予30的值,使用bash執行child.sh,然后檢查num3的值是否變化:
[root@localhost bin]# bash child.sh 21 [root@localhost bin]# echo $num3 30
可以看到num3的值并沒有受到影響。再使用source運行:
[root@localhost bin]# source child.sh 21 [root@localhost bin]# echo $num3 21
這里可以看到num3的值受到shell文件執行的影響而產生了變化。
上例中child文件內容就是最基本的順序執行命令的格式,最上一行的#!一定要寫在行首,這時識別shell文件的必要格式,后面接上所匹配的shell類型,這里匹配的是bash,所以寫為#!/bin/bash,這個格式叫做shell的首行shebang機制,如果缺少了這個,文件就不能被當成shell文件所執行。后面的行就是一個一個的單個命令,按照上下順序執行,最后得出結果。
二.什么是變量,它有什么用
還是查看child.sh的文件內容,所定義的num1,2,3,甚至得到的結果都是固定的21,如此看來shell腳本過于呆滯死板,完全沒有自由與靈活性。變量的出現給這個呆滯死板的shell注入了鮮活的生命,打個比方來說就像教會一個赤手空拳的遠古人使用工具一樣,戰斗力倍增。下面我們將child.sh的內容改一下:
[root@localhost bin]# cat child.sh #!/bin/bash num1=$1 num2=$2 num3=$[$num1+$num2] echo $num3
這里使用了$1 $2…這種變量叫做位置變量,在執行shell命令后加上參數,就會根據參數的順序給文件中的$1,$2..賦值,如下操作:
[root@localhost bin]# child.sh 4 5 9
這樣就可以使用上述命令進行任意數的相加,child.sh的作用就變得比以前牛逼了。下面開始介紹變量的種類以及特殊變量。
變量可以分為5類:本地變量、環境變量、局部變量、位置變量以及特殊變量。
1.本地變量與環境變量的區別
本地變量只作用于當前shell環境中,定義方式為name=xxx,調用方式為$name。環境變量作用于當前shell和其子shell中,可以使用export name=xxx或者declare -x name=xxx定義,調用方式同上。下面舉例說明:
[root@localhost bin]# name1=10 [root@localhost bin]# echo $name1 10 [root@localhost bin]# bash McgeeWang! WanSui!!!!! [root@localhost bin]# echo $name1 [root@localhost bin]# exit exit [root@localhost bin]# export name2=20 [root@localhost bin]# echo $name2 20 [root@localhost bin]# bash McgeeWang! WanSui!!!!! [root@localhost bin]# echo $name2 20
此例先定義本地變量name1,bash進入子進程調用name1,變量值為空。exit回到shell定義環境變量name2,bash切換至子進程中,name2的變量值仍然存在。
2.常用特殊變量的意義
$?:上一條命令的執行結果,0為真,非0為假
$#:所有變量的總數
$0:當前shell名
$$:當前shell的進程號
$*:傳給shell的所有參數,以一個長字符串顯示出來
$@:傳給shell的所有參數,以列表方式顯示出來
這里舉例如下辨認$@與$*的使用區別:
制造shell腳本xxx.sh與yyy.sh,內容如下
[root@localhost bin]# cat yyy.sh #!/bin/bash xxx.sh "$@" xxx.sh "$*" [root@localhost bin]# cat xxx.sh #!/bin/bash echo "$1" echo "$2" echo "$3"
執行yyy.sh,輸入多個變量1 2 3,得到結果如下:
[root@localhost bin]# yyy.sh 1 2 3 1 2 3 1 2 3
可以看到$@代表了“1”“2”“3”,而$*代表了“1 2 3”,這就是它倆的區別。
三.條件判斷和邏輯運算腳本中在的使用
test命令有三種格式,作為判斷真假
test 條件
[ 條件 ]
[[ 條件 ]]
而test又分為數值測試,字符串測試,文件測試這幾種:
1.數值測試(只用于比較數值):
-eq:是否等于
-ge:是否大等于
-gt:是否大于
-le:是否小等于
-lt:是否小于
2.字符串測試(只用于比較字符串):
==:是否等于
>:ascii碼是否大于
<:ascii碼是否小于
!=:是否不等于
=~:左側是否匹配右側的字符串格式(一般使用[[]]的格式,并且支持glob通配符)
-z “string”:string是否空,空為真,不空為假
-n “string”:string是否為不空,不空為真,空為假
3.文件測試:
-a file:file是否存在
-e file:file是否存在
-b file: file是否存在且為塊設備文件
-c file:file是否存在且為字符設備文件
-d file:file是否存在且為目錄文件
-f file:file是否存在且為普通文件
-h / -L file:file是否存在且為符號鏈接文件
-p file: file是否存在且為命名管道文件
-s file:是否存在且為套接字文件
-r file:是否存在且可讀
-w file: 是否存在且可寫
-x file:是否存在且可執行
-g file:是否存在且擁有sgid權限
-u file:是否存在且擁有suid權限
-k file:是否存在且擁有sticky權限
-s file:是否存在且內容非空
-t fd:fd表示文件描述符是否已經打開并且與某終端相關
-N file:文件上一次被讀取之后是否被修改過
-O file:當前有效用戶是否為文件屬主
-G file:當前有效用戶是否為文件屬組
file1 -ef file2:file1與file2是否指向同一個inode
file1 -nt file2:file1是否新于file2
file1 -ot file2:file1是否舊于file2
&&(與)、||(或)、!(非),聯合test命令的判斷結果可以實現命令的選擇執行方式。簡單來說,command1 && command2,當command1為真,command2才會執行。command1 || command2,當command1為假,command2才會執行。這樣就實現了命令的選擇執行。舉例如下:
[root@localhost bin]# cat judgefile.sh #!/bin/bash read $1 [[ $1 =~ .*\.sh$ ]] && chmod +x $1 && echo '+x' || echo 'do not +x'
這個shell文件的內容為判斷輸入文件名是否為.sh結尾,如果是,則加上執行權限并打印“+x”,如果不是,則只打印“do not +x”。
原創文章,作者:mcgeewang,如若轉載,請注明出處:http://www.www58058.com/34362