shell腳本須知

什麼是shell腳本,首先它是一個腳本,並不能做爲正式的編程語言,說白了就是shell腳本就是一些命令的集合。mysql

凡是自定義的腳本建議放到/usr/local/sbin/目錄下,這樣的好處是方便管理和維護,且利於之後交接給接替你的管理員。linux

shell腳本的結構sql

#cat first.shshell

#! /bin/bash編程

## This is my first shell script.數組

datebash

echo "Hello world!"編程語言

腳本要以#! /bin/bash開頭,表明的意思:該文件是使用的是bash語法,若是不使用該行也是能夠的,可是若是把這個腳本放到一個默認shell並不是bash的系統裏,那麼這個腳本頗有多是不能成功執行的。ide

還能夠適當在腳本中使用#寫一些腳本相關的註釋內容,如做者、建立日期或者版本等。這些並非shell腳本必定要的,只是爲了統一管理,規範化。函數


shell腳本的幾種執行方式

  1. fork:直接使用絕對路徑來執行腳本,這種方式會啓動一個子shell來執行腳本。

  2. source filename:在當前shell環境下,讀取並執行filename中的命令。注:該命令可用命令「.」來替代,如:source .bash_rc 與 .  .bash_rc 是等效的。

  3. exec 絕對路徑:exec使用shell腳本的絕對路徑在當前shell(shell會被重置到初始環境)下執行腳本,腳本執行完後會退出該shell。

  4. ./script啓動一個子shell來執行腳本。

  5. sh|bash filename啓動一個子shell讀取並執行filename中的命令。

  • 子shell的變量結果不會被帶回父shell,因此要想經過腳本設置當前shell的環境變量時,要用source命令。

shell腳本執行方式

是否須要執行權限

緣由

exec

須要執行權限

由腳本主動調用shell來執行命令

fork./

source.

無需執行權限

shell主動讀取腳本並執行

bashsh

使用sh命令執行一個腳本時,可使用-x參數查看這個腳本的執行過程,在進行腳本調試時,有利於發現問題。

# sh -x first.sh

+ date

Fri Jan  822:28:23 CST 2016

+ echo 'Hello world!'

Hello world!


shell自定義變量

在shell腳本中定義變量,能夠方便咱們很方便的編輯、修改腳本,且使腳本變得簡潔。

格式:變量名=值


shell數學運算

在shell中進行數學運算時,須要使用$[]括起來。

乘法運算:

# a=8;b=3;echo "$a*$b=$[$a*$b]"

8*3=24

除法運算

# a=8;b=3;echo "$a/$b=$[$a/$b]"

8/3=2

  • 默認shell是不支持小數的。若是須要小數,則須要調用bc(linux 系統中的計算器)「yum –y install bc」

  • bc不會進行四捨五入。

若是想要保留2位小樹,能夠這樣實現。

# echo "scale=2;8/3"|bc

2.66


shell用戶交互

shell腳本能夠實現讓用戶輸入一些字符串(read命令)或者讓用戶去選擇(select語句)的行爲。

 

read命令

# cat read.sh

#! /bin/bash

## Using 'read' in shell script.

read -p "Please input a number: " x

read -p "Please input another number: " y

sum=$[$x+$y]

echo "The sum of the two numbers is: $sum"

 

read命令相似與visualbasic的input函數,做用是產生一個「輸入行」,將用戶輸入的字符串賦值給read命令語句後的變量。

 

# sh read.sh

Please input a number: 2

Please input another number: 10

The sum of the two numbers is: 12

 

select語句

select 循環提供了一個簡單的方法來建立一個編號的菜單,用戶可從中選擇。它是有用的,當你須要從列表中選擇,要求用戶選擇一個或多個項目。

select 表達式是一種bash的擴展應用,動做包括:

l  自動用1,2,3,4列出菜單(沒有echo指令,自動顯示菜單)

l  自動read輸入選擇(沒有 read指令,自動輸入)

l  賦值給變量(沒有賦值指令,自動輸入數字後,賦值字符串給變量)

 

語法格式:

selectvariable in value1 value2 value3 …

do

   command

done

 

例子:

# cat sel.sh

#! /bin/bash

echo "What is your favourite OS?"

select var in "Linux" "Gnu Hurd" "FreeBSD" "Other"

do

   break

done

echo "You have selected $var"

 

# sh sel.sh

What is your favourite OS?

1) Linux

2) Gnu Hurd

