一、bash中的变量
变量类型:
- 本地变量:只对当前shell进程有效,对其子shell以及其它shell都无效;
定义变量:[set]Var_name="value"
变量赋值的3种方式:
(1)可以是直接字串name="username"
(2)变量引用:name=$username,把变量username的值赋给name
(3)命令引用:name=`COMMAND` ,name=$(COMMAND)
引用变量:${name}或$name
如果在字符串中引用变量:
""(双引号):弱引用,其中的变量引用会被替换为变量值
' '(单引号):强引用,其中的变量引用不会被替换为变量值,而保留原字符串
显示已定义的所有变量:
# set
撤销变量:unset Var_name
unset -f 函数名 #删除函数
- 局部变量:local Var_name="value"
- 环境变量:使用export命名的的变量,对当前shell进程及其子shell有效
定义环境变量三种方法:
1、export Var_name="Value"
2、Var_name="Value"
export Var_name
3、declare -x Var_name="Value"
- 只读变量:不能unset,只能退出当前shell
readonly name
declare -r name
- 位置变量
如:/tmp/test.sh 3 89
$0:脚本名称自身,执行脚本所用的目录如./xx.sh或者/sh/xx.sh
$1:脚本第一个参数,3,以空格隔开的参数
$2:脚本第二个参数,89
${10}:脚本第10个参数,以后都需要加{}
$#:参数的个数
$*:脚本的所有参数,把所有的脚本参数当作一个字符串,当把这个参数传给第二个脚本的时候,相当于一个参数
$@:脚本的所有参数,每个参数为独立字符串,当把这个参数传递给第二个脚本的时候,还是相当于原来的n个独立的参数
注意:$@ $* 只在被双引号包起来的时候才会有差异
- 特殊变量:
$?:上一条命令的执行状态返回值
状态用数字来表示:0-255
0:成功
1-255:失败,1,2,127,255 是预留的,其他的可以自己定义
bash中变量的命名要求:
1、只能使用数字、字母和下划线组成
2、不能以数字开头
3、不能使用程序中的关键字
4、区分大小写
5、见名知义:例如:totalWeigt
注意:变量在赋值时不能使用$。
例如$name=wang ×错误
name=wang √正确
二、bash的算数运算
bash实现算数运算的几种方法:
(1)let varName=算术表达式
(2)varName=$[算术表达式]
(3)varName=$((算术表达式))
(4)varName=`expr $num1 + $num2` #"+"两端要有空格
(5)declare -i var=数值
(6)echo "算数表达式" | bc
bash中的算数运算符:
+ 加
- 减
* 乘
/ 除
% 取余数
** 乘方
let totalWeight+=2,自加并赋值,相当于let totalWeight= totalWeight +2。以此类推
+=
-=
*=
/=
%=
三、bash中的逻辑运算
判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程
评估布尔声明,以便用在条件性执行中
若真,则返回0
若假,则返回1
测试命令:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
注意:EXPRESSION前后必须有空白字符
数值测试
-v VAR 变量VAR是否设置
-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
字符串测试
= 是否等于
> ascii码是否大于ascii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
-z "STRING" 字符串是否为空,空为真,不空为假
-n "STRING" 字符串是否不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号
文件测试
存在性测试
-a FILE:同-e
-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: 是否存在且非空
文件是否打开:
-t fd: fd文件描述符是否在某终端已经打开
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
双目测试:
FILE1 -efFILE2: FILE1是否是FILE2的硬链接
FILE1 -ntFILE2: FILE1是否新于FILE2(mtime)
FILE1 -otFILE2: FILE1是否旧于FILE2
组合条件测试
第一种方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -f “$FILE” ] && [[ “$FILE”=~ .*.sh$ ]]
第二种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行,[[ ]] 不支持
四、编程练习
1、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到 /root/etcYYYY-mm-dd中
# cat /root/bin/backup.sh #!/bin/bash target_dir="/root/etc`date +%F`.tar.gz" tar -zcf $target_dir /etc
2、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和允许普通用户登录系统
# cat /root/bin/nologin.sh #!/bin/bash [ -e /etc/nologin ] || touch /etc/nologin # cat /root/bin/login.sh #!/bin/bash [ -e /etc/nologin ] && mv /etc/nologin{,.bak-`date +%F`}
3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
# vim /root/bin/disk.sh #!/bin/bash disk_and_num=`df -h | grep "/dev/sd" | tr -s " " "%" | cut -d"%" -f1,5 | sort -t"%" -k2 -nr | head -1` disk=`echo $disk_and_num | cut -d% -f1` num=`echo $disk_and_num | cut -d% -f2` echo "The most usage of dis is $disk and the rate is ${num}%"