shell脚本
脚本语言的特点(解释型语言):
脚本语言不需要编译,脚本语言的解析器可以直接阅读脚本语言并按照指令执行。解析器本身就是一个程序,被CPU执行的程序。脚本语言的特点注定脚本语言的执行效率不可能比编译型语言高。
脚本语言简单易学。
编译型语言:
C语言
C++语言
什么是 shell 脚本 ? linux命令的有序集合。用来批处理linux命令。
shell脚本是专门为了批处理linux指令而诞生的脚本语言,并不适合表达复杂逻辑。
shell脚本的解析器 bash
初识shell脚本
告诉计算机,我接下来写的东西是一个脚本。
注意:后面有空格有时会有错误!
开头
#!bin/bash
.sh 是脚本的后缀名
创建脚本
vi text.sh
写指令
clear 清屏
ls 查看当前文件
date 打印当前时间
touch files.txt 创建一个txt文件
脚本执行
默认脚本文件没有权限,需要增加执行权限。
chomd +x text.sh
执行脚本
./text.sh
注释:
如果需要在脚本中添加注释,在前面加一个#
变量
1.为了方便标识变量,变量名通常用大写字符
2.不能以数字开头,开头必须是字母或下划线
3.不能使用标点符号
echo 表示输出 类似于printf
等号的两边不能有空格
没有$ 表示直接显示
前面加$ 表示变量的值
#!/bin/bash
NUM=2
echo NUM #显示内容NUM
echo $NUM #显示变量的值2
位置参数 与 预设参数
当我们执行脚本时 可以给多个参数 这个参数可以在脚本中使用
位置参数:0 1 2 3 4 ...
#!/bin/bash
NUM1=$0 #./text.sh
echo $NUM1
NUM2=$1 #1
echo $NUM2
NUM3=$2 #2
echo $NUM3
在运行上面程序时 可以预设参数
./text.sh 1 2
| | |
$0 $1 $2
参数位置的值,赋值给指定的变量
预设变量:#*
$# 可以看输入参数的个数(没有0位的参数)
$* 可以看到所有的参数,用空格隔开,把所有的参数保存到预设变量中(没有0位参数)
练习
请编写shell脚本: 创建目录文件,目录文件的名字由位置参数决定。
创建完目录之后,在目录中再创建一个普通文件,名字也由位置参数决定。
#!/bin/bash
mkdir $1
touuch $1/$2
编写一个脚本,复制一个文件夹到另外一个路径。
文件夹的名字和路径,由位置参数决定。
#!/bin/bash
cp -r $1 $2
功能语句
输出: echo 输出一行
输入: read 输入
程序运行后,等待输入值,赋值给变量。输入时,不能有回车。
#!/bin/bash
read NUM1 NUM2 #输入的两个参数
echo $NUM1 #变量的值1
echo $NUM2 #变量的值2
./text.sh 12 23
| |
NUM1 NUM2
可以增加提示
#!/bin/bash
read -p "please input:" NUM1 NUM2
echo $NUM1
echo $NUM2
练习
创建一个目录文件,然后,在此目录下创建一个普通文件。 文件名字由输入决定。
#!/bin/bash
read -p"please input" DIR FILE
mkdir $DIR
touch $DIR/$FILE
echo success
" "与 ' '
两者都表示字符串
" "不完全输出 用变量值替代变量 等价不写" "
' '完全输出 完全按照写的样子输出
练习
1.使用位置参数,创建一个文件夹。
2.输入一个文件名 在刚才创建的文件夹中,创建该文件
#!/bin/bash
mkdir $1
read -p"please input" FILENAME
touch $1/$FILENAME
shell 计算
shell脚本并不善于计算
` `反引号
表示运算
#!/bin/bash
NAME=`ls/`
echo $NAME #`ls/`执行的结构赋值给NAME并打印
expr 运算语句
expression表达式
#!/bin/bash
NUM1=1
NUM2=2
X=`expr $NUM1 + $NUM2` # expr表示运算的表达式
echo $X
赋值符号的左右两侧一定 不要 有 空格!!!
运算符两侧一定 一定 要 放空格
乘法运算符号: '*' 或者 \* 因为*在linux命令中是通配符,所以shell脚本中的乘法不能用*
#!/bin/bash
NUM1=1
NUM2=2
X=`expr $NUM1 + $NUM2`
echo $X
X=`expr $NUM1 - $NUM2`
echo $X
X=`expr $NUM1 '*' $NUM2` # 乘法有两种表达形式
echo $X
X=`expr $NUM1 \* $NUM2`
echo $X
X=`expr $NUM1 / $NUM2`
echo $X
练习
使用read输入两个数
计算两个数的(加、减、乘(\**)、除、模除)
#!/bin/bash
read -p "please input num" NUM1 NUM2
X=`expr $NUM1 + $NUM2`
echo $X
X=`expr $NUM1 - $NUM2`
echo $X
X=`expr $NUM1 '*' $NUM2` # 乘法有两种表达形式
echo $X
X=`expr $NUM1 / $NUM2`
echo $X
X=`expr $NUM1 % $NUM2`
echo $X
######使用位置参数
#!/bin/bash
read -p "please input num" $1 $2
NUM1=$1
NUM2=$2
X=`expr $NUM1 + $NUM2`
echo $X
X=`expr $NUM1 - $NUM2`
echo $X
X=`expr $NUM1 '*' $NUM2` # 乘法有两种表达形式
echo $X
X=`expr $NUM1 / $NUM2`
echo $X
X=`expr $NUM1 % $NUM2`
echo $X
脚本语言执行到语法错误的那行代码时才会报错,之前没有错误的代码都执行完了。
shell的if
if的格式
[ ] 两边注意空格
if [ 条件 ]
then
语句
elif
then
语句
...
else # 没有then
语句
fi # if反着写 表示if语句结束
if判断的对象
if 语句可以判断 字符串 数值 文件的类型
字符串
#!/bin/bash
if [ "ads" = "adsd" ] #判断字符串 = 只能判断字符串
then
cheo "equal"
else
echo "no equal"
fi
-z 判断字符串是否为空
#!/bin/bash
read -p "please input" NAME
if [ -z $NAME ]
then
cheo "emtpy"
else
echo "no emtpy"
fi
请输入你的名字,判定是否是“xiaoming”同学。
是 显示 yes
否 显示 no
空 显示empty
#!/bin/bash
read -p "please input:" NAME
if [ -z $NAME ] # 判断字符串是否为空
then
echo "empty"
elif [ $NAME = "xiaoming" ]
then
echo "yes"
else
echo "no"
fi
数值
-eq 相等 equal
-ne 不等 not equal
-gt 大于 greater than
-ge 大于等于 greater equal
-lt 小于 less than
-le 小于等于 less equal
#!/bin/bash
read -p "please input:" NUM
if [ $NUM -eq 10 ]
then
echo "等于10"
fi
if [ $NUM -ne 10 ]
then
echo "不等于10"
fi
if [ $NUM -gt 10 ]
then
echo "大于10"
fi
if [ $NUM -ge 10 ]
then
echo "大于等于10"
fi
if [ $NUM -lt 10 ]
then
echo "小于10"
fi
if [ $NUM -le 10 ]
then
echo "小于等于10"
fi
练习
输入两个数A B,判定大小。
A>B 输出 “A>B”
A==B 输出“A==B”
A<B 输出“A<B”
#!/bin/bash
read -p "please input" NUM1 NUM2
if [ NUM1 -gt NUM2 ]
then
cheo "A>B"
elif [ NUM1 -eq NUM2 ]
then
echo "A==B"
else
echo "A<B"
fi
输入一个数值,判定此数值是否是偶数。
#!/bin/bash
read -p "please input:" NUM
if [ `expr $NUM % 2` -eq 0 ]
then
echo "yes"
else
echo "no"
fi
文件测试
测试语句:
-f filename 判断文件是否为普通文件 file
-d filename 判断文件是否为目录文件 directory
-e filename 判断文件是否存在 exist
-L filename 判断文件是否为链接文件 link
-w filename 判断是否有写权限 write
-x filename 判断是否有执行权限 excute
-r filename 判断是否有读权限 read
练习
#!/bin/bash
read -p "please input" FILENAME
if [ -e $FILENAME ]
then
echo "exist"
if [ -d $FILENAME ]
then
echo "dir"
elif [ -f $FILENAME ]
then
echo "file"
fi
else
echo "no exist"
fi
请输入文件名称,判定此文件是否拥有执行权限。
#!/bin/bash
read -p "please input" FILENAME
if [ -x $FILENAME ]
then
echo "yes"
else
echo "no"
fi
创建一个目录文件,进入目录后,再创建个普通文件。 目录文件和普通文件名都是输入的。
添加条件: 1. 判断该目录文件是否存在:如果存在,就不创建。如果不存在,创建。
判断普通文件是否存在。
#!/bin/bash
read -p "please input" DIR FILE
if [ -e $DIR ]
then
echo "exist"
else
echo "no exist"
mkdir $DIR
fi
if [ -e $DIR/$FILE ]
then
echo "exist"
else
echo "no exist"
touch $DIR/$FILE
fi
shell 中的case
等同于C语言的switch-case
case $变量 in # 判断变量的值
a) # 值是什么
语句
;; # 相当于break 但是 不能省略
b)
语句
;;
*) # 相当于default
语句
;;
esac # 表示结束 case 反写
练习
编写shell脚本,实现按键 asdw 控制输出上下左右
#!/bin/bash
read -p "please input" NAME
case $NAME in
a)
echo'左'
;;
s)
echo'下'
;;
w)
echo'上'
;;
d)
echo'右'
;;
esac
编写脚本,实现简单的计算功能。
示例:
./test.sh 3 + 4 输出7
./test.sh 3 - 4 输出-1
计算乘法不能输入* 可以输入x表示乘法
使用位置参数
#!/bin/bash
case $2 in
+)
echo `expr $1 + $3`
;;
-)
echo `expr $1 - $3`
;;
x)
echo `expr $1 '*' $3`
;;
/)
echo `expr $1 / $3`
;;
%)
echo `expr $1 % $3`
;;
esac
使用read 编写以上程序
#!/bin/bash
read -p "please input" SUM1 TYPE SUM3
case $TYPE in
+)
echo `expr SUM1 + SUM3`
;;
-)
echo `expr SUM1 - SUM3`
;;
x)
echo `expr SUM1 '*' SUM3`
;;
/)
echo `expr SUM1 / SUM3`
;;
%)
echo `expr SUM1 % SUM3`
;;
esac
shell中的循环
for循环
for NAME in $(单词表)
do
语句
done
示例
#!/bin/bash
LIST="a b c d"
for NAME in $LIST
do
echo "$NAME"
done
练习
请输出 根目录下的所有文件名称 使用for循环
首先使用ls /命令获得根目录下所有文件的名称
#!/bin/bash
LIST=`ls /`
for NAME in $LIST
do
echo $NAME
done
请使用循环实现,将 day7 目录中的所有文件,都拷贝到 day8 中。(不使用 cp -r )用循环一个一个文件拷贝
可以手动创建day7和day8,然后手动在day7创建一些文件
#!/bin/bash
mkdir day7 day8
touch day7/a{1..9}
LIST=`ls day7`
for FILE in $LIST
do
if [ -f day7/$FILE ]
then
cp day7/$FILE day8
fi
if [ -d day7/$FILE ]
cp -r day7/$FILE day8
fi
done
echo "success"
whiie循环格式
while [ 条件 ]
do
语句
done
#!/bin/bash
M=1
while [ $M -le 10 ]
do
echo $M
M=`expr $M + 1`
done
练习
求 1~100 的和。 (while)
#!/bin/bash
M=0
SUM=0
while [ $M -lt 100 ]
do
M=`expr $M + 1`
SUM=`expr $SUM + $M`
done
echo $SUM
使用 while 完成功能: 创建 temp1 ~ temp9 九个文件夹
提示:创建文件不能使用通配符,通配符只能用来查找
#!/bin/bash
M=1
while [ $M lt 10 ]
do
mkdir temp$M
M=`expr $M + 1`
done
break
break 直接退出当前循环
#!bin/bash
M=1
while [ $M -lt 10 ]
do
if [ $M -eq 5 ]
then
break
fi
echo $M
M=`expr $M + 1`
done
break n 直接退出几层循环
#!/bin/bash
M=1
while [ $M -lt 5 ]
do
echo $M
N=1
while [ $N -lt 5 ]
do
echo $N
if [ $N -eq 3 ]
then
break 2
fi
N=`expr $N + 1`
done
M=`expr $M + 1`
done
死循环
while [ 1 ]
文件不存在
if [ ! -e $FILENAME ]
文件存在 并且 是一个文件夹
if [ -e $FILENAME -a -d $FILENAME ]
shell 综合练习
编写一个弹出式菜单的shell程序并实现其简单的菜单功能
* MENU *
* 1.copy 2.rename *
* 3.remove 4.exit *
输入时不能写 ~
即用户按下数字1,复制
输入被复制的文件名,和复制到的路径(需要判断是否是文件夹)
输入数字2,改名
输入要改名的文件,改后的名字
输入数字3 删除
输入要删除的文件(需要判断是否是文件夹)
输入数字4,退出
结束程序 结束循环
#!/bin/bash
while [ 1 ]
do
echo '------------------------'
echo '*MENU*'
echo '*1.copy 2.rename*'
echo '*3.remove 4.exit*'
echo '------------------------'
read -p "please input" NUM
case $NUM in
1)
echo 'copy'
read -p "please innput" FILENAME FILEADD
if [ -e $FILENAME -a -f $FILENAME ]
then
cp $FILENAME $FILEADD
echo "copy file success~"
elif [ -e FILENAME -d FILENAME ]
then
cp -r $FILENAME $FILEADD
echo "copy dir success~"
else
echo"filename error"
fi
;;
2)
echo 'rename'
read -p "please innput" OLDNAME NEWNAME
if [ -e $OLDNAME -a ! -e $NEWNAME ]
then
mv $OLDNAME $NEWNAME
echo "update success~"
else
echo "filename error~"
fi
;;
3)
echo 'remove'
read -p "please innput" NAME
if [ -e $NAME -a -f $NAME ]
then
rm $NAME
echo "remove file succesee~"
elif [ -e $NAME -a -d $NAME ]
then
rm -r $NAME
echo "remove dir success~"
else
echo "remove error~"
fi
;;
4)
echo 'exit'
braek
;;
esac
done
shell 总结
shell (壳) 终端用来解释并执行linux命令
首先 用户在命令提示符下键入命令文本,开始于shell进行交互;
接着,shell将用户的命令或是按键转化为内核所理解的命令,操作系统做出响应,直到控制相关的硬件设备,最后,shell将结果提交给用户。