1. 程式人生 > >shell程式設計之步步為營(2)

shell程式設計之步步為營(2)

我們今天接著學習shell程式設計!

首先接著介紹shell指令碼中的非常重要的一種變數:位置變數

  • 位置變數 : 在指令碼中呼叫通過命令列引數傳遞給指令碼的引數。

$1 , $2 , … : 對應呼叫第1、第2…等引數 $0 : 命令本身 $* : 傳遞給指令碼的所有引數 [email protected] : 傳遞給指令碼的所有引數(與$*是有區別的) $# : 傳遞給指令碼的引數個數

示例: 我們寫一個指令碼來測試一下:

#!/bin/bash
#
echo $0
echo $2
echo "\$* : $*"
echo "\
[email protected]
: [email protected]" echo "\$# : $#"

執行命令,結果如下:

[[email protected] ~]$ chmod +x test.sh
[[email protected] ~]$ ./test.sh Tom Jerry Cherry
./test.sh
Jerry
$* : Tom Jerry Cherry
[email protected] : Tom Jerry Cherry
$# : 3
  • shift : 引數左移

用法: 在shell指令碼中,用於將引數踢出: shift : 踢出一個引數,即第二個引數變成第一個,第三個引數變成第二個; shift # :踢出#個引數;

示例: 我們輸入4個引數,分別為Tom,Jerry,Cherry,Baby,首先打印出第一個引數,即Tom;然後踢出第一個引數,此時第二個引數Jerry變成第一個引數,再次列印引數1,顯示的便是Jerry…

#!/bin/bash
#
echo $1
shift
echo $1
shift 2
echo $1
echo "\$* : $*"
echo "\[email protected] : [email protected]"
echo "\$# : $#"

[[email protected] ~]$ ./test.sh Tom Jerry Cherry Baby
Tom
Jerry
Baby
$* : Baby
[email protected]
: Baby $# : 1
  • 算術運算

執行算術運算操作有如下四種方式: (1)# let var = EXPRESSION 運算結果不直接打印出來 (2)# var = $[ EXPRESSION ] 運算結果會直接打印出來 (3)# var = $(( EXPRESSION )) 運算結果直接打印出來 (4)# var = $(expr EXPRESSION) 算術表示式以空格隔開,結果不直接打印出來,且*需要轉義

示例:

[[email protected] ~]$ num1=4
[[email protected] ~]$ num2=8

[[email protected] ~]$ let sum=$num1+$num2
[[email protected] ~]$ echo $sum
12

[[email protected] ~]$ var1=$[$num1+$num2]
[[email protected] ~]$ echo $var1
12

[[email protected] ~]$ var2=$(($num1+num2))
[[email protected] ~]$ echo $var2
12

[[email protected] ~]$ var3=$(expr $num1 + $num2)
[[email protected] ~]$ echo $var3
12

  • bash內建的隨機數生成器:$RANDOM

示例: 生產60以內的隨機數

[[email protected] ~]$ VAR=$[$RANDOM%60]
[[email protected] ~]$ echo $VAR
18
[[email protected] ~]$ VAR=$[$RANDOM%60]
[[email protected] ~]$ echo $VAR
48
[[email protected] ~]$ VAR=$(($RANDOM%60))
[[email protected] ~]$ echo $VAR
6
[[email protected] ~]$ let VAR=$RANDOM%60
[[email protected] ~]$ echo $VAR
49
[[email protected] ~]$ VAR=$(expr $RANDOM % 60)
[[email protected] ~]$ echo $VAR
37
  • 增強型賦值

+=,-=,*=,/=,%=,++,–

示例:

[[email protected] ~]$ let var=13
[[email protected] ~]$ echo $var
13
[[email protected] ~]$ let var-=3
[[email protected] ~]$ echo $var
10
[[email protected] ~]$ let var*=2
[[email protected] ~]$ echo $var
20
[[email protected] ~]$ let var/=4
[[email protected] ~]$ echo $var
5
[[email protected] ~]$ let var%=3
[[email protected] ~]$ echo $var
2
[[email protected] ~]$ let var++
[[email protected] ~]$ echo $var
3
[[email protected] ~]$ let var--
[[email protected] ~]$ echo $var
2
  • 條件測試:判斷條件是否滿足;由測試機制來實現;

用法 專用的測試表達式需要由測試命令輔助完成測試過程,測試命令如下: # test EXPRESSION # [ EXPRESSION ] # [[ EXPRESSION ]]

注:EXPRESSION前後必須有空格

bash的測試型別: 數值測試 、字串測試、檔案測試。

