Shell脚本编程 简介
Linux 的 Shell 种类众多,常见的有:
Bourne Shell(/usr/bin/sh或/bin/sh) Bourne Again Shell(/bin/bash) C Shell(/usr/bin/csh) K Shell(/usr/bin/ksh) Shell for Root(/sbin/sh) 程序编程风格
过程式:以指令为中心,数据服务于命令 对象式:以数据为中心,命令服务于数据 shell是一种过程式编程 过程式编程
编程语言分类
编译型语言 解释型语言(shell是一种解释型语言)
运行脚本
给予执行权限,通过具体的文件路径指定文件执行
直接运行解释器,将脚本作为解释器程序的参数运行
bash退出状态码
范围是0-255
脚本中一旦遇到exit命令,脚本会立即终止,终止退出状态取决于exit命令后面的数字
如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态
变量 变量命名 1 2 3 4 5 6 7 8 9 10 11 12 有效命名: RUNOOB LD_LIBRARY_PATH _var var2 无效命名: ?var=123 user*name=runoob 语句给变量赋值for file in `ls /etc` 或for file in $(ls /etc)
使用变量 1 2 3 4 5 6 7 8 9 10 定义变量: your_name="eagles" 使用变量:echo $your_name echo ${your_name} 建议使用{}号作边界for skill in Ada Coffe Action Java; do echo "I am good at ${skill} Script" done 如果使用$skillScript ,则将会输出空值
只读变量 1 2 3 4 5 #!/bin/bash myUrl="http://www.google.com" readonly myUrl myUrl="http://www.runoob.com" 执行脚本后,显示只读变量无法修改
删除变量 1 2 3 4 #!/bin/sh myUrl="http://www.runoob.com" unset myUrlecho $myUrl
变量种类 本地变量:生效范围仅为当前shell进程;(其他shell,当前的子sehll进程均无效)
环境变量:生效范围为当前shell进程及子进程
变量声明1:export name = “value” 变量声明2:declare -x name = “value” bash中有许多内建的变量环境:SHELL,PATH等等 局部变量:生效范围为当前shell进程中某代码片断(通常指函数)
位置变量: 2…来表示,让脚本在脚本代码中调用通过命令行传递给它的参数;
特殊变量:? 0 * @ #
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $1 ,$2 ,…:对应调用第1,第2等参数$0 :命令本身 $*:传递给脚本的所有参数(把所有参数当作整体)$@ :传递给脚本的所有参数$# :传递给脚本的参数的个数 案例1: myecho.shecho "命令本身是:$0 " echo "第一个参数是:$1 " echo "第二个参数是:$2 " echo "一共有$# 个参数" echo "所有参数是:$@ " 案例2:判断所给文件的行数 linecount.sh linecount="$(wc -l $1|cut -d' ' -f1) " echo "This file have ${linecount} lines"
数组 1 2 3 4 5 6 语法格式:array_name=(value1 ... valuen) 示例: my_array=(A B C D) array_name[0]=value0 array_name[1]=value1 array_name[2]=value2
1 2 3 4 5 6 7 8 读取数组:${array_name[index]} 获取数组中的所有元素: my_array[0]=A my_array[1]=B my_array[2]=C my_array[3]=Decho "数组的元素为: ${my_array[*]} " echo "数组的元素为: ${my_array[@]} "
1 2 3 4 5 6 7 获取数组的长度: my_array[0]=A my_array[1]=B my_array[2]=C my_array[3]=Decho "数组元素个数为: ${#my_array[*]} " echo "数组元素个数为: ${#my_array[@]} "
算数运算 1 2 3 4 5 + ‐ * / % ** ... 增强赋值: +=,‐=,*=,/=,%= 乘法符号有些场景中需要转义 : *\ bash有内建随机数生成器:$RANDOM
1 2 3 4 5 6 7 8 9 (1) let var(变量名)=算术表达式 (2) var=$[算术表达式] (3) var=$((算术表达式)) (4) var=$(expr arg1 arg2 arg3 …) var=$(expr 1 + 2)expr 本身是一个命令,可以直接进行运算 [root@centos73 ~] 1+2 [root@centos73 ~] 3
1 2 3 4 5 练习1:计算/etc/passwd文件中第10个用户的第20个用户的ID之和 练习2:传递两个文件路径参数给脚本,计算这两个文件之中所有空白行之和 练习3:统计/etc/,/var/,/usr/目录下有多少目录和文件
条件测试 测试命令:test EXPERSSION
1 2 3 4 5 6 7 8 num1=100 num2=100if test $[num1] -eq $[num2]then echo '两个数相等!' else echo '两个数不相等!' fi
数值测试 ‐gt:是否大于
‐ge:是否大于等于
‐eq:是否等于
‐ne:是否不等于
‐lt:是否小于
‐le:是否小于等于
练习题,比较两个数的大小
1 2 3 4 5 6 7 8 9 10 [root@localhost ~]read -p "请输入两个整数" num1 num2if [ $num1 -gt $num2 ];then echo "$num1 > $num2 " elif [ $num1 -lt $num2 ];then echo "$num1 < $num2 " else echo "$num1 = $num2 " fi
字符串测试 1 2 3 4 5 6 7 8 ==:是否等于 >:是否大于 <:是否小于 !=:是否不等于 =~:左侧字符串是否能够被右侧的PATTERN所匹配 Note:此表达式一般用于[[ ]]中 ‐z “STRING”:测试字符串是否为空,空则为真,不空则为假 ‐n “STRING”:测试字符串是否不空,不空则为真,空则为假
文件测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 简单的存在性测试: ‐a FILE :文件存在性测试,存在为真,否则为假 存在性及类型测试: ‐b FLIE:是否存在且为块设备文件; ‐c FILE:是否存在且为字符设备文件; ‐d FILE:是否存在且为目录文件; ‐f FILE:是否存在且为普通文件; ‐h FILE 或 ‐L FILE : 存在且为符号链接文件; ‐p FIEL :是否存在且为命名管道文件; ‐S FILE:是否存在且为套接文件; 文件权限测试: ‐r FILE:是否存在且可读 ‐w FILE:是否存在且可写 ‐x FILE:是否存在可执行 文件特殊权限测试: ‐u FILE:是否存在且拥有suid权限; ‐g FILE:是否存在且拥有sgid权限; ‐k FILE:是否存在且拥有sticky权限; 文件大小测试: ‐s FILE:是否存在且非空 文件是否打开: ‐fd:fd表示文件描述符是否已经打开且与某终端相关 ‐N FILE:文件自动上一次读取之后是否被修改过; ‐O FILE:当前用户是否为文件的属主; ‐G FILE:当前有效用户是否为文件数组; 双目测试: FILE1 ‐ef FILE2 :FILE1与FILE2是否指向同一个设备上的相同inode FILE1 ‐nt FILE2:FILE1是否新于FILE2 FILE1 ‐ot FILE2:FILE1是否旧于FILE2
组合测试条件 1 2 3 4 5 6 7 8 9 10 11 12 逻辑运算符: &&代表的意思是当前一个命令执行成功时会继续执行后续的命令,当前一个命令执行失败的时候不会执行后续的命令 ||代表的意思是当前一个命令执行成功时不会继续执行后续的命令,当前一个命令执行失败的时候会执行后续的命令 第一种方式: COMMAND1 && COMMAND2 COMMAND1 || COMMAND2 ! COMMAND 第二种方式: EXPRESSION1 ‐a EXPRESSION2 EXPRESSION1 ‐o EXPRESSION2 ! EXPRESSION Note:必须使用测试命令进行
选择执行 1 2 3 if 判断条件;then 条件为真的分支代码fi
1 2 3 4 5 if 判断条件;then 条件为真的分支代码else 条件为假的分支代码fi
1 2 3 4 5 6 7 if 判断条件;then 条件为真的分支代码elif 判断条件;then 条件为真的分支代码else 条件为假的分支代码fi
1 2 3 4 练习1:判断两个数是否相等 Note:if 经常会与test 命令一起使用 练习2:判断用户是否存在,如果不存在添加用户,并设置密码和用户相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 read -p "请输入用户名:" userid $user &> /dev/null thing="$(echo $?) " if test $[thing] -eq 0then echo "用户已存在" else useradd $user echo $user | passwd --stdin $user &>/dev/null echo -e "账户已id成功创建\n" echo "密码已更新为账户名" $user fi
用户交互 read命令 常用选项:
‐a:将内容读入到数组中echo ‐n “Input muliple values into an array:” read ‐a array echo "get $