shell脚本学习笔记(2)

Shell脚本笔记

1.最简单的Shell脚本

Shell脚本是以行为单位的,脚本中所包含的成分主要有:注释(#)、命令、Shell变量和结构控制语句。

用户可以使用任何文本编辑器编辑Shell脚本文件,如vi、gedit等。

脚本的调用的两种方式:

sh script-file  

./script-file

执行时要考虑脚本是否具有可执行权限,sh可以执行没有可执行权限的脚本

另一种调用方法是先将脚本文件的访问权限修改为可执行:

chmod u+x script-file 

或:

chmod 744 script-file

查看文件权限:

ls -l

当执行一个脚本文件时,Shell就产生一个子Shell(即一个子进程)去执行命令文件中的命令。因此脚本中的变值不能传递到当前Shell(即父进程Shell)

一个最简单的script:

#!/bin/bash

# Program

# This program shows "Hello World!"

echo -e "Hello World. "

exit 0

#!/bin/bash 在调用bash脚本时,以#!开头的语句通知系统用何解释器执行此脚本

如果bash是默认的Shell,那么脚本的开头也不用非得写上#!

脚本说明应包括:

脚本名词、脚本功能、版权声明、复杂脚本应对算法做简要说明

2.Shell 变量

name=string

name是变量名,变量名用小写字母命名

=是赋值符号,两边不能有空格,否则将视为命令

v1=centos

v2=’this is a shell script test.’

Shell脚本中的变量只有整数和字符串

eg:

        v2='This is a test from zhanghongo.'

echo $v2

在调用的Shell变量之前加上$符号

eg:

a=10

b=20

echo $(($a+$b))

echo $((10+20*30-40))      

((c=2+3+4-5))

echo $c      

在Shell中做加减乘除模取余运算,要加上两层小括号,而且要在输出的值之前加上$符号

Shell字符串变量表达式:

表达式

说明

${#string}

$string的长度

${string:position}

从position开始提取字符串

${string:position:length}

从位置position开始提取长度为$length的子串

${string#substring}

从开头删除最短匹配子串

${string##substring}

从开头删除最长匹配子串

${string%substring}

从结尾删除最短匹配子串

${string%%substring}

从结尾删除最长匹配子串

包含字符串操作后的脚本,如果使用sh script-file执行,会报错:Bad substitution

可以使用以下方式执行不会报错

./script-file

bash script-file

#删除开始的字符串

echo ${str#I love}

#删除开始I到.的所有字符串(最短匹配)

echo ${str#I*.}

#删除开始I到.的所有字符串(最长匹配)

echo ${str##I*.}

#如果*后面没有字符(如:echo ${str##I*}),则只删除*前面的字符串,并不会删除*表示的部分,*表示任意字符串

#如果字符串开头是空格,则用echo输出的时候,默认会省略开头的空格

3.文件判断——test与[]

test:

标志

说明

-f

文件是否存在

-d

目录是否存在

-r

文件是否有读权限

-w

文件是否有写权限

-x

文件是否有执行权限

eg:  

#判断是否存在/home/sky/mytest,存在就输出exist,否则输出not exist

        filename=/home/sky/mytest

test -f $filename && echo 'exist' || echo 'not exist'

eg:

#判断目录是否存在,存在就输出exist,否则输出not exist

directoryname=/home/sky

test –d $directoryname && echo ‘exist’ || echo ‘not exist’

中括号[]判断注意

-在中括号中必须都要使用空格来分隔——4个空格

-在中括号中的变量,最好都要用双引号括起来

-在中括号中的常数,最好都以单引号括起来

eg:

[ “$a” == ”$b” ] && echo ‘Yes’ || echo ‘No’

[ ‘12’ == ’10’ ] && echo ‘Yes’ || echo ‘No’

条件判断:

单分支判断:

if []; then

        echo statement

fi

双分支判断:

if []; then

        echo statement1

else

        echo statement2

fi

多分支判断:

if []; then

        echo statement1

elif []

        echo statement2

elif []

        echo statement3

else       # else可以省略

        echo statement4

fi

条件选择判断:注意执行语句要用;;结束

case $name in

1);;

esac

if语句在中括号中同时使用test判断文件是否存在时,会报错:

test: line 7: [: -f: binary operator expected

原因是:中括号和test都是表示判断。

修改方法:

#method1:去掉test,使用中括号做判断

filename=/home/sky/mytest1

if [ -f $filename];then

echo 'The file is exist.'

else

echo 'The file is not exist.'

fi

# method2:去掉中括号,使用test做判断

filename=/home/sky/mytest1

if test -f $filename;then

echo 'The file is exist.'

else

echo 'The file is not exist.'

fi

eg:使用多分支条件

#!/bin/bash

# Program

# function: view hardware infomation

echo 'Please input your hardware to view.'

read hd

if [ $hd == cpu ]; then

echo 'Your cpu info is.'

cat /proc/cpuinfo

elif [ $hd == mem ]; then

echo 'Your memory is.'

cat /proc/meminfo

elif [ $hd == hard ]; then

echo 'Your harddisk is.'

df -h

else

echo 'I dont know what your input'

fi

多分支选择语句,用sh script-file执行时,会出现错误

使用bash script-file执行,不会出现错误

eg:使用case多选

#!/bin/bash

# Program

echo 'Please input a number.'

read kemu

case $kemu in

yuwen)

        echo "Your input number is yuwen.";;

shuxue)

        echo "Your input number is shuxue.";;

yingyu)

        echo "Your input number is yingyu.";;

*)

        echo "I dont know what you input";;

esac

#注意事项:

只要变量kemu的输入字符串和条件判断的字符串一样,就视为条件成立

条件后面要加右括号

执行语句结束要加两个分号

case条件语句以esac结束

循环操作:

while循环:

while condition;do

done;

until循环:

untile condition;do

done;

for循环:

for(());do

statement

done;

总结:3种循环都是以done结束循环

1.while循环

eg: while loop

#!/bin/bash

# while loop

i=10

while (($i>=5));do

echo $i;

((i--));

done;

特殊条件运算符号:-eq  -ne  -gt   -ge   -lt   -le

一般运算符分别是: ==  !=    >   >=    <    <=

总结:在双层小括号中支持一般的比较运算符,但是在中括号中,只能支持特殊条件运算符

eg:  使用while循环实现输出10到100,使用中括号[]作为条件判断

min=10

max=100

while [ $min -le $max ]  #注意[]中需要4个空格,中括号中只支持特殊条件运算符

do

    echo $min

    min=`expr $min + 1`    #注意此处不是单引号,而是Tab上面那个键单独按下输入的符号;等号前后无空格

done

eg:  使用while循环,实现输出10到小于100能被4整除的整数,使用双层小括号作为条件判断

i=10

while(($i<100))    #双层小括号支持一般运算符

do

        if(($i%4==0))

        then

                echo $i

        fi

        i=$(($i+1))             #赋值运算的形式

done

2.for循环

eg:用for循环输出从1到10的整数

for i in {1..10};  #分号可加可不加,理解成集合语法

do

        echo $i

done

eg:for循环条件的另一种形式,理解成集合

for i in 1 2 3 4 5

do

        echo $i

done

eg:for循环输出1到100的整数

for i in `seq 100`

do

        echo $i

done

eg:for循环条件的另一种格式,类似于java语言

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

do

        if((i%3==0))

        then

                echo $i

        fi

done

3.until循环

eg:输出0到不大于5的整数的的平方

  i=0

  until [ $i –gt 5]

  do

let “square=i*i”       #let语法

echo “$i * $i = $square”

let “i++”

done

eg:使用for循环输出99乘法口诀表

for i in `seq 9`   #seq语法,这里不是单引号,是Tab键上面那个

do

        for j in `seq $i`      #seq语法,注意i前面要加上$符号

        do

                let "temp = i * j"            #let语法,引号中间定义了一个temp变量,变量i,j之前不需要加$符号

                echo -n "$i*$j=$temp  "   #-n表示不换行输出

        done

        echo "" #换行

done

Shell脚本中的function

  1. 必须在函数调用前先申明函数

eg:根据用户输入的参数,输出对应的数;假设脚本保存为:func

  #!/bin/bash

function print() {

        echo "Your input is $1"        #$1是用户默认输出的第1个参数

}

echo "This program will print your selection!"

case $1 in

"one")

        print 1;;      #调用print函数,并个其传递默认参数1

"two")

        print 2;;

*)

        print "not 1 or 2.";;

esac

调用本脚本的方法:bash func one  #one是传递给脚本的默认参数

eg:定义两个变量相加的函数fSum

#!/bin/bash

fSum 3 2;

function fSum()  # $0表示函数本身

{

        echo $1,$2;

        return $(($1+$2));  

}

fSum 5 7;   #调用函数,可以像使用一个新定义的命令

total=$(fSum 3 2)    #在小括号中,也可以像使用命令一样,调用函数

echo $?

echo "return"

echo $total;

假设本脚本定义为testfun1.sh             

如果要在shell中直接调用某个sh脚本的某个函数,需要先source命令,再调用该函数:

source testfun1.sh

fSum 2 3               

函数删除:

unset –f 函数名                                                

原文地址:https://www.cnblogs.com/HITSZ/p/8243129.html