數值測試

  • -gt 大於
  • -ge 大於等於
  • -eq 等於
  • -ne 不等於
  • -lt 小於
  • le 小於等於

示例:

[[email protected] ~]$ test 1>3
[[email protected] ~]$ echo $?
1

[[email protected] ~]$ [ 100 -eq 100 ]
[[email protected] ~]$ echo $?
0

字串測試:用於字串比較時的運算元應該加引號

  • ==或者= 相等
  • > 大於
  • < 小於
  • != 不等於
  • =~ 左側是否能被右側的PATTERN匹配,一般用於[[ ]]中;
  • -z “STRING” 測試字串是否為空;不空為真、空為假;
  • -n “STRING” 測試字串是否不為空;不空為真、空為假;

示例:

[[email protected] ~]$ name=jeffrey
[[email protected] ~]$ echo $name
jeffrey
[[email protected] ~]$ [-z "$name"]
bash: [-z: command not found...
[[email protected] ~]$ [ -z "$name"]
bash: [: missing `]'
[[email protected] ~]$ [ -z "$name" ]
[[email protected] ~]$ echo $?
1
[[email protected] ~]$ myname=jeffrey
[[email protected] ~]$ [ -n "$myname" ]
[[email protected] ~]$ echo $?
0
[[email protected] ~]$ [ "$name"="$myname" ]
[[email protected] ~]$ echo $?
0
[[email protected] ~]$ [ "$name"!="$myname" ]
[[email protected] ~]$ echo $?
0
[[email protected] ~]$ [ "$name"! = "$myname" ]
[[email protected] ~]$ echo $?
1
[[email protected] ~]$ [[ "$name" =~ ^m ]]
[[email protected] ~]$ echo $?
0
[[email protected] ~]$ [[ "$name" =~ ^t ]]
[[email protected] ~]$ echo $?
1
[[email protected] ~]$ [[ "$name" =~ ^m.* ]]
[[email protected] ~]$ echo $?
0

bash自定義退出狀態碼

bash可以自定義退出狀態碼:exit n

若指令碼中一旦遇到exit命令,指令碼會立即終止,終止退出狀態取決於exit命令後面的數字;如果未給指令碼指定退出狀態碼,整個指令碼的退出狀態碼取決於指令碼中執行的最後一條命令的狀態碼。

今天的練習

1,計算系統上/etc/passwd上第10個使用者和第20個使用者的ID之和; 指令碼sumid.sh內容如下:

#!/bin/bash
#
id1=$(head -10 /etc/passwd | tail -1 | cut -d: -f3)
id2=$(head -20 /etc/passwd | tail -1 | cut -d: -f3)
sum_ID=$[$id1+$id2]
echo "The sum of No.10 id  and No.20 id is $sum_ID"

執行結果如下:

[[email protected] ~]$ chmod +x sumid.sh
[[email protected] ~]$ ./sumid.sh
The sum of No.10 id  and No.20 id is 70

2,計算/etc/rc.d/rc.sysinit以及/etc/rc.d傳遞兩個檔案路徑作為引數給指令碼,計算檔案的空白行數之和; 指令碼blankline.sh內容如下:

#!/bin/bash
#
line1=$(grep "^[[:space:]]*$" $1 | wc -l)
line2=$(grep "^[[:space:]]*$" $2 | wc -l)
sum=$[ $line1 + $line2 ]
echo "blank lines all is $sum"

執行結果:

[[email protected] jeffrey]# ./blankline.sh /etc/profile /etc/bashrc
blank lines all is 18

3,統計/etc,/var,/usr共有多少個子目錄和檔案; 指令碼count.sh內容:

#!/bin/bash
#
num1=$(ls -l /etc | wc -l)
num2=$(ls -l /var | wc -l)
num3=$(ls -l /usr | wc -l)
num=$[$num1+$num2+$num3]
echo "file number is $num"

執行結果如下:

[[email protected] jeffrey]# chmod +x count.sh
[[email protected] jeffrey]# ./count.sh
file number is 333

4,寫一個指令碼,接受一個檔案路徑作為引數,若引數行小於1,則提示使用者“至少給出一個引數”,並立即退出;否則,顯示第一個引數所指向的檔案中的空白行數;

指令碼test.sh內容:

#!/bin/bash
#
[ "$#" -lt 1 ] && echo "至少應輸入一個引數" && exit 125
line=$(grep "^[[:space:]]*$" $1 | wc -l)
echo "$line"

執行結果:

[[email protected] jeffrey]# chmod +x test.sh
[[email protected] jeffrey]# ./test.sh
至少應輸入一個引數
[[email protected] jeffrey]# ./test.sh /etc/profile
11