命令行替换:
! 历史替换(前面已经讲过) {} 字符展开,每次一个 如:mkdir chap{01,02,03,04}
mkdir -p chap{01,02,03,04}/{html,text} ~username 用户的家目录
$或${} 变量替换,将变量的值取出来,也叫变量解释 $(( )) 算术替换,用于算术运算,不过只支持整数
命令行上的+、-、*、/没有传统的数学意义
echo ((1+2))
` `或$() 命令替换,取命令执行结果
*、? 通配符
[abcd] 方括号中的任一个
[^abc] 不在方括号中的任一个
shell变量
shell变量分类:环境变量、局部变量。
环境变量:能被子shell继承
局部变量:只存在于创建它的shell环境中
有些把shell变量分为4类,将环境变量细分为:普通环境变量、
位置参数、特定变量参数。
内置环境变量:
$? 最近命令执行的退出状态
$- 当前启用中的shell选项标记
$$ 当前shell进程ID
$PPID 当前shell父进程的ID
$! 最新后台命令的进程ID
$0 当前执行的进程名(程序名)
$1-9 程序接收的参数
$# 位置参数的数量
$* 所有位置参数的内容
变量定义:
为变量名赋一个值即定义了。如A=5
注意:
1、=两边没有空格。
2、值含有空格时,要用“”括起来(如B=“hell words”)
3、如果要定义的是环境变量,前面加export(如export C=3)
4、shell是一弱类型语言,变量无严格的数据类型。具体类型取
决于当时语义环境。如 a=123;echo $a\"bdc\";echo $((a+5))
5、变量名约定俗成为大写。
变量解释:$ (必要时要使用${}来界定变量范围)
A=apple
echo \"how are you\" > $A_ode.txt
echo \"how are you\" > ${A}_ode.txt
比较其区别?
变量删除 unset
unset A
创建一个shell脚本:
vim firtsh.sh
#!/bin/bash 指定shell的解释器
# 注释
hell=\"Hello! how are you\"
echo $hell
运行shell
1、设置其可执行权限 chmod 755 firstsh.sh
2、输入文件名直接运行(./firstsh.sh)
echo 回显
格式:echo [选项] 字符串
-n 不换行
read 读数据,并放到指定的变量中
if 条件分支
1、if [ 条件 ]
then
commands
fi
执行流程:判断[ ]中的条件是否成立,成立的话,
执行then-if之间的命令,不成立的话,就不执行。
2、if [ 条件 ]
then
commands
else
commands
fi
执行流程:判断[ ]中的条件是否成立,成立的话,
执行then-else之间的命令,
不成立的话,执行else-fi之间的命令。
比较运算:
数值比较:
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
字符比较:
= 等于
!= 不等于
-z 是否为空
-n 非空
\\> 大于
\\< 小于
文件测试
-b file 若文件存在,且是一个块设备文件,返回真
-c file 若文件存在,且是一个字符设备文件,返回真
-d file 若文件存在,且是一个目录,返回真
-e file 判断文件是否存在
-f file 若文件存在,且是一个普通文件,返回真
-r file 文件是否存在,且可读
-w file 文件是否存在,且可写
-x file 文件是否存在,且可执行
file1 -nt file2 file1是否比file2新
file1 -ot file2 file1是否比file2旧
多条件的表示:
[ condition1 -a condition2 ]
等介于 [ condition1 ] && [ condition2 ]
[ condition1 -o condition2 ]
等介于 [ condition1 ] | | [ condition2 ]
不可以
[ condition1 && condition2 ]
但是,可以
[[ condition1 && condition2 ]]
练习:1、写一个程序,输入三个数,显示其中较大的那个数。
echo \"enter the first number of the three:first\" #read v1
#echo \"enter the second number of the three:second\" #read v2
#echo \"enter the third number of the three:third\" #read v3
#max=$v1
#if [ $v1 -lt $v2 ] # then
# max=$v2 #fi
# if [ $v1 -lt $v3 ]
# then
# max=$v3 # fi
#if [ $2 -lt $v3 ] # then
# max=$v3 n=3 #fi
#echo \"the biggest one is the $n one $max\"
2、写一个程序,判断参数文件是否存在,如果存在的话,显示其
内容如果不存在,则显示“文件不存在”
!#/bin/bash clear echo \"\"
if [ $# -ne 1 ] then
echo \"can shu wrong\" fi if [ -r $1 ]
then
echo \"file cun zai nei rong ru xia \" cat $1
else echo \"$1 not exsit\" fi
3、写一个程序myservice.sh 模拟service 的执行过程
输入myservice.sh xx start (xx为输入的任一服务名)
显示 xx start ...
输入myservice.sh xx stop
显示 xx stop ...
输入myservice.sh xx restart
显示 xx restart ...
只后一个参数只接收start,stop,restart输入其它值是提示错误
!#/bin/bash clear echo \"\"
if [ $# -ne 1 ]
then
echo \"can shu wrong\" fi if [ -r $1 ] then
echo \"file cun zai nei rong ru xia \" cat $1
else echo \"$1 not exsit\" fi
4、写一个程序判断apache是否启动,如果没有启动,则启动它
已启时给一个提示,apache服务已启动。
#!/bin/bash clear
a=`ps -ef | grep http| wc -l`
if [ $a -lt 2 ] then
echo \"the apache is stop\" else
echo \"the apache servic is open!\" fi 变量运算
字符运算
字符连接:
将变量直接按顺序输入,会自动连接起来
取字符串长度:
${#STR} expr length $STR
例:A=\"ALSKDFKLASDFJ“
echo ${#A}
或 expr length $A
取子串:
${STR:n} n表示位置,忽略前n个字符
${STR:n:m} 忽略前n个,取m个
${STR:(-n)} 取最后的n个
${STR:(-n):m} 从最右边的n个开始取m个
删除操作:
echo ${STR#*r} #从左到右 ## 到最右 * 删除
echo ${STR##*r}
echo ${STR%/*}
数值运算
$[ ]
A=3
B=2
echo $[$A+$B]
$(( ))
echo $(($A*$B))
echo $(($A+$B))
*后面的字符表示删除到哪里 %从右到左 %% 到最左 * 删除 从右到左删除,删除的字符要在*前 cut 剪切文件(取其中的某一段)
格式:cut [选项] [文件名]
-c 字符
-f 字段
-d 字段分隔符
cut -d: -f1,2,7 /etc/passwd | head -5
case 多分支
语法:
case var in
pattern1)
commands
;;
pattern2)
commands
;;
*)
commands
;;
esac
执行流程:
判断var值与下面哪个pattern匹配,如果匹配的话,就执行其下的
commands,如果不匹配的话,有*,则执行*下的command
如果不匹配,也没有*,就什么都不做 for 循环
for var in word1 word2 word3 ... wordn do
commands done
C式for 循环
for ((var=x;condition;changevar)) do
commands done
如:for ((i=1;i<10;i++))
do
commands
done
while 循环
格式:while [ condition ]
do
commands
done
while [ $n -lt 101 ]
循环嵌套:
循环中包含循环,一个循环作为另一个循环的一部分。
练习:将/etc/下及其子目录下的所有conf文件,复制到/test中,并按顺序改名。
第一个被复制的的为xx.conf xx.conf1 xx.conf xx.conf2
#!/bin/bash # n=1
for i in `find /etc/ -name \"*.conf\"` do
a=`basename $i`
b=/test/$a$n
n=$[$n+1]
cp $i $b done
删除/home下所有的空文件,并给出删除文件的名字,和最后的统计,共删
了多少个
1 #!/bin/bash 2 #
3 files=`find /home -size 0`
4 lines=`find /home -size 0|wc -l`
5 echo \"一共有$lines空文件需要删除\"
6 echo \"删除的文件列表:\"
7 for file in $files 8 do
9 echo $file
10 rm -f $file 11 done
~
用while写一个求100内的奇数和
在/test下建三个文件,分别为111、222、333,每隔10秒钟,进行改名
111-->222 222-->333 333-->111
使用第四个变量来作为中间变量,用mv命令,sleep为时间休止命令
until 循环
直到型循环,直到条件满足就不再进行循环,与while刚才相反
格式:until [ condition ]
do
commands
done
执行流程:判断条件是不是不成立(或者讲返回值是不是非0),
不成立就执行循环体,条件成立了,就退出循环。
循环控制
break 跳出循环,中止当前循环
continue 跳过余下的语句,直接进行到下一轮
循环输出的处理
可在done末尾添加处理命令来实现(见/sh/3_3.sh)。 数组:
具有相同名字,不同下标变量的集合。
数组定义:
方法一:与普通变量一样,直接赋值。
值用()括起来,值之间用空格分开。
如:mytest=(one two three four five)
如值含有空隔,要用“”将值括起来
方法二:直接给元素赋值
mytest[0]=a
mytest[1]=b
mytest[2]=c
方法三:将方法一、二综合起来了
mytest=([0]=abcd [1]=df [2]=423)
方法四:用declare定义
declare -a mytest=(5 6 7 8)
declare不但可定义数组,还可定义其它变量
-a 定义数组
-f 定义函数
-i 定义为整数
-r 定义变量为只读
数组使用:
数组使用主要是使用其中的元素,使用时用:数组名[下标] 的形式
如果直接用数组名的话,默认取第一个元素。元素下标从0开始。
显示所有变量:echo ${mytest
即下标用*表示
获取数组元素个数:echo ${#mytest }
删除数组:unset 数组名
会将整个数组删掉
删除数组元素:unset ${mytest[2]}
数组复制:aa=(${bb }) 函数:
shell脚本编程中经常会用到一些相同的代码,如果这些代码比较短小的话
没太大的问题,但经常用到一些大段的相同代码,就会感到很麻烦了。
这时shell就引入的函数。函数可以理解成具有名字的代码块。调用时只要
输入函数名即可。
函数定义:
funcation funcation_name() {
commands }
funcation_name (){
commands
}
函数删除:
unset funcation_name
使用函数:
直接输入文件名即可。有参数的话,给定参数。
但要注意:定义必须要在使用之前,即先定义,后使用。
练习:写一程序打印 * * * * *
* *
* *
* *
*
打印一个等腰三角形
*
***
*****
*******
*********
定义一个函数,第一个参数指定打印的字符,第二个参数决定打印的个数
因篇幅问题不能全部显示,请点此查看更多更全内容