Linux shell 脚本编程
基本使用
脚本文件格式
- 第一行,顶格:#!/bin/bash
- 注释信息:#
- 代码注释:
- 缩进,适度添加空白行;
算术运算格式: +,-,*,/, **, %
- (1) let VAR=算术运算表达式
- (2) VAR=$[算术运算表达式]
- (3) VAR=$((算术运算表达式))
- (4) VAR=$(expr $ARG1 $OP $ARG2)
注意:有些时候乘法符号需要转义
增强型赋值:
变量做某种算术运算后回存至此变量中;
- let i=$i+#
- let i+=#
- +=,-=,*=, /=, %=
自增:
- VAR=$[$VAR+1]
- let VAR+=1
- let VAR++
自减:
- VAR=$[$VAR-1]
- let VAR-=1
- let VAR--
练习:
1 写一个脚本,完成如下功能:
- 添加三个用户;
- 求此三个用户的UID之和;
2、写一个脚本
计算/etc/passwd文件中的第10个用户和第20个用户的id号之和;
id1=$(head -10 /etc/passwd | tail -1 | cut -d: -f3) id2=$(head -20 /etc/passwd | tail -1 | cut -d: -f3)
3、写一个脚本
计算/etc/rc.d/init.d/functions和/etc/inittab文件的空白行数之和;
grep "^[[:space:]]*$" /etc/rc.d/init.d/functions | wc -l
条件测试:
- 判断某需求是否满足,需要由测试机制来实现;
如何编写测试表达式以实现所需的测试:
(1) 执行命令,并利用命令状态返回值来判断;
- 0:成功
- 1-255:失败
(2) 测试表达式
- test EXPRESSION
- [ EXPRESSION ]
- [[ EXPRESSION ]]
注意:EXPRESSION两端必须有空白字符,否则为语法错误
bash的测试类型
- 数值测试
- 字符串测试
- 文件测试
数值测试:数值比较
- -eq:是否等于; [ $num1 -eq $num2 ]
- -ne:是否不等于;
- -gt:是否大于;
- -ge:是否大于等于;
- -lt:是否小于;
- -le:是否小于等于;
字符串测试:
- ==:是否等于;
- >:是否大于;
- <:是否小于;
- !=:是否不等于;
- =~:左侧字符串是否能够被右侧的PATTERN所匹配;
- -z "STRING":判断指定的字串是否为空;空则为真,不空则假;
- -n "STRING":判断指定的字符串是否不空;不空则真,空则为假;
注意:
- (1) 字符串要加引用;
- (2) 要使用[[ ]];
文件测试:
存在性测试
- -a FILE
- -e FILE
文件的存在性测试,存在则为真,否则则为假;
存在性及类型测试
- -b FILE:是否存在并且为 块设备 文件;
- -c FILE:是否存在并且为 字符设备 文件;
- -d FILE:是否存在并且为 目录文件;
- -f FILE:是否存在并且为 普通文件;
- -h FILE或 -L FILE:是否存在并且为 符号链接文件;
- -p FILE:是否存在且为 命名管道文件;
- -S FILE:是否存在且为 套接字文件;
文件权限测试:
- -r FILE:是否存在并且 对当前用户可读;
- -w FILE:是否存在并且 对当前用户可写;
- -x FILE:是否存在并且 对当前用户可执行
特殊权限测试:
- -u FILE:是否存在并且 拥有suid权限;
- -g FILE:是否存在并且 拥有sgid权限;
- -k FILE:是否存在并且 拥有sticky权限;
文件是否有内容:
- -s FILE:是否有内容;
时间戳:
-N FILE:文件自从上一次读操作后是否被修改过;
从属关系测试:
- -O FILE:当前用户是否为文件的属主;
- -G FILE:当前用户是否属于文件的属组;
双目测试:
- FILE1 -ef FILE2:FILE1与FILE2是否指向同一个文件系统的相同inode的硬链接;
- FILE1 -nt FILE2:FILE1是否新于FILE2;
- FILE1 -ot FILE2:FILE1是否旧于FILE2;
组合测试条件:
逻辑运算:
第一种方式:
- COMMAND1 && COMMAND2
- COMMAND1 || COMMAND2
- ! COMMAND
- [ -O FILE ] && [ -r FILE ]
第二种方式:
- -a 逻辑与
- -o 逻辑或
- ! 取反
练习:将当前主机名称保存至hostName变量中
- 主机名如果为空,或者为localhost.localdomain,则将其设置为www.magedu.com;
hostName=$(hostname) [ -z "$hostName" -o "$hostName" == "localhost.localdomain" -o "$hostName" == "localhost" ] && hostname www.magedu.com
脚本的状态返回值:
默认是脚本中执行的最后一条件命令的状态返回值;
自定义状态退出状态码:
- exit [n]:n为自己指定的状态码;
注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;
向脚本传递参数:
位置参数变量
- myscript.sh argu1 argu2
引用方式:
- $1, $2, ..., ${10}, ${11}, ...
轮替:
- shift [n]:位置参数轮替;
写一脚本,通过命令传递两个文本文件路径给脚本,计算其空白行数之和;
#!/bin/bash # file1_lines=$(grep "^$" $1 | wc -l) file2_lines=$(grep "^$" $2 | wc -l) echo "Total blank lines: $[$file1_lines+$file2_lines]"
特殊变量:
- $0:脚本文件路径本身;
- $#:脚本参数的个数;
- $*:所有参数
- $@:所有参数
选择执行:
单分支的if语句:
if 测试条件 then 代码分支 fi
双分支的if语句:
if 测试条件; then 条件为真时执行的分支 else 条件为假时执行的分支 fi
示例:通过参数传递一个用户名给脚本,此用户不存时,则添加之
#!/bin/bash # if [ $# -lt 1 ]; then echo "At least one username." exit 2 fi if grep "^$1\>" /etc/passwd &> /dev/null; then echo "User $1 exists." else useradd $1 echo $1 | passwd --stdin $1 &> /dev/null echo "Add user $1 finished." fi
通过命令行参数给定两个数字,输出其中较大的数值
#!/bin/bash # if [ $# -lt 2 ]; then echo "Two integers." exit 2 fi declare -i max=$1 if [ $1 -lt $2 ]; then max=$2 fi echo "Max number: $max."
创建一个20G的文件系统,块大小为2048,文件系统ext4,卷标为TEST,要求此分区开机后自动挂载至/testing目录,且默认有acl挂载选项;
(1) 创建20G分区;
- fdisk /dev/sda
(2) 格式化:
mke2fs -t ext4 -b 2048 -L 'TEST' /dev/DEVICE
(3) 编辑/etc/fstab文件
- LABEL='TEST' /testing ext4 defaults,acl 0 0