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.\n"
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
- 必须在函数调用前先申明函数
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 函数名