3) Free BSD

4) Other

#? 2

You have selected Gnu Hurd

 

  • select自己就是一個循環,break就是當選擇後,就跳出循環。

  • 當變量內容含有空格時,應該將其用""括起來。

 

select通常和case語句結合使用,以上面一個例子爲例,將它優化下:

# cat sel.sh

#! /bin/bash

echo "What is your favourite OS?"

select var in "Linux" "Gnu Hurd" "FreeBSD" "Other"

do

   case $var in

   Linux)

      break;;

   "Gnu Hurd")

      break;;

   "Free BSD")

      break;;

   Other)

      break;;

   *)

      echo "Please enter anumber:(1-4)";;

   esac

done

 

echo "You have selected $var"

 

  • select雖然循環卻在第一次選擇以後再也不顯示菜單,只循環輸入。

# sh sel.sh

What is your favourite OS?

1) Linux

2) Gnu Hurd

3) Free BSD

4) Other

#? 6

Please enter a number:(1-4)

#? 8

Please enter a number:(1-4)

#? 3

You have selected Free BSD

Shell腳本預設變量

# cat option.sh

#! /bin/bash

sum=$[$1+$2]

echo "$0$1"+"$2"="$sum"

 

# sh option.sh 2 3

option.sh 2+3=5

 

$#表示參數的個數,$0是腳本自己的名字,$1是執行腳本時跟的第一個參數,$2是執行時跟的第二個參數,$3是…固然一個shell腳本的預設變量是沒有限制的。


if語句

if語句是邏輯判斷語句。

if幾種語法格式:

1)  if 判斷語句;then command;fi

2)  if 判斷語句;then command;else command;fi

3)  if 判斷語句

then

   command

fi

4)  if 判斷語句

then

   command

elif 判斷語句

then

command

   else

      command

fi

 

例子

# cat if1.sh

#! /bin/bash

read -p "Please input your score: " a

if ((a<60)); then

echo "You didn'tpass the exam."

Fi

if判斷語句的相關內容

在進行數值關係運算時,除了可使用(())的形式外,還可使用[],但不能使用>,<,=,!=這些符號,要使用-lt(小於),-gt(大於),-le(大於等於),-ge(大於等於),-eq(等於),-ne(不等於)。

  • 再使用[]時要注意空格。

 

例子

# cat if1.sh

#! /bin/bash

read -p "Please input your score: " a

if [ $a –lt60 ]; then

echo "You didn't pass theexam."

Fi

 

在判斷語句中可使用&&(而且)、||(或者)、!(非)

 

# a=10; if [ $a -lt 1 ] || [ $a -gt 5 ]; then echo OK; fi

OK

# a=5; if [ $a -gt 1 ] && [ $a -lt 10 ]; then echo OK; fi

OK

 

和文件相關的判斷參數

  • -e :判斷文件或目錄是否存在

  • -d :判斷是否是目錄,並是否存在

  • -f :判斷是不是普通文件,並是否存在

  • -r :判斷文檔是否有讀權限

  • -w :判斷是否有寫權限

  • -x :判斷是否可執行

例子:

# if [ -x/bin/bash ]; then echo ok; fi

ok

 

# if [ ! –x/bin/bash ];then chmod +x /bin/bash;fi

 

和變量相關的判斷參數

  • -n:判斷變量是否不爲空

  • -z:判斷變量是否爲空

  • ==或=:判斷變量的值是否爲指定值

  • !=:判斷變量的值是否非指定值

 

例子:

# a=;if [ -n "$a" ]; then echo "a is not null";else echo "a is null"; fi

 

# a=;if [ -z $a ]; then echo "a is null"; fi

a is null

 

判斷條件也能夠是一條命令

例子:

#  if grep -q '^mysql:' /etc/passwd;then echo"user mysql exitst.";fi

user mysqlexitst.

  • grep –q的做用是,過濾但不輸出。

case選擇語句

語法格式:

case 變量 in

value1 |value2)

   command

   ;;

value3)

   command

   ;;

value4)

   command

   ;;

*)

   command

   ;;

esac

 

  • 上面的結構中,不限制 value 的個數,可使用|匹配多個值,*則表明除了上面的 value 外的其餘值。

 

例子:

# cat case.sh

#! /bin/bash

read -p "Input a number: " n

a=$[$n%2]

case $a in

1)

echo "The number isodd."

;;

0)

echo "The number iseven."

;;

*)

echo "It's not anumber!"

