shell脚本的学习
- shell脚本: 本质 shell命令的 有序集合
- 一种解释型 语言 不需要编译
- 方便操作者 对重复性的操作进行 编程
- 一种无类型语言 变量没有类型 或 字符串类型
- 注意事项: 对标点符号 和 格式 非常严格 特别是空格
创建一个shell脚本步骤:
- 1. 创建一个普通文件 通常 后缀.sh
- touch hello.sh
- 2. 修改权限 添加可执行权限
- chmod 777 hello.sh
- 3. 写脚本
- vim hello.sh
- 第一行 #!/bin/bash
- 打印 echo "hello world"
- 4. 运行脚本 ./hello.sh
练习: 写一个创建脚本的脚本 创建mk.sh
变量: 多用于 代指文件名 各种名字 或参数 命令等
- 用户自定义变量:
- 变量定义 变量名=值 等号两边 没有空格
- 变量使用 引用其值 $变量名 本质是字符替换
#创建一个变量 赋值6.sh NAME=6.sh #变量使用 引用其值 $变量名 本质是字符串替换 echo $NAME
位置变量:
- $0 运行脚本的指令本身
- $1,$2,……$9 分别包含第一个到第九个命令行参数
#位置变量 echo "\$0=$0" echo "\$1=$1" echo "\$2=$2" echo "\$3=$3" echo "\$4=$4" echo "\$5=$5"
预定义变量: 有终端预先定义的一些变量
- 由系统保留和维护的一组特殊的变量,这些变量通常用于保存程序运行状态等
- $# 包含命令行参数的个数
- $@ 包含所有命令行参数:“$1,$2,……$9”
- $? 包含前一个命令的退出状态
- $* 包含所有命令行参数:“$1,$2,……$9”
- $$ 包含正在执行进程的ID号
#预定义变量 echo \$#=$# echo \$?=$? echo \$@=$@ echo \$*=$* echo \$$=$$
环境变量: 一组存储终端环境参数的 变量
- export 命令 可以打印输出 终端所有的环境变量
- PWD 存储当前工作路径
- USER 存储当前终端的登录用户
- HOME 存储当前用户的家目录
- PATH 存储当前终端 的命令搜索路径
gec@ubuntu:~/Linux基础/shell$ export | grep PWD declare -x OLDPWD="/home/gec/Linux基础" declare -x PWD="/home/gec/Linux基础/shell" gec@ubuntu:~/Linux基础/shell$ export | grep USER declare -x USER="gec" declare -x USERNAME="gec" gec@ubuntu:~/Linux基础/shell$ HOME HOME:未找到命令 gec@ubuntu:~/Linux基础/shell$ export | grep HOME declare -x HOME="/home/gec" gec@ubuntu:~/Linux基础/shell$ export | grep PATH declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" declare -x WINDOWPATH="2" gec@ubuntu:~/Linux基础/shell$
- echo $PATH
- /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/gcc-4.6.4/bin:/home/xwq/esp8266/xtensa-lx106-elf/bin:/home/xwq/.local/bin
shell脚本的 输入输出
- shell脚本的 输入输出:
- echo 输出字符串
- read 从终端读取字符串
shell中 的算数运算
- expr 数学表达式 每个符号与数值 间都要有空格分开
- 支持 + - \* / % 但只能做 整数运算 不能做小数运算
shell脚本的程序结构
if结构
- 程序结构:
- if 结构
- if [ 表达式 ]
- then
- 命令块1
- else
- 命令块2
- fi
- 没有else 可以省略
- if [ 表达式 ]
- then
- 命令块1
- fi
shell 表达式
- 字符串测试
- s1 == s2 测试两个字符串的内容是否完全一样
- s1 != s2 测试两个字符串的内容是否有差异
- -z s1 测试s1 字符串的长度是否为0
- -n s1 测试s1 字符串的长度是否不为0
- 整数测试
- a -eq b 测试a 与b 是否相等
- a -ne b 测试a 与b 是否不相等
- a -gt b 测试a 是否大于b
- a -ge b 测试a 是否大于等于b
- a -lt b 测试a 是否小于b
- a -le b 测试a 是否小于等于b
- note: test语句执行成功(满足条件) 返回结果0 失败返回1
- -d name 测试name 是否为一个目录
- -e name 测试一个文件是否存在
- -f name 测试name 是否为普通文件
- -L name 测试name 是否为符号链接
- -r name 测试name 文件是否存在且为可读
- -w name 测试name 文件是否存在且为可写
- -x name 测试name 文件是否存在且为可执行
- -s name 测试name 文件是否存在且其长度不为0
- f1 -nt f2 测试文件f1 是否比文件f2 更新
- f1 -ot f2 测试文件f1 是否比文件f2 更旧
- 练习 输入一个文件名 判断该文件 是否存在, 若存在 判断是否为 普通文件且是空的 则 删除它
#!/bin/bash #echo "请输入一个文件名" #read FILE FILE=$1 if [ -z $FILE ] then echo "UseAge:该脚本用于删除一个空的普通文件" echo "需要指定一个文件名参数" else echo "正在操作$FILE" if [ -e $FILE ] then echo "文件存在" if [ -f $FILE ] then echo "是普通文件" if [ -s $FILE ] then echo "文件有内容" else echo "文件没有内容, 删除$FILE" rm $FILE fi fi fi fi
case 多分支结构
- 结构:
- case $变量名 in
- 值1) 命令块1
- ;;
- 值2) 命令块2
- ;;
- ...
- *) 命令块n
- esac
- 运行逻辑 将变量中字符串 与 ) 左边的字符串比较 相等 就 执行后面的命令块
- 若 不相等 继续向后比较
- 值可以使用通配符
- 练习: 输入成绩 输出 优良中差
#!/bin/bash echo "请输入你的成绩:" read CJ case $CJ in 100) echo "成绩优秀" ;; 9?) echo "成绩优秀" ;; 8?) echo "成绩良好" ;; [76]?) echo "成绩中等" ;; *) echo "成绩差" esac
循环结构:
for循环
- for循环 结构1:
- for (( I=0;I<10;I++ ))
- do
- 循环命令块
- done
示例: 创建10个文件 文件名为 file_数.txt
#!/bin/bash
#创建10个txt结尾文件
for (( I=0;I<10;I++))
do
touch file_$I.txt
done
- 结构2:
- for 变量名 in 取值列表
- do
- 循环命令块
- done
- 取值列表: 以空格 回车 等分隔开的的字符串
- 每次循环 变量的值 就是 取值列表 中的一个
- 顺序的
示例: 打印输出 当前目录中 所有.sh 文件的内容都打印出来
#!/bin/bash
for FILE in `ls *.sh`
do
echo "======>$FILE<======"
cat $FILE
done
练习: 写一个脚本实现 将当前目录中 所有的 空的 普通文件 删除
#!/bin/bash
for FILE in `ls *.*`
do
./if.sh $FILE
done
while循环
- while循环:
- while [ 条件表达式 ]
- do
- 循环语句块
- done
- 与C的运行逻辑完全一样
- 循环控制语句 与C的break与continue关键字效果完全一样
- break
- continue
了解: shell 的函数
- 函数定义:
- 函数名()
- {
- 命令块
- }
- 函数调用
- 函数名
- 参数传递 使用位置变量
示例:
#!/bin/bash
NUM=20
#定义一个函数
fun()
{
A=20
echo NUM=$NUM
echo "this is a func"
return 0
}
ADD()
{
#A=20
C=`expr $1 + $2`
echo $C
return 0
# return 一个8bit的数0-255
# 用于传递函数执行是否成功
# 作为命令执行的状态 $?
}
# 调用函数
fun
# 该方式调用的 其中的变量将会继续沿用
RET=`ADD 10 23`
# 命令置换方式调用
# 函数中的变量不能在函数外引用
echo $?
echo RET=$RET
echo C=$C
echo A=$A