shell筆記-全面總結-強化腳本編寫能力

最近給雙十一晚會做直播,並且雙十一紅包一角標廣告形式投放出去,在預熱階段需要看下效果,數據團隊沒法給出一些指標數據,需要我們自己做數據分析給出,平時shell使用的少,很多數據分析的命令忘記了,趁此機會總結下:

shell文件頭

需要定義解釋器
#!/bin/bash

執行方式
第一種,作爲程序執行:
chmod +x ./red-data.sh #給腳本添加執行權限
./red-data.sh#執行腳本
第二種,作爲解釋器參數執行:
/bin/sh  red-data.sh

變量

定義
shell中沒有變量類型的概念,並且不需要提前聲明,賦值=號左右不能有空格,如:
variableName="value"
如果shell中沒有給變量賦值,則默認是空
調用變量
只需要在變量名字前加$即可調用,但是有時候爲限定變量名的邊界,需要大括號{}
site="youku"
echo $site
echo ${site}is playing video
設置只讀變量
site="youku"
readonly site
myUrl="tudou"

[[email protected]]$ site="tudou"
-bash: site: readonly variable
刪除變量
使用unset刪除變量,但是不能刪除只讀變量:
unset variable_name
特殊變量、參數
$0  shell中在$0中存放了腳本本身的名字,
$? 是顯示最後命令的退出狀態,0表示沒有錯誤,其他表示有錯誤
$!  shell把最後一個發送到後臺進程的id
$$  登錄shell的進程id
$#   存放命令行中輸入參數的個數,通常用來校驗輸入參數是否正確使用
$*   傳遞給程序的所有參數,在參數個數不確定時候,很有用
${n} 如果傳遞9個以上參數,不能用$10、$11來去參數,必須使用${10}、${11}
$@  用法,$@要使用雙引號括起來,否則和$*的用法相同了:
變量替換
${parameter:-value}   是如果parameter不爲空就替換爲它的值,爲空就替換爲value
${parameter:=value}  是parameter爲空時,不但使用value,而且把它賦值給parameter(注意=),這種方法不能給位置參數賦值,parameter不能是數字
${parameter:?value}  是parameter不爲空,shell就替換它的值,否則shell把value寫入標準錯誤,然後退出(這種情況發生在登錄shell中,不會衝系統註銷)
${parameter:+value}   是如果parameter不爲空就替換爲value,否則什麼也不替換

引用

單引號
單引號忽略所有特殊符號
雙引號
部分特殊符號不被忽略
A)美元符號
B)反引號
B)反斜槓
雙引號中用反斜槓去掉字符的特殊意義(美元符號、反斜槓、反引號、換行符、其它雙引號),但是反斜槓在其它特殊符號前,雙引號要把它忽略。
15:03 [[email protected]]$ echo "\   hello world  \$y and \"$x\""
\   hello world  $y and ""
第一個空格前的反斜槓沒有被忽略,顯示出來
反斜槓
續行、轉義
反引號
告訴shell執行括起來的命令
$(...)結構
格式:$(command) 和反引號功能一樣
14:59 [[email protected]]$ echo "there are $(who | wc -l) user login in"
there are 3 user login in
expr命令
expr只是整數計算,如果浮點型的計算,可以使用awk或bc計算
此命令支持的操作符有加(+)、減(-)、乘(*)、除(/)、求模(%),其中乘法*需要用反斜槓,因爲linux中*會解析爲當前目錄下所有文件的名字

運算

算數運算
運算符 說明 舉例
+ 加法 `expr $a + $b` 結果爲 30。
- 減法 `expr $a - $b` 結果爲 10。
* 乘法 `expr $a \* $b` 結果爲  200。
/ 除法 `expr $b / $a` 結果爲 2。
% 取餘 `expr $b % $a` 結果爲 0。
= 賦值 a=$b 將把變量 b 的值賦給 a。
== 相等。用於比較兩個數字,相同則返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用於比較兩個數字,不相同則返回 true。 [ $a != $b ] 返回 true。
注意:乘法運算需要加反斜槓

