Linux基础10Shell脚本详解

时间:2022-11-14 15:35:01

本文主要介绍了Linux Shell脚本相关知识,包含以下内容:

1.变量。

2.默认变量。

3.shift操作。

4.条件判断if语句。

5.分支判断case语句。

6.函数。

7.循环while。

8.循环until。

9.循环for。

10.脚本语法检查。

 

 

1. 变量

声明变量

字符串变量:

declare A="123456"

 

数值变量:

$declare -i a=10

declare -i b=3

declare -i c=${a}*${b}

 

从标准输入读取变量

cat 2.sh

#!/bin/bash

 

read -p "your first name:" firstname

read -p "your last name:"  lastname

echo -e "\full name is :${firstname} ${lastname} !!!"

 

执行如下:

./2.sh

your first name:abc

your last name:def

 

ull name is :abc def !!!

 

 

2. 默认变量

在脚本中,使用$0, $1, $2, ....来表示执行脚本时所传递的参数. 其中$0表示脚本本身, $1表示第1个参数, $2表示第2个参数.

 

$#表示从$1开始的参数的个数.

$@表示将"$1", "$2" ,...用空格分隔开的一个列表,每一项是一个字符串.$@表示"$1" "$2" "$3" .....

$*表示将$1,$2,..用空格分隔开的一个字符串,只有一个字符串. $*表示"$1 $2 $3 ...."

 

现有如下脚本:

cat 8.sh

#!/bin/bash

 

echo -e "script filename: $0"

echo -e "argument count: $#"

echo -e "arguments:$1,$2,$3,$4,$5,$6,$7,$8,$9,$10"

echo -e "$""@:$@"

echo -e "$""*:$*"

 

 

执行结果如下:

source 8.sh a1 a2 a3 a4   a5  a6 a7 a8 a9

script filename: bash

argument count: 9

arguments:a1,a2,a3,a4,a5,a6,a7,a8,a9,a10

$@:a1 a2 a3 a4 a5 a6 a7 a8 a9

$*:a1 a2 a3 a4 a5 a6 a7 a8 a9

 

 

 

$$表示当前进程的进程ID.

[oracle@102.coe2coe.me:~/test/bash]$echo $$

3581

[oracle@102.coe2coe.me:~/test/bash]$ps -elf|grep 3581

0 S oracle     3581   3574  0  80   0 -  7054 wait   09:22 pts/14   00:00:00 bash

0 R oracle     7101   3581  0  80   0 -  5828 -      10:54 pts/14   00:00:00 ps -elf

0 S oracle     7102   3581  0  80   0 -  4156 pipe_w 10:54 pts/14   00:00:00 grep --color=auto 3581

 

 

$@$*的区别使用以下脚本可以方便的看到:

cat 8.sh

#!/bin/bash

 

echo -e "PID:$$"

echo -e "script filename: $0"

echo -e "argument count: $#"

echo -e "arguments:$1,$2,$3,$4,$5,$6,$7,$8,$9,$10"

echo -e "$""@:$@"

echo -e "$""*:$*"

 

echo -e "-----------\$@-------------"

for  i in "$@"; do

  echo -e "$i"

done

 

echo -e "-----------\$*---------------"

for i in "$*"; do

  echo -e "$i"

done

 

 

 

 

 

[oracle@102.coe2coe.me:~/test/bash]$./8.sh a1 a2 a3 a4 a5

PID:7414

script filename: ./8.sh

argument count: 5

arguments:a1,a2,a3,a4,a5,,,,,a10

$@:a1 a2 a3 a4 a5

$*:a1 a2 a3 a4 a5

-----------$@-------------

a1

a2

a3

a4

a5

-----------$*---------------

a1 a2 a3 a4 a5

 

 

3. shift操作

shift操作可以将$1,$2,$3,$4,$5等参数列表中的第1个元素从列表中移除.使得参数列表变成为$2,$3,$4,$5.参数的个数也减少一个.

 

./10.sh a1 a2 a3 a4 a5

PID:7502

script filename: ./10.sh

argument count: 5

arguments:a1,a2,a3,a4,a5,,,,,a10

