shell编程的语法主要分为五个环节,分别是变量,字符串,运算符,流程控制,函数五大部分
shell编程的基础语法
一 变量
1.1 shell变量名
1. 变量名中不能用$(这个符号在shell中表示引用)
2. 变量名和等号之间不能有空格
username="张三"
3. 可以使用字母数字下划线,但是首字母不能以下划线开头
4. 不能使用bash里的关键字
5. 不能使用标点符号,中间不能有空格
1.2 使用shell变量
使用一个定义过的shell变量,在变量名的前面加上$
yourname=zhangsan
myname=lisi
echo $yourname
echo ${yourname}
# 加花括号可以识别变量边界
1.3只读变量
只读变量和Java里的常量很像,定义了之后,这个变量不能随便被赋值,或者被unset删除
readonly yourname
1.4 删除变量
只读变量不能山,普通变量可以删
unset myname
二 字符串
2.1 定义时最好用双引号
- 单引号转义时存在无法识别的问题,单引号中任何字符都会原样输出
#!/bin/bash
skill='java'
str='I am good at $skill'
echo $str
运行结果:
I am good at $skill
- 双引号里可以有变量,可以有转义字符
#!/bin/bash
skill='java'
str="I am good at $skill"
echo $str
运行
[root@localhost test]# sed -i ‘s/\r$//’ test1.sh
[root@localhost test]# ./test1.sh
I am good at java
2.2获取字符串长度
shell代码
#!/bin/bash
skill='java'
echo ${skill}
echo ${#skill}
输出结果
[root@localhost test]# sed -i ‘s/\r$//’ test1.sh
[root@localhost test]# ./test1.sh
java
4
2.3提取子字符串
shell代码
#!/bin/bash
skill='I like Java'
echo ${skill:2}
#substring(2)
#从第二个字符开始截取
echo ${skill:2:2}
#substring(2,2)
#从索引2处开始截取两个字符
输出结果
[root@localhost test]# sed -i ‘s/\r$//’ test1.sh
[root@localhost test]# ./test1.sh
kike Java
ki
2.4 查找子字符串
查找like字符串中字符i所在的位置
shell代码
#!/bin/bash
skill='like'
echo `expr index "$skill" i`
[root@localhost test]# sed -i ‘s/\r$//’ test1.sh
[root@localhost test]# ./test1.sh
2
三 运算符
虽然原生bash不支持数学运算,但是可以通过expr来实现
使用有两个个原则
- 表达式和运算符之间要有空格
- 完整的表达式要被飘号包含,飘号的位置在esc键的下边
3.1算数运算符
可以看一下图中的示范脚本,加减乘除取余赋值,==,!=
#!/bin/bash
skill='like'
a=8
b=9
# 加法 +
echo ` expr $a + $b `
# 减法 -
echo ` expr $a - $b `
# 乘法 *
echo ` expr $a \* $b `
# 除法 /
echo ` expr $b / $b `
# 取余 %
echo ` expr $b % $a `
# 赋值 =
echo skill
echo ` expr a=$b `
# 相等 == 返回值为true
#echo ` [ $a == $b ] `
# 不等 != 返回值为false
#echo ` [ $a!= $b ] `
3.2 关系运算符
这个主要分为三个类型,一是数字之间的关系,二是文件权限的关系,三是文件类型之间的关系
3.2.1 数字之间的关系
-eq (equal) 等于
-ne (not equal) 不等于
-lt (less than) 少于
-le (less equal) 少于等于
-gt (greater than) 大于
-ge (grater equal) 大于等于
3.2.2 文件权限
linux是一个多用户的系统,多用户要采用权限分段方式来执行指令,它用三组二进制数来表示一个文件的权限,如下图所示
- 简写是从000到777 ,三个位置分别代表rwx,读写执行
- 000 000 000 基本上什么操作都做不了
- 111 111 111 所有权限都可以 最高777,意思是所有者,组,公共,都可以
四 流程控制
4.1 if判定
#!/bin/bash
if [ "$1"x = "gu"x ]
then
echo "welcome, gu"
fi
# 输入第二个参数,表示年龄,判断属于哪个年龄段
if [ $2 -lt 18 ]
then
echo "未成年人"
elif [ $2 -lt 35 ]
then
echo "青年人"
elif [ $2 -lt 60 ]
then
echo "中年人"
else
echo "老年人"
fi
4.2 case语句
#!/bin/bash
case $1 in
1)
echo "one"
;;
2)
echo "two"
;;
3)
echo "three"
;;
*)
echo "number else"
;;
esac
4.3 for循环
#!/bin/bash
for IP in `cat /root/for/ip.txt` #ip文件为存放ip地址的
do
ping -c 3 -i 0.2 -w 3 $IP &>/dev/null #-c 3 ping3次主机 -i 0.2ping主机间隔 -w 3ping主机超时间隔
if [ $? -eq 0 ];then
echo "host $IP is up"
else echo "host $IP is down"
fi
done
4.4 while循环
#!/bin/sh
counter=5
factorial=1
while [ $counter -gt 0 ]
do
factorial=$(( $factorial * $counter ))
((counter--))
done
echo $factorial
五 函数
5.1 函数基础
sh文件
#!/bin/bash
# 定义函数
fun1 (){
echo "这是一个函数"
}
#调用函数
fun1
运行过程
[root@localhost test]# sed -i ‘s/\r$//’ test2.sh
[root@localhost test]# ./test2.sh
这是一个函数
5.2 自动化监视脚本
流量检测
#!/bin/bash
NIC=$1
echo -e " In ------ Out"
while true; do
OLD_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)
OLD_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)
sleep 1
NEW_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)
NEW_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)
IN=$(printf "%.1f%s" "$((($NEW_IN-$OLD_IN)/1024))" "KB/s")
OUT=$(printf "%.1f%s" "$((($NEW_OUT-$OLD_OUT)/1024))" "KB/s")
echo "$IN $OUT"
sleep 1
done
服务器初始化
#/bin/bash
# 设置时区并同步时间
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
if ! crontab -l |grep ntpdate &>/dev/null ; then
(echo "* 1 * * * ntpdate time.windows.com >/dev/null 2>&1";crontab -l) |crontab
fi
# 禁用selinux
sed -i '/SELINUX/{s/permissive/disabled/}' /etc/selinux/config
# 关闭防火墙
if egrep "7.[0-9]" /etc/redhat-release &>/dev/null; then
systemctl stop firewalld
systemctl disable firewalld
elif egrep "6.[0-9]" /etc/redhat-release &>/dev/null; then
service iptables stop
chkconfig iptables off
fi
# 历史命令显示操作时间
if ! grep HISTTIMEFORMAT /etc/bashrc; then
echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/bashrc
fi
# SSH超时时间
if ! grep "TMOUT=600" /etc/profile &>/dev/null; then
echo "export TMOUT=600" >> /etc/profile
fi
# 禁止root远程登录
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# 禁止定时任务向发送邮件
sed -i 's/^MAILTO=root/MAILTO=""/' /etc/crontab
# 设置最大打开文件数
if ! grep "* soft nofile 65535" /etc/security/limits.conf &>/dev/null; then
cat >> /etc/security/limits.conf << EOF
* soft nofile 65535
* hard nofile 65535
EOF
fi
# 系统内核优化
cat >> /etc/sysctl.conf << EOF
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_tw_buckets = 20480
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_fin_timeout = 20
EOF
# 减少SWAP使用
echo "0" > /proc/sys/vm/swappiness
# 安装系统性能分析工具及其他
yum install gcc make autoconf vim sysstat net-tools iostat if