shell 腳本里的命令執行
1. 在bash中,$( )與` `(反引號)都是用來作命令替換的。
命令替換與變量替換差不多,都是用來重組命令行的,先完成引號里的命令行,然后將其結果替換出來,再重組成新的命令行。
$( )與``
在操作上,這兩者都是達到相應的效果,但是建議使用$( ),理由如下:
``很容易與''搞混亂,尤其對初學者來說,而$( )比較直觀。
最后,$( )的弊端是,並不是所有的類unix系統都支持這種方式,但反引號是肯定支持的。
關於命令嵌套:
$(ps -ef|grep `ps -ef|grep nginx |grep 'ottcache'|grep 'master process'|awk '{print $2}' ` |grep 'worker process'|awk '{print $2}')
里面的命令用 `` 反引號得出 pid, 再替換掉該位置, $() 執行另一個命令。
[root@CGSLV5_03 home]# echo today is $(date "+%Y-%m-%d") today is 2019-08-14 [root@CGSLV5_03 home]# echo today is `date "+%Y-%m-%d"` today is 2019-08-14 [root@CGSLV5_03 home]#
[root@localhost ~]# echo Linux `echo Shell `echo today is `date "+%Y-%m-%d"``` Linux Shellecho today is 2017-11-07 #過多使用``會有問題 [root@localhost ~]# echo Linux `echo Shell $(echo today is $(date "+%Y-%m-%d"))` Linux Shell today is 2017-11-07 ``和$()混合使用 [root@localhost ~]# echo Linux $(echo Shell $(echo today is $(date "+%Y-%m-%d"))) Linux Shell today is 2017-11-07 #多個$()同時使用也不會有問題
2. ${ }變量替換 、 ${} 里面還可以有 #*,##*,#*,##*,% *,%% *
一般情況下,$var與${var}是沒有區別的,但是用${ }會比較精確的界定變量名稱的范圍。
exp 1
[root@localhost ~]# A=Linux [root@localhost ~]# echo $AB #表示變量AB [root@localhost ~]# echo ${A}B #表示變量A后連接着B LinuxB
截取變量的部分
file=/dir1/dir2/dir3/my.file.txt
可以用${ }分別替換得到不同的值:
${file#*/}: 刪掉第一個 / 及其左邊的字符串:dir1/dir2/dir3/my.file.txt
${file##*/}: 刪掉最后一個 / 及其左邊的字符串:my.file.txt
${file#*.}: 刪掉第一個 . 及其左邊的字符串:file.txt
${file##*.}: 刪掉最后一個 . 及其左邊的字符串:txt
${file%/*}: 刪掉最后一個 / 及其右邊的字符串:/dir1/dir2/dir3
${file%%/*}: 刪掉第一個 / 及其右邊的字符串:(空值)
${file%.*}: 刪掉最后一個 . 及其右邊的字符串:/dir1/dir2/dir3/my.file
${file%%.*}: 刪掉第一個 . 及其右邊的字符串:/dir1/dir2/dir3/my
記憶的方法為:
# 是 去掉左邊(鍵盤上#在 $ 的左邊)
%是去掉右邊(鍵盤上% 在$ 的右邊)
單一符號是最小匹配;兩個符號是最大匹配
取子串及替換
命令 解釋 結果
${file:0:5} 提取最左邊的 5 個字節 /dir1
${file:5:5} 提取第 5 個字節右邊的連續 5 個字節 /dir2
${file/dir/path} 將第一個 dir 提換為 path /path1/dir2/dir3/my.file.txt
${file//dir/path} 將全部 dir 提換為 path /path1/path2/path3/my.file.txt
${#file} 獲取變量長度 27
3. $(( )) 可以 整數運算、進制轉換、重定義變量值
bash中整數運算符號
| 符號 | 功能 |
|---|---|
| + - * / | 分別為加、減、乘、除 |
| % | 余數運算 |
| & | ^ ! | 分別為“AND、OR、XOR、NOT” |
[root@localhost ~]# echo $((2*3)) 6 [root@localhost ~]# a=5;b=7;c=2 [root@localhost ~]# echo $((a+b*c)) 19 [root@localhost ~]# echo $(($a+$b*$c)) 19
$(( ))可以將其他進制轉成十進制數顯示出來。用法如下:echo $((N#xx))
其中,N為進制,xx為該進制下某個數值,命令執行后可以得到該進制數轉成十進制后的值。
[root@localhost ~]# echo $((2#110)) 6 [root@localhost ~]# echo $((16#2a)) 42 [root@localhost ~]# echo $((8#11)) 9
(( ))重定義變量值,是 [] 數學表達式的加強版
[root@localhost ~]# a=5;b=7 [root@localhost ~]# ((a++)) [root@localhost ~]# echo $a 6 [root@localhost ~]# ((a--));echo $a 5 [root@localhost ~]# ((a<b));echo $? 0 [root@localhost ~]# ((a>b));echo $? 1
4. ${name[*]} ${name[@]} ${#name[*]} 區別
在linux的shell里,${name}可以表示變量,也可以表示數組。
name后面加〔〕的,一般是數組,
${name[*]} 是數組所有元素(all of the elements)
${name[@]} 是數組每一個元素(each of the elements) ,循環數組用這個 。
${#name[*]} 是數組元素的個數,也可以寫成 ${#name[@]}
${name:-Hello} 是指,如果${name}沒有賦值,那么它等於Hello,如果賦值了,就保持原值,不用管問這個Hello了。
${!array_name[@]} 、${!array_name[*]} 獲取數組的下標。
str=" 114.114.114.114 2000:192:434:234 " #變成數組 ip_list=(${str}) for i in "${!ip_list[@]}"; do echo "@""$i=>${ip_list[i]}""@" done echo "數組個數: ${#ip_list[@]}" echo "數組下標: ${!ip_list[@]}"
5. 單小括號 ()
命令組。括號中的命令將會新開一個子shell順序執行,所以括號中的變量不能夠被腳本余下的部分使用。括號中多個命令之間用分號隔開,最后一個命令可以沒有分號,各命令和括號之間不必有空格。
命令替換。等同於`cmd`,shell掃描一遍命令行,發現了$(cmd)結構,便將$(cmd)中的cmd執行一次,得到其標准輸出,再將此輸出放到原來命令。有些shell不支持,如tcsh。
用於初始化數組。如:array=(a b c d) 【($str) 會把字符串按照 字段分隔符:空格、制表符、換行符 ,分割形成 數組】
參考 https://www.cnblogs.com/splendid/p/11201733.html
注意:
[[ ]] 是 字符串表達式的加強版