$@:a1 a2 a3 a4 a5

$*:a1 a2 a3 a4 a5

-----------$@-------------

a1

a2

a3

a4

a5

-----------$*---------------

a1 a2 a3 a4 a5

shift .....   //1shift操作之后,参数列表变为$2,$3,$4,$5

-----------$@-------------

a2

a3

a4

a5

-----------$*---------------

a2 a3 a4 a5

shift .....   //2shift操作之后,参数列表变为$3,$4,$5.

-----------$@-------------

a3

a4

a5

-----------$*---------------

a3 a4 a5

 

 

shift还可以带参数,表示将几个参数从参数列表中移除掉.

shift 2 表示移除掉最前面的2个参数.

默认为1,即移除掉最前面的1个参数.

 

 

 

4. 条件判断if语句

 

条件判断使用test命令或者中括号[]来进行.

 

 

if [ 条件判断表达式 ]; then

  其他语句

fi

 

thenif条件在同一行时,必须使用分号(;).

thenif条件不在同一行时,可以省略分号(;),也可以不省略分号.

if [ 条件判断表达式 ]

then

  其他语句

fi

 

 

 

cat 11.sh

#!/bin/bash

 

echo "argument count:$#"

echo "arguments:$@"

 

if [ "$#" -lt  1 ]; then

  echo -e "too small arguments. argument count must be  greater then 0 "

fi

 

没有参数的情况,if条件满足了.

source 11.sh

argument count:0

arguments:

too small arguments. argument count must be  greater then 0

 

带有2个参数的情况,if条件不满足.

[oracle@102.coe2coe.me:~/test/bash]$source 11.sh a1 a2

argument count:2

arguments:a1 a2

 

 

if语句中的条件表达式可以有多个,此时可用&&或者||来表示逻辑与和逻辑或的关系.

 

cat 12.sh

#!/bin/bash

 

echo "argument count:$#"

echo "arguments:$@"

 

if [ "$#" -gt  0 ]  && [ "$1" -gt 10 ]  && [ "$1" -lt 20  ]; then

  echo -e "condition matches."

fi

 

 

[oracle@102.coe2coe.me:~/test/bash]$./12.sh 12

argument count:1

arguments:12

condition matches.

[oracle@102.coe2coe.me:~/test/bash]$./12.sh 9

argument count:1

arguments:9

 

 

上述脚本中的带有&&逻辑与运算符的if表达式等效于以下脚本中的带-a 参数的表达式.

而带||逻辑或运算符号的表达式等效于-o参数的表达式.

 

cat 13.sh

#!/bin/bash

 

echo "argument count:$#"

echo "arguments:$@"

 

if [ "$#" -gt  0  -a  "$1" -gt 10  -a  "$1" -lt 20  ]; then

  echo -e "condition matches."

fi

 

 

[oracle@102.coe2coe.me:~/test/bash]$./13.sh 13

argument count:1

arguments:13

condition matches.

[oracle@102.coe2coe.me:~/test/bash]$./13.sh 21

argument count:1

arguments:21

 

 

 

复杂的条件判断可以使用以下语法来实现:

 

if [ 条件表达式1 ]; then

   执行语句1

elif [ 条件表达式2 ]; then

   执行语句2

else

   执行语句3

fi

 

 

cat 14.sh

#!/bin/bash

 

echo "argument count:$#"

echo "arguments:$@"

 

if [ "$#" -lt 1 ]; then

  echo -e "argument count too small."

  exit -1;

elif [ "$1" -lt 60 ]; then

  echo  -e "bad"

elif [ "$1" -lt 80 ]; then

  echo -e  "good"

elif [ "$1" -le 100 ]; then

  echo -e  "excellent"

else

  echo -e  "abnormal"

fi

 

 

./14.sh 30

argument count:1

arguments:30

bad

[oracle@102.coe2coe.me:~/test/bash]$./14.sh 70

argument count:1

arguments:70

good

[oracle@102.coe2coe.me:~/test/bash]$./14.sh 90

argument count:1

arguments:90

excellent

[oracle@102.coe2coe.me:~/test/bash]$./14.sh 120