關係運算
關係運算符只支持數字,不支持字符串,除非字符串的值是數字
關係運算符列表
運算符 說明 舉例
-eq 檢測兩個數是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。
-ne 檢測兩個數是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 檢測左邊的數是否大於右邊的,如果是,則返回 true。 [ $a -gt $b ] 返回 false。
-lt 檢測左邊的數是否小於右邊的,如果是,則返回 true。 [ $a -lt $b ] 返回 true。
-ge 檢測左邊的數是否大等於右邊的,如果是,則返回 true。 [ $a -ge $b ] 返回 false。
-le 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。 [ $a -le $b ] 返回 true。

布爾運算
運算符 說明 舉例
! 非運算,表達式爲 true 則返回 false,否則返回 true。 [ ! false ] 返回 true。
-o 或運算,有一個表達式爲 true 則返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 與運算,兩個表達式都爲 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

字符串運算
運算符 說明 舉例
= 檢測兩個字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 檢測兩個字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 檢測字符串長度是否爲0,爲0返回 true。 [ -z $a ] 返回 false。
-n 檢測字符串長度是否爲0,不爲0返回 true。 [ -z $a ] 返回 true。
str 檢測字符串是否爲空,不爲空返回 true。 [ $a ] 返回 true。

文件運算
用於檢測Unix文件的各種屬性
操作符 說明 舉例
-b file 檢測文件是否是塊設備文件,如果是,則返回 true。 [ -b $file ] 返回 false。
-c file 檢測文件是否是字符設備文件,如果是,則返回 true。 [ -b $file ] 返回 false。
-d file 檢測文件是否是目錄,如果是,則返回 true。 [ -d $file ] 返回 false。
-f file 檢測文件是否是普通文件(既不是目錄,也不是設備文件),如果是,則返回 true。 [ -f $file ] 返回 true。
-g file 檢測文件是否設置了 SGID 位,如果是,則返回 true。 [ -g $file ] 返回 false。
-k file 檢測文件是否設置了粘着位(Sticky Bit),如果是,則返回 true。 [ -k $file ] 返回 false。
-p file 檢測文件是否是具名管道,如果是,則返回 true。 [ -p $file ] 返回 false。
-u file 檢測文件是否設置了 SUID 位,如果是,則返回 true。 [ -u $file ] 返回 false。
-r file 檢測文件是否可讀,如果是,則返回 true。 [ -r $file ] 返回 true。
-w file 檢測文件是否可寫,如果是,則返回 true。 [ -w $file ] 返回 true。
-x file 檢測文件是否可執行,如果是,則返回 true。 [ -x $file ] 返回 true。
-s file 檢測文件是否爲空(文件大小是否大於0),不爲空返回 true。 [ -s $file ] 返回 true。
-e file 檢測文件(包括目錄)是否存在,如果是,則返回 true。 [ -e $file ] 返回 true。 

控制流

if條件判斷
主要有以下幾種格式:
if ... fi 語句;
if ... else ... fi 語句;
if ... elif ... else ... fi 語句。
例如:
#!/bin/bash
echo "開始處理點播散投-----------"
if [ -n "$1" ]
then
    dt=$1
else
    dt=`date -d "1 day ago" "+%Y%m%d"`
fi
echo "正在查詢日期:"${dt}

注意:[ expression ] expression與[]之間一定要有空格,否則語法錯誤

if ... else 語句也經常與 test 命令結合使用
#!/bin/bash
num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
    echo ‘The two numbers are equal!‘
    else
    echo ‘The two numbers are not equal!
fi 
執行:
15:20 [[email protected]]$ sh test.sh
‘The two numbers are equal!‘

for循環
格式一:
for i  in  1  2  3
do
     echo  $i
done
列出當前目錄下所有文件
for  file  in *
do
     echo $file
