吳宏東 - 記於2018年07月03日 - 博客 https://segmentfault.com/u/wu...shell
#!/bin/bash是shell腳本的第一行代碼,表示該腳本使用什麼解釋器;segmentfault
#!/bin/bash
echo命令用於向窗口輸出文本;數組
echo "hello shell"; # 開啓轉義 換行 echo -e "hello \n shell"; # 反引號 顯示命令執行結果 echo `ls /`; # 將顯示結果定向到文件 echo 'hello' > 1.txt;
單行註釋bash
# 表示單行註釋;
多行註釋,EOF還能夠用其餘符號,例如!函數
:>>EOF 註釋內容1 註釋內容2 EOF :>>! 註釋內容1 註釋內容2 !
建立腳本文件,命名爲/tmp/hello.shoop
#!/bin/bash echo "hello shell";
賦予腳本執行的權限,執行腳本測試
chmod u+x /tmp/hello.sh; ./tmp/hello.sh
格式:key=value;
value當爲單引號或雙引號內容時,即爲字符串;當爲數字時,即爲數值型;
使用變量用美圓符號$引用,標準格式是:${key};但有時也能夠使用$key;進行引用;code
# 字符串變量 a='A'; b="${a}\\B"; # 只讀變量 readonly c=7; # 全局變量 export d=3.14; # 單引號的內容會原樣輸出,不能出現單引號,不能使用轉義字符 echo $a; # 雙引號內容能夠包含變量,能夠使用轉義字符 echo $b; # 刪除變量 unset c;
n="0123456789"; m="aaabbbaaabbb"; # 返回字符串變量n的長度 echo ${#n}; # 返回從第5個字符開始到最後的部分 echo ${n:5}; # 返回從第0個字符開始,長度爲5的部分 echo ${n:0:5}; # 刪除開頭部分與012匹配的部分 echo ${n#012}; # 刪除結尾部分與789匹配的部分 echo ${n%789}; # 替換第一次出現的aaa爲xxx echo ${m/aaa/xxx}; # 替換所有aaa爲xxx echo ${m//aaa/xxx}; # 替換開頭部分的aaa爲xxx echo ${m/#aaa/xxx}; # 替換結尾部分的bbb爲xxx echo ${m/%aaa/xxx};
執行輸出:進程
10 56789 01234 3456789 0123456 xxxbbbaaabbb xxxbbbxxxbbb xxxbbbaaabbb aaabbbaaabbb
v=V; echo $v; # 若v未定義或爲空值,則返回vvv,但v的值不變;若v存在且非空,則返回V; echo ${v:-vvv}; # 若v未定義或爲空值,則返回vvv,且v的值被賦值爲vvv;若v存在且非空,則返回V; echo ${v:=vvv}; # 若v未定義或爲空值,則返回vvv,並終止腳本;若v存在且非空,則返回V; echo ${v:?vvv}; # 若v未定義或爲空值,則返回空值,但v的值不變;若v存在且非空,則返回vvv; echo ${v:+vvv};
四則運算符:+、-、*、/
冪運算符、模運算符:**、%
自增自減運算符:++、--
賦值運算符:=、+=、-=、*=、/=、%=
比較運算符:<、>、<=、>=、==、!=
邏輯運算符:&&、||、!字符串
# 運算表達式必須在雙括號內((表達式)) echo $((a=3**2));# 輸出9
格式:read -p <Prompt String> [<變量名>...];
# 輸入單個變量 read -p "請輸入:" n; echo $n; # 輸入多個變量 read -p "請輸入:" n1 n2 n3; echo $n1 / $n2 / $n3;
每一個命令都會返回一個狀態碼,0表示成功,其餘非零數值表示各類狀況的錯誤,exit n;(n的範圍是0~255),1表示通用錯誤,126表示沒有執行權限,127表示命令沒有找到;
格式:./shell腳本文件 參數1 參數2 ...
# 向腳本文件test.sh參入3個參數 ./shell/test.sh p1 p2 p3; # test.sh文件內獲取參數 echo $1 $2 $3;
# 傳遞到腳本的參數個數 echo $#; # 顯示全部參數 echo $*; echo $@; # 顯示第1個參數 echo $1; # 顯示第10個參數,第10個參數起必須使用${n} echo ${10}; # 顯示最後命令的退出狀態,0表示沒有錯誤,其餘值表示有錯; echo $?; # 當前進程的PID echo $$;
格式1:test <測試表達式>
格式2:[ <測試表達式> ]
格式3:[[ <測試表達式> ]]
格式1和格式2等價,格式3能夠使用&&、||、!的邏輯鏈接符;
格式2和3符號先後必須留空格;
a=1.1; b=1.1; if test $a == $b; then # if (( $a == $b )); then # if [ $a -eq $b ]; then # if [[ $a == $b ]]; then echo '相等'; fi;
-z str 字符串是否爲空串;
-n str 字符串是否爲非空串;
str1 == str2 兩個字符串是否相同;
str1 != str2 兩個字符串是否不一樣;
[] 中使用-eq、-ne、-gt、-ge、-lt、-le;
(())中使用==、!=、>、>=、<、<=;
[]中使用-a、-o、!;
[[]]中使用&&、||、!;
-e file 文件是否存在;
-f file 是否普通文件;
-d file 是否目錄;
-L file 是否連接文件;
-b file 是否爲塊設備文件;
-c file 是否爲字符設備文件;
-s file 是否長度不爲零、非空文件;
-r file 是否爲可讀文件;
-w file 是否爲可寫文件;
-x file 是否爲可執行文件;
-O file 是否爲文件的屬主;
-G file 是否爲文件的屬組;
-u file 是否設置了SUID的權限;
-g file 是否設置了SGID的權限;
# 當目錄不存在時建立該目錄 [ !-e /shell ] && mkdir -p /shell;
格式1:array=(a1 'a2' a3);
格式2:array[0]=a1;array[1]='a2';array[2]=a3;
# 定義數組 array=(1 '2'); # 設置第三個元素 array[2]=3; # 顯示第一個元素 echo array[0]; # 獲取數組的所有元素 echo ${array[*]}; echo ${array[@]}; # 獲取數組的大小 echo ${#array[*]};
格式:function fun() { }
function關鍵字能夠省略;
能夠添加返回 return n;(n必須是0~255)執行函數後,能夠經過$?獲取返回值;
fun() { return 1; echo 'over'; } fun; echo $?;
if test -e /shell/1; then echo '1文件存在'; elif test -e /shell/2; then echo '2文件存在'; # else分支是最後的默認分支,能夠省略,最多隻能一個 else echo '都不存在'; fi;
read -p '請輸入:' num; case $num in 1) echo 'num=1' ;; 2) echo 'num=2' ;; *) echo 'num=?' ;; esac
break:跳出循環;
continue:跳過本次循環,進入下一次迭代;
exit n:會停止當前函數以及調用它的主shell;
i=0; len=10; while (($i < $len));do echo $i; let "i++"; done; # 循環讀取文件行內容 while read line; do echo $line; done < /shell/proxy; # 或 cat /shell/proxy | while read line; do echo $line; done;
until 表達式與while相反,當返回值爲0時結束循環;
# 字面常量列表 for loop in 1 2 3 4 5; do echo "The value is: $loop" done; # 參數列表,in $@能夠省略 for p in $@; do echo $p; done; # 序列列表 for x in {1..9}; do echo $x; done; # C語言型for循環 for((i=0;i<10;i++)) { echo $i; }
select是一種菜單循環結構,無限循環,退出能夠加入break或按<Ctrl+C>,通常加入case語句處理;
select x in 1 2 3; do case $x in 1) echo 'x=1' ;; *) echo 'x=?' ;; esac; done;
while : # 或 while true do echo 'loop'; done; for(( ; ; )){ echo 'loop'; }