argument count:1

arguments:120

abnormal

 

 

 

5. 分支判断case语句

 

case语句的语法格式如下所示:

 

case  "变量名称"  in

"变量的值" 1)

   语句1

    ;;

 

"变量的值" 2)

    语句2

    ;;

 

*)

    语句3

     ;;

 

esac

 

 

每个分支的值后面必须有小括号分隔开.每个分支的最后面必须有2个连续的分号(;)来隔开. 最后一个分支一般使用*)表示其它值. 语句的最后使用esac关键字结束语句.

 

 

 

cat 15.sh

#!/bin/bash

 

echo "argument count:$#"

echo "arguments:$@"

 

if [ "$#" -le 0 ]; then

  echo -e "too small argument count"

  exit -1

fi

 

 

case  "$1" in

  "a")

  echo  -e "excellent"

  ;;

  

  "b")

  echo -e "good"

  ;;

 

  "c")

  echo -e "bad"

  ;;

 

  *)

  echo -e "abnormal"

  ;;

 

esac

 

 

 

 

./15.sh

argument count:0

arguments:

too small argument count

[oracle@102.coe2coe.me:~/test/bash]$./15.sh a

argument count:1

arguments:a

excellent

[oracle@102.coe2coe.me:~/test/bash]$./15.sh b

argument count:1

arguments:b

good

[oracle@102.coe2coe.me:~/test/bash]$./15.sh c

argument count:1

arguments:c

bad

[oracle@102.coe2coe.me:~/test/bash]$./15.sh d

argument count:1

arguments:d

abnormal

[oracle@102.coe2coe.me:~/test/bash]$./15.sh abc

argument count:1

arguments:abc

abnormal

 

 

 

 

6. 函数

bash脚本中可以定义和调用函数.

函数的参数的访问也是使用$#,$@,$*,$1,$2等等来实现. 函数的返回值使用return语句来定义,在调用函数时使用$?来取得函数的返回值.

cat 16.sh

#!/bin/bash

 

function evaluate_score( ) {

case  "$1" in

  "a")

  echo  -e "excellent"

  return 5

  ;;

  

  "b")

  echo -e "good"

  return 3

  ;;

 

  "c")

  echo -e "bad"

  return 1

  ;;

 

  *)

  echo -e "abnormal"

  return 0

  ;;

 

esac

 

}

 

 

 

echo "argument count:$#"

echo "arguments:$@"

 

 

if [ "$#" -le 0 ]; then

  echo -e "too small argument count"

  exit -1

fi

 

evaluate_score "$1"

echo "function return value:$?"

 

[oracle@102.coe2coe.me:~/test/bash]$./16.sh a

argument count:1

arguments:a

excellent

function return value:5

[oracle@102.coe2coe.me:~/test/bash]$./16.sh b

argument count:1

arguments:b

good

function return value:3

[oracle@102.coe2coe.me:~/test/bash]$./16.sh c

argument count:1

arguments:c

bad

function return value:1

[oracle@102.coe2coe.me:~/test/bash]$./16.sh d

argument count:1

arguments:d

abnormal

function return value:0

[oracle@102.coe2coe.me:~/test/bash]$./16.sh

argument count:0

arguments:

too small argument count

 

 

7. 循环while

while循环的语法如下:

while [ 条件 ];

do

  语句;

done

 

当条件满足时,继续执行循环,否则退出循环.

 

 

cat 17.sh

#!/bin/bash

 

echo -e "argument count:${#}";

echo -e "arguments:${@}";

 