done
格式二:
不帶參數的for循環,這種特殊格式,shell自動將命令行的所有參數註冊列表
for var
do
     command
     ......
done
相當於
for  var  in  “$@”
do
     command
     ......
done

while循環
只要while循環後的命令狀態爲0,循環就會一直執行下去
格式:
while  command1
     do
           command
           command
          ...
 done

util命令
與while不同的是,只有util後的命令狀態不爲0,就會一直執行下去
格式:
util     commond1
     do     
          command
          ......
done

case邏輯
case可以將一個值與多個值比較
格式:
case value in
part1)  command
           ......
           command;;
........
partn)  command
           ......
           command;;
esac

把value依次與part1.....partn比較,發現匹配,則執行匹配項和雙分號之間的所有命令,沒有匹配則不執行。
例如:
#!/bin/bash

if [  "$#" -ne 1 ]
then
        echo "用法:number數字"
        exit 1
fi
case "$1"
     in
        0) echo zero;;
        1) echo one;;
        2) echo two;;
        3) echo three;;
        4) echo four;;
        5) echo five;;
esac

case中還支持正則表達式匹配,例如萬能匹配*
#!/bin/bash

if [  "$#" -ne 1 ]
then
        echo "用法:number數字"
        exit 1
fi

case "$1"
     in
        0) echo zero;;
        1) echo one;;
        2) echo two;;
        3) echo three;;
        4) echo four;;
        5) echo five;;
        *) echo "any thing"
esac

case的匹配條件可以使用  |  邏輯或
例如:
#!/bin/bash
if [  "$#" -eq 0  -o "$#" -gt 1  ]
then
        hour=$(date +%H)
else
        hour="$1"
fi

case $hour
     in
        0? | 1[01] ) echo "Good morning";;
        1[2-7]     ) echo "Good afternoon";;
        *          ) echo "Good evening";;
esac

break、continue
break和所有程序的意思是一樣的,跳出所有循環,但break後邊可以跟數字參數,標示跳出第幾層循環,默認不寫表示跳出本層循環
如:
break n
表示跳出第 n 層循環
#!/bin/bash
for var1 in 1 2 3
do
   for var2 in 0 5
   do
      if [ $var1 -eq 2 -a $var2 -eq 0 ]
      then
          break 2
      else
          echo "$var1 $var2"
      fi
   done
done
執行結果:
15:42 [[email protected]]$ sh test-break.sh
1 0
1 5
continue 後面也可以跟一個數字,表示跳出第幾層循環

字符串

拼接
shell中字符串拼接異常的簡單,直接放到一起即可,如:
15:50 [[email protected]]$ echo "welcome to "$site
welcome to youku
獲取長度
15:58 [[email protected]]$ site="youku"
tty:[0] jobs:[1] cwd:[/opt/flamegraph]
15:58 [[email protected]]$ echo ${#site}
5
截取
16:00 [[email protected]]$ site="youku"
tty:[0] jobs:[1] cwd:[/opt/flamegraph]
16:01 [[email protected]]$ echo ${site:1:3}
ouk
截取第1-3個字符

數組

shell中支持一維數組,使用和程序語言是一樣的,下標也是從0開始計算index
定義格式:
空格分開
array_name=(value0 value1 value2 value3)
換行
array_name=(
value0
value1
value2
value3
)
也可以單獨定義數組的各個分量:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2

讀取
valuen=${array_name[2]}
使用@ 或 * 可以獲取數組中的所有元素,例如:
${array_name[*]}
${array_name[@]}

獲取長度
獲取數組長度的方法與獲取字符串長度的方法相同,例如:
# 取得數組元素的個數
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得數組單個元素的長度
lengthn=${#array_name[n]}

註釋

單行註釋
使用# 註釋

多行註釋
方法一
: '
被註釋的多行內容
'
方法二
:<<eof
被註釋的多行內容
eof
 方法三
:<<!
被註釋的多行內容
!
 方法四
 if false ; then
    被註釋的多行內容
 fi

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