;;

esac

 

這是一個判斷奇偶數的腳本,%在shell中是做爲取餘的符號

 

for循環語句

for 變量名 in 循環的條件; do

command

done

 

這裏的「循環的條件」能夠寫成一組字符串或者數字(用 1 個或者多個空格隔開), 也能夠是一條命令的執行結果,注意要使用反單引號``.

 

# for i in 1 2 3 a b; do echo $i; done

1

2

3

A

B

 

# for i in `seq 1 5`; do echo $i;done

1

2

3

4

5

 

  • seq命令:用於產生從某個數到另一個數之間的全部整數

# seq 1 5

1

2

3

4

5

while循環語句

while循環語句經常用來編寫死循環的腳本,用於監控某項服務。

 

語句格式:

while 循環條件;do

      command

done

 

例子:

# cat while.sh

#! /bin/bash

a=5

while [ $a -ge 1 ]; do

echo $a

a=$[$a-1]

done

 

把循環條件用一個:(冒號)替代,這樣能夠作到死循環

 

# cat load.sh

#!/bin/bash

shu=1

while : ; do

load=`uptime|awk '{print$(NF-2)}'|cut -d. -f1`     

if [ $load -gt 10 ]&& [ $shu -le 4 ] ;then

      echo "system load is high."|mail -s"system load" admin@139.com

      shu=$[$shu+1]

      sleep 30

elif [ $shu -gt 4 ];then

      shu=1

      sleep 3600

else

shu=1

      sleep 30

fi

done

 

這是一個監控系統負載的腳本。沒30秒檢測一次系統負載,若是負載值高於10時,向admin@163.com發一封告警郵件,若是連續4次負載高於10時,則休眠1小時再繼續執行腳本,以免頻繁發送郵件,對管理員形成騷擾(告警收斂)。

break、continue、exit

break:退出本層循環

continue:跳過接下來的語句,直接進入下一次循環

exit:退出當前shell

 

#!/bin/bash
for i in `seq 1 5`;do

echo $i

if [ $i== 3 ];then break ;fi
echo $i

done

echo aaaaaaa

 

# sh break.sh

1

1

2

2

3

aaaaaaa

 

#!/bin/bash
for i in `seq 1 5`;do

echo $i

if [ $i== 3 ];then continue ;fi
echo $i

done

echo aaaaaaa

 

# sh continue.sh

1

1

2

2

3

4

4

5

5

aaaaaaa

 

#!/bin/bash
for i in `seq 1 5`;do

echo $i

if [ $i== 3 ];then exit ;fi
echo $i

done

echo aaaaaaa

 

# sh exit.sh

1

1

2

2

3

shell函數

函數就是把一段代碼整理到一個小單元中,並給這個小單元起一個名,當用到這段代碼時,直接調用這個小單元的名字便可。

函數格式:

function_name() {

   command

}

 

函數應定義在shell腳本的開頭

# cat sum.sh

#! /bin/bash

sum() {

   echo$1"+"$2"="$[$1+$2]

}

sum 3 4

 

 

# sh sum.sh

3+4=7

 

獲取網卡名對應的IP:

# cat ip.sh

#!/bin/bash

ip() {

ifconfig |grep -A1"$1 " |tail -1 |awk '{print $2}'|awk -F':' '{print $2}'

}

read -p "Please input the eth name: " e

myip=`ip $e`

echo "$e address is $myip"

 

# sh ip.sh

Please input the eth name: lo

lo address is 127.0.0.1

shell數組

定義元素:

name[下標]=value     

ü  下標從0開始

 

定義數組:

   name=(value1value2 value3 …)

 

刪除數組:

unset name

 

刪除元素:

   unset name[下標]

 

打印數組的全部元素:

   echo${name[*]}或echo ${name[@]}

  • 與打印變量不一樣,打印數值時須要使用${}將數組擴起來

 

打印數組:

   echo${name[下標]}

   打印第2個元素: echo ${a[1]}

 

打印數組的元素個數:

   Echo${#name[@]} 或者 echo ${#a[*]}

 

數組分片:

   echo${name[*]:下標x:下標y}

  • 限制數組的打印範圍,打印下標x到下標y之間的元素

 

數組替換:

   echo ${name[@]/value1/value2}

  • 更改數組的輸出,將value1替換爲value2

  • name=(${name[@]}/value1/value2)也能夠經過這種形式進行賦值

相關文章
相關標籤/搜索