function  test_while() {

local i=0;

while [ ${i} -lt $# ];

do

  echo -e "${i}";

  let i=i+1;

done

}

 

echo -e "----------------------"

test_while  $1 $2 $3

echo -e "-----------------------------"

test_while  $@

 

 

source 17.sh a b c

argument count:3

arguments:a b c

----------------------

0

1

2

-----------------------------

0

1

2

 

 

8. 循环until

 

 

until循环的语法如下:

 

until [ 条件 ];

do

  语句;

done

 

当不满足条件时,执行循环,否则退出循环.

 

cat 18.sh

#!/bin/bash

 

echo -e "argument count:${#}";

echo -e "arguments:${@}";

 

function  test_until() {

local i=0;

until [ ${i} -ge $# ];

do

  echo -e "${i}";

  let i=i+1;

done

}

 

echo -e "----------------------"

test_until  "$1" "$2" "$3" "$4"

echo -e "-----------------------------"

test_until  $@

echo -e "---------------"

test_until  $*

 

 

 

source 18.sh a b c "aa bb cc"

argument count:4

arguments:a b c aa bb cc

----------------------

0

1

2

3

-----------------------------

0

1

2

3

4

5

---------------

0

1

2

3

4

5

 

 

 

 

9. 循环for

 

for循环的语法如下:

 

for  循环变量 in  集合变量

do

   语句;

done

 

在循环体中使用${循环变量}的方式访问循环变量.for循环中的循环变量为全局变量,在循环体之外,以及循环所在函数之外均可以正常访问.

 

cat 20.sh

#!/bin/bash

 

echo -e "argument count:${#}";

echo -e "arguments:${@}";

 

function  test_for() {

for i in $@

do

  echo -e "${i}";

done

 

}

 

echo -e "----------------------"

test_for  $1 $2 $3

echo -e "-----------------------------"

test_for  $@

 

echo "i is : ${i} ."

 

source 20.sh a b c "aa bb cc"

argument count:4

arguments:a b c aa bb cc

----------------------

a

b

c

-----------------------------

a

b

c

aa

bb

cc

i is : cc .

 

 

for循环还可以方便的访问集合中的元素.语法如下:

for 循环变量 in $(seq 最小值 最大值)

do

  语句;

done

 

其中$(seq 最小值 最大值)表示一个集合,元素为最小值到最大值之间的连续的整数.

 

还可以表示为:

for 循环变量 in {最小值..最大值}

do

  语句;

done

 

其中{最小值..最大值}表示的含义跟$(seq 最小值 最大值)相同.

 

 

cat 21.sh

#!/bin/bash

 

 

for i in $(seq 1 5)

do

  echo -e "${i}";

done

 

echo -e "---------------"

for i in {1..5}

do

  echo -e "${i}"

done

 

 

 

 

 

[oracle@102.coe2coe.me:~/test/bash]$source 21.sh

1

2

3

4

5

---------------

1

2

3

4

5

 

 

这里介绍的连续整数的集合的变量形式,不仅适用于for循环,还可以用于其它语句中.

echo $(seq 1 6)

1 2 3 4 5 6

[oracle@102.coe2coe.me:~/test/bash]$echo {1..6}

1 2 3 4 5 6

 

 

for循环还可以按照初值和步长的方式来定义一个循环.

for ((循环变量初值; 条件; 变化))

do

  语句;

done

 

此时,for关键后的表达式必须使用两个小括号括起来:(()).

 

cat 22.sh

#!/bin/bash

 

 

for (( i=1; i<=5; i=i+1))

do

  echo "${i}"

done

 

[oracle@102.coe2coe.me:~/test/bash]$source 22.sh

1

2

3

4

5

 

 

10. 脚本语法检查

 

sh命令使用-n参数表示不执行脚本,而是仅仅检查脚本有误语法错误.

 

现在有一个存在语法错误的脚本的内容如下:

cat 23.sh

#!/bin/bash

 

echo  -e "this script is for test only."

 

#此处存在一个语法错误.

echo  -e "aaaaa'  

 

 

for ((i=1; i<=5; i=i+1))

do

  echo "${i}"

done

 

直接使用source方式执行脚本时,会先执行存在语法错误之前的各个语句,比如echo.

[oracle@102.coe2coe.me:~/test/bash]$source 23.sh

this script is for test only.

bash: 23.sh: line 9: unexpected EOF while looking for matching `"'

bash: 23.sh: line 12: syntax error: unexpected end of file

 

使用sh -n方式检查脚本语法错误时,并不会实际执行任何语句.

[oracle@102.coe2coe.me:~/test/bash]$sh -n 23.sh

23.sh: 12: 23.sh: Syntax error: Unterminated quoted string