---. 1 root root 51 1月 19 13:58 echo_test.sh
[root@centOS7 shell01]# ./echo_test.sh # 有了权限就直接运行
hello world
2.解释器直接运行(不需要给权限)
```shell
[root@centOS7 shell01]# chmod 644 echo_test.sh # 把权限取消
[root@centOS7 shell01]# ll echo_test.sh # 查看权限
-rw-r--r--. 1 root root 51 1月 19 13:58 echo_test.sh
[root@centOS7 shell01]# bash echo_test.sh # 使用解释器运行shell脚本
hello world
[root@centOS7 shell01]# sh echo_test.sh # 使用解释器运行shell脚本
hello world
shell中的特殊符号
~: 家目录 # cd ~ 代表进入用户家目录
!: 执行历史命令 !!执行上一条命令
$: 变量中取内容符
+ - * / %: 对应数学运算符 加 减 乘 除 取余
&: 后台执行
*: 星号是shell 通配符 匹配所有
?: 问号是shell通配符 匹配除回车以外的一个字符
;: 分号可以在shell中一行执行多个命令,命令之间用分号隔开
|: 管道符,上一个命令的输出作为下一个命令的输入 cat filename | grep "abc"
\: 转义字符
[root@centOS7 shell01]# expr 3 * 3
expr: 语法错误
[root@centOS7 shell01]# expr 3 \* 3 #进行转义,转成乘号
9
``: 反引号 命令中执行命令 echo "today is `date+%F`"
'': 单引号,脚本中字符串要用单引号引起来,但是不同于双引号的是, 单引号不解释变量
"": 双引号 脚本中出现的字符串可以用双引号引起来
shell中的管道应用
管道符|:很多组合命令都需要通过管道来实现完成输出,管道符其实就是下一个命令对上一个命令的输出做处理。
[root@centOS7 shell01]# cat /etc/passwd | grep "root" #将检索出来的信息通过管道给grep,通过筛选“root”打印出结果
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
shell重定向
> 重定向输入 覆盖原数据
>> 重定向追加输入,在原数据的末尾添加
< 重定向输出 wc -l < /etc/passwd
<< 重定向追加输出 fdisk /dev/sdb <<EOF ......... EOF
# > 会覆盖原有的数据
[root@centOS7 shell01]# echo hello haha > ./text.txt
[root@centOS7 shell01]# cat text.txt
hello haha
[root@centOS7 shell01]# echo world > ./text.txt
[root@centOS7 shell01]# cat text.txt
world
# >> 在原有的数据末尾追加
[root@centOS7 shell01]# echo world >> ./text.txt
[root@centOS7 shell01]# echo world >> ./text.txt
[root@centOS7 shell01]# cat text.txt
world
world
world
# <
[root@centOS7 shell01]# wc < text.txt
3 3 18
[root@centOS7 shell01]# wc text.txt
3 3 18 text.txt
shell数学运算
expr命令:只能做整数运算,格式比较古板,运算符与数字之间需要空格
[root@centOS7 shell01]# expr 1 + 2
3
[root@centOS7 shell01]# expr 1 - 2
-1
[root@centOS7 shell01]# expr 10 * 3 #必须进行转义
expr: 语法错误
[root@centOS7 shell01]# expr 10 \* 3
30
[root@centOS7 shell01]# expr 10 % 3
1
使用bc计算器处理浮点运算,scale=2代表小数点保留两位
[root@centOS7 shell01]# echo "scale=2;3+100"|bc #脚本中使用管道符进行计算,控制台使用bc命令直接进入交互模式计算
103
[root@centOS7 shell01]# echo "scale=2;100-2"|bc
98
[root@centOS7 shell01]# echo "scale=2;100/3"|bc
33.33
[root@centOS7 shell01]# echo "scale=2;100*3"|bc
300
[root@centOS7 shell01]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
scale=3
90/27
3.333
使用let命令也可以
[root@centOS7 shell01]# let sum=7+9
[root@centOS7 shell01]# echo $sum
16
使用(())
[root@centOS7 shell01]# echo $((1+9))
10
[root@centOS7 shell01]# echo $((2*9))
18
[root@centOS7 shell01]# echo $((9/2))
4
[root@centOS7 shell01]# echo $((100%3))
1
[root@centOS7 shell01]# echo $((100**3)) # 100的三次方
1000000
随机数
$RANDOM # 取值范围 0-32767
条件测试命令
test expression | [ expression ] | [[ expression ]]
# expression前后必须有空白字符
状态码$?true返回0,否则返回1
# 变量测试
-v VAR 查看变量VAR是否定义
[ -v VAR ]
# 数值测试
-gt 是否大于
-ge 大于等于
-eq 等于
-ne 不等于
-lt 小于
-le 小于等于
# 字符串测试
-z "STRING" 字符串是否为空,空为真,不空为假
-n "STRING" 字符串是否不空,不空为真,空为假
= 是否等于
!= 是否不等于
> ascii码是否大于ascii码
< 是否小于
== 左侧字符串是否和右侧的PATTERN相同
注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式用于[[ ]]中;扩展的正则表达式
#文件测试-存在性测试
-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
比如:[ -d /etc ]
# 文件测试-权限测试
-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 -ef FILE2: FILE1是否是FILE2的硬链接
FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2: FILE1是否旧于FILE2
# 组合测试条件
[ EXPRESSION1 -a EXPRESSION2 ] 并且
[ EXPRESSION1 -o EXPRESSION2 ] 或者
[ ! EXPRESSION ] 取反
关于()和{}
( list ) 会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境, 帮助参看:man bash
搜索(list)
{ list; } 不会启子shell, 在当前shell中运行,会影响当前shell环境, 帮助参看:man bash 搜索{ list; }
范例: () 和 {}
[root@centos8 ~]# name=mage;(echo $name;name=wang;echo $name );echo $name
mage
wang
mage
[root@centos8 ~]# name=mage;{ echo $name;name=wang;echo $name; } ;echo $name
mage
wang
wang
退出脚本
exit NUM 退出脚本,释放系统资源,NUM代表一个整数,代表返回值 ,num范围为1-255
[root@centOS7 shell01]# cat exit_code.sh
#!/usr/bin/bash
echo "hello world"
expr 6 \* 8
exit 178
[root@centOS7 shell01]# bash exit_code.sh
hello world
48
[root@centOS7 shell01]# echo $? # 输出上一个命令的返回值(退出码)
178
echo $?:
0表示成功(Zero - Success)
非0表示失败(Non-Zero - Failure)
脚本调试
bash -n 脚本 # 检测脚本中的语法错误
bash -x 脚本 # 调试执行
shell格式化输出
一个程序需要有0个或以上输入,一个或多个输出
echo命令
功能:将内容输出搭配默认显示设备
# echo命令的功能是在显示器显示一段文字,一般起到一个提示的作用。
语法:echo[-ne][字符串]
# 补充说明:echo会将输入的字符串送往标准输出,输出的字符串间以空格字符分开,并在最后加上换行符。
命令选项:
-n :不在最后自动换行
-e :若字符串中出现以下字符,则特别加以处理,而不会当做一般文字输出
转义字符:
\a 发出警告声
\b 删除前一个字符
\c 最后不加上换行符号
\f 换行但光标仍旧停留在原来的位置
\n 换行且光标移至行首
\r 光标移至行首,但不换行
\t 插入tab
\v 与\f相同
\插入\字符
\nnn 插入nnn,八进制所代表的ASCll字符
-help 显示帮助
-version 显示版本信息
[root@centOS7 shell01]# echo -n "date:";date
date:2021年 01月 20日 星期三 10:44:31 CST
[root@centOS7 shell01]# vim fruits.sh
#!/bin/bash
echo -e "\t\t\t\tFruits Shop"
echo -e "\t1) Apple"
echo -e "\t2) Banana"
echo -e "\t3) Orange"
[root@centOS7 shell01]# bash fruits.sh
Fruits Shop
1) Apple
2) Banana
3) Orange
颜色代码
脚本中echo显示内容带颜色显示。echo显示带颜色需要使用参数-e
格式:echo -e “\033[字背景颜色;字体颜色m 字符串\033[0m”
例子:
echo -e “\033[30m 黑色字 \033[0m”
echo -e “\033[31m 红色字 \033[0m”
echo -e “\033[32m 绿色字 \033[0m”
echo -e “\033[33m 黄色字 \033[0m”
echo -e “\033[34m 蓝色字 \033[0m”
echo -e “\033[35m 紫色字 \033[0m”
echo -e “\033[36m 天蓝字 \033[0m”
echo -e “\033[37m 白色字 \033[0m”
echo -e “\033[40;37m 黑底白字 \033[0m”
echo -e “\033[41;37m 红底白字 \033[0m”
echo -e “\033[42;37m 绿底白字 \033[0m”
echo -e “\033[43;37m 黄底白字 \033[0m”
echo -e “\033[44;37m 蓝底白字 \033[0m”
echo -e “\033[45;37m 紫底白字 \033[0m”
echo -e “\033[46;37m 天蓝底白字 \033[0m”
echo -e “\033[47;30m 白底黑字 \033[0m”
\033[0m 关闭所有属性
\033[1m 设置高亮度
\033[4m 下划线
\033[5m 闪烁
\033[7m 反显
\033[8m 消隐
\033[30m – \033[37m 设置前景色
\033[40m – \033[47m 设置背景色
\033[nA 光标上移n行
\033[nB 光标下移n行
\033[nC 光标右移n行
\033[nD 光标左移n行
\033[y;xH设置光标位置
\033[2J 清屏
\033[K 清除从光标到行尾的内容
\033[s 保存光标位置
\033[u 恢复光标位置
\033[?25l 隐藏光标
\033[?25h 显示光标
shell基本输入
read命令
默认接受键盘的输入,回车符代表输入结束
read命令选项:
-p 打印信息
-t N 限定timeout时间为N
-s 不回显,用于密码
-n 限定输入字符个数
#!/bin/bash
clear
echo -n -e "Login: "
read login
echo -n -e "Password: "
read pass
echo "login: $login password:$pass"
shell变量
变量介绍
在编程中,总有一些临时数据需要临死存放在内存中,以待后续使用时快速读出。内存在系统启动的时候被按照1B一个单位编号(16进制编号),并对内存的使用情况做记录,保存在内存跟踪表中。
计算机单位
1B=8bit
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024GB
1PB=1024TB
1EB=1024EB
1ZB=1024EB

变量分类
1.本地变量:用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中
2.全局变量:所有用户都能使用,保存在/etc/profile、/etc/bashrc文件中
3.用户自定义变量:用户自定义,比如脚本中的变量
定义变量
变量格式
变量格式:变量名=值
## 注意:在shell中的变量名和等号之间不能有空格
变量命名规则:
命名只能使用英文字母、数字和下划线,首个字符不能以数字开头
中间不能有空格
不能使用标点符号
不能使用bash里的关键字
比如:name='ketty' score=88.8 age=18 var1=1
值可以是以下形式:
name='root'
name="$USER"
name=`COMMAND` 或 name=$(COMMAND)
读取变量
读取变量内容:
$变量名
[root@centOS7 shell01]# name='hello ketty'
[root@centOS7 shell01]# echo $name
hello ketty
取消变量unset和显示已定义的变量set
set
[root@centOS7 shell01]# unset name
[root@centOS7 shell01]# echo $name # 打印出来的是null
定义全局变量export
export name='hello'
上述变量都是一次性变量,系统重启就会丢失。如果希望本地变量或者全局变量可以永久使用,可以将需要设置的变量写入变量文件。
定义永久变量
本地变量:用户私有变量,只有本用户可以使用,保存在家目录的.bash_profile、.bashrc文件中
全局变量:所有用户都可以使用,保存在/etc/profile、/etc/bashrc中
本地变量:
[root@centOS7 shell01]# tail -l ~/.bash_profile
全局变量:
[root@centOS7 shell01]# tail -l /etc/profile
bash内的环境变量
PATH
PWD
SHELL
USER
UID
HOME
SHLVL
LANG
MAIL
HOSTNAME
HISTSIZE
位置变量
$1 $2....对应第一个、第二个参数
$0 命令本身,包括路径
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数
清空所有位置变量:set --
变量扩展
`` 反引号,命令替换
\ 反斜杠,禁止单个字符扩展
! 感叹号,历史命令替换
shell数组
数组语法
数组名称=(元素1 元素2 元素3) 元素以空格分开
数组读出
${数组名称[索引]}
索引默认从0开始
[root@centOS7 shell01]# student=(ketty xiaofei daye)
[root@centOS7 shell01]# echo ${student[0]}
ketty
[root@centOS7 shell01]# echo ${student[2]}
daye
查看数组
declare -a
[root@centOS7 shell01]# declare -a
declare -a student='([0]="ketty" [1]="xiaofei" [2]="daye")'
访问数组元素
echo ${array1[0]} 访问数组的第一个元素
echo ${array1[@]} 访问数组中的所有元素 等同于echo ${array1[*]}
echo ${#array1[@]} 统计数组元素的个数
echo ${!array1[@]} 获取数组元素的索引
echo ${array1[@]:1} 从数组下标1开始
echo ${array1[@]:1:2}从数组下标1开始,访问两个元素
[root@centOS7 shell01]# echo ${student[0]}
ketty
[root@centOS7 shell01]# echo ${student[*]}
ketty xiaofei daye
[root@centOS7 shell01]# echo ${#student[@]}
3
[root@centOS7 shell01]# echo ${student[@]}
ketty xiaofei daye
[root@centOS7 shell01]# echo ${!student[@]}
0 1 2
[root@centOS7 shell01]# echo ${student[@]:1:2}
xiaofei daye
关联数组
关联数组可以允许用户自定义数组的索引
定义关联数组
# declare -A array1
# 声明一个关联数组 同时赋值多个
declare -A ass_array1
ass_array1=([name]='zhangshan' [age]='18')
echo ${ass_array1[name]}
# 声明一个关联数组 一个一个赋值
declare -A ass_array2
ass_array2[name]='lisi'
ass_array3[age]=19
echo ${ass_array2[name]}
shell流程控制-if判断语句
shell中的运算
数学比较运行
数学比较运算(比较的是整型)
-eq 等于
-gt 大于
-lt 小于
-ge 大于或等于
-le 小于或等于
-ne 不等于
INTEGER1 -eq INTEGER2
INTEGER1 is equal to INTEGER2
INTEGER1 -ge INTEGER2
INTEGER1 is greater than or equal to INTEGER2
INTEGER1 -gt INTEGER2
INTEGER1 is greater than INTEGER2
INTEGER1 -le INTEGER2
INTEGER1 is less than or equal to INTEGER2
INTEGER1 -lt INTEGER2
INTEGER1 is less than INTEGER2
INTEGER1 -ne INTEGER2
INTEGER1 is not equal to INTEGER2
测试
[root@centOS7 local]# test 1 -eq 1;echo $?
0
[root@centOS7 local]# test 1 -gt 1;echo $?
1
[root@centOS7 local]# test 1 -ge 1;echo $?
0
[root@centOS7 local]# test 1 -lt 1;echo $?
1
[root@centOS7 local]# test 1 -le 1;echo $?
0
[root@centOS7 local]# test 1 -ne 1;echo $?
1
字符串比较运算
== 等于
!= 不等于
-n 检查字符串长度是否大于0
-z 检查字符串长度是否为0
#### 记得加空格
[root@centOS7 shellstudy]# test $USER == "root";echo $?
0
文件比较与检查
-d #检查文件是否存在且为目录
-e #检查文件是否存在(文件或者文件夹都可以)
-f #检查文件是否存在且为文件
-r #检查文件是否存在且可读
-s #检查文件是否存在且不为空
-w #检查文件是否存在且可写
-x #检查文件是否存在且可执行
-O(大写O)#检查文件是否存在且被当前用户拥有
-G #检查文件是否存在且默认组为当前用户组
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧
[root@centOS7 shellstudy]# test -d shell01;echo $?
0
[root@centOS7 shellstudy]# test -r shell01/array1.sh;echo $?
0
逻辑运算
&& 逻辑与
|| 逻辑或
! 逻辑非
赋值运算
= 赋值运算符
if语法
语句格式1 []中括号间一定要有空格
if [ condition ] # condition值为false或true
then
commands
fi # 结束
语句格式2
if [ condition ] # condition值为false或true
then
commands1
else
commands2
fi # 结束
语句格式3
if [ condition1 ] # condition值为false或true
then
commands1
elif [ condition2 ]
then
commands2
............
else
commandx
fi # 结束
### test
read NUM
if [ $NUM -eq 10 ]
then
echo "输入的`echo $NUM`等于10"
elif [ $NUM -gt 10 ]
then
echo "输入的`echo $NUM`大于10"
else
echo "输入的` echo $NUM`小于10"
fi
if高级应用
条件符号使用双圆括号,可以在条件中植入数学表达式
[root@centOS7 shell02_if]# cat if_avg.sh
#!/bin/bash
if (( 100%3+1>1 ));then
echo 'yes'
else
echo 'no'
fi
[root@centOS7 shell02_if]# bash if_avg.sh
yes
使用双方括号可以在条件中使用通配符
for i in ac ab ag rr rt rvv
do
if [[ "$i" == r* ]]
then
echo "$i"
fi
done
[root@centOS7 shell02_if]# bash if_avg.sh
rr
rt
rvv
shell流程控制-for循环语句
for语法1
for var in value1 value2 ...
do
command
done
#### test
[root@centOS7 shell_for]# cat for_1.sh
#!/bin/bash
for i in `seq 1 9`
do
echo "$i"
done
for语法2
for((变量;条件;自增减运算))
do
commands
done
####### test
#!/bin/bash
for (( i=0;i<9;i++ ))
do
echo "$i"
done
无限循环
for ((;;))
do
command
done
循环控制语句
#!/bin/bash
echo -n "倒计时:"
for i in `seq 9 -1 1`
do
echo -n -e "\b$i"
sleep 1
done
# 监控主机存活脚本
for (( ;; ))
do
ping -c1 $1 &>/dev/null
if [ $? -eq 0 ]
then
echo "`date +"%F %H:%M:%S"` : $1 is up "
else
echo "`date +"%F %H:%M:%S"` : $1 is down "
fi
# 控制脚本
sleep 5
done
continue跳过循环中的某次循环,break终止循环
[root@centOS7 shell_for]# cat continue.sh
#! /bin/bash
for (( i=0;i<10;i++ ))
do
if [ $i -eq 5 ]
then
continue
else
echo $i
fi
done
[root@centOS7 shell_for]# bash continue.sh
0
1
2
3
4
6
7
8
9
shell流程控制-while循环语句
### while循环语法
while [ condition ]
do
commands
done
## 使用while循环遍历文件夹内容
[root@centOS7 shell_for]# cat continue_1.sh
#!/bin/bash
while read i
do
echo "$i"
done < $1
while循环控制与语句嵌套
# 嵌套 if for while
# 循环控制 sleep break continue
a1 () {
# 打印1-9
i=1
while [ $i -lt 10 ]
do
echo $i
if [ $i -eq 5 ]
then
break
fi
i=$((i+1))
done
}
a2 () {
# 打印1-9 当数值等于5 跳过当前循环
i=0
while [ $i -lt 10 ]
do
i=$((i+1))
if [ $i -eq 5 ]
then
continue
fi
if [ $i -eq 10 ]
then
break
else
echo "$i"
sleep 1
fi
done
}
## 99乘法表
n=1
while [ $n -lt 10 ]
do
for (( m=1;m<=$n;m++ ))
do
echo -n -e " $m * $n =$((m*n))\t"
done
echo
n=$((n+1))
done
until语句
until介绍:和while正好相反,until是条件为假时开始执行,条件为真时停止执行
## until语法
until [ condition ]
do
commands
done
## until案例
#!/bin/bash
n=10
until [ $n -gt 20 ]
do
echo $n
n=$((n+1))
sleep 1
done
case多条件分支语句
## case语法
case 变量1 in
条件1)
执行代码1
;;
条件2)
执行代码2
;;
.......
esac
## case案例1
[root@centOS7 shell_case]# cat case_test.sh
#!/bin/bash
read -p "NUM:" num
case $num in
1)
echo "haha"
;;
2)
echo "hehe"
;;
3)
echo "heihei"
;;
*)
echo "bye"
;;
esac
## case案例2
[root@centOS7 shell_case]# cat case_in.sh
#!/bin/bash
case $1 in
zmn | ZMN)
echo "你好,丈母娘"
;;
lzr|LZR)
echo "你好,老丈人"
;;
*)
echo "USE: $0 zmn|lzr"
;;
esac
[root@centOS7 shell_case]# bash case_in.sh zmn
你好,丈母娘
[root@centOS7 shell_case]# bash case_in.sh LZR
你好,老丈人
shell特殊变量
## 特殊参数
$* 代表所有参数,其间隔为IFS内定参数的第一个字元
$@ 与*类同,不同之处在于不参照IFS
$# 代表参数数量
$? 执行上一个指令的返回值
$- 最近执行的foreground pipeline的选项参数
$$ 本身的process ID 进程id
$ 执行上一个背景指令的PID
$_ 显示出最后一个执行的命令
$N shell的第几个外传参数
### 测试
[root@centOS7 shell_case]# cat shell_variable.sh
#!/bin/bash
echo "脚本的名字是: $0"
echo "脚本的参数是: $*"
echo "传参数量:$#"
echo "脚本执行进程号:$$"
echo "最后执行命令:$_"
echo "第二个参数是: $2"
[root@centOS7 shell_case]# bash shell_variable.sh aa bb vv ff gg
脚本的名字是: shell_variable.sh
脚本的参数是: aa bb vv ff gg
传参数量:5
脚本执行进程号:43808
最后执行命令:脚本执行进程号:43808
第二个参数是: bb
shell函数
### 函数优点
1.代码模块化,调用方便,节省内存
2.代码模块化,代码量少,排错简单
3.代码模块化,可以改变代码的执行顺序
### 函数语法1
函数名 () {
代码块
return N
}
### 函数语法2
function 函数名{
代码块
return N
}
[root@centOS7 function_test]# cat function_test1.sh
#!/bin/bash
# 定义函数
start1 () {
echo "apache start ...... [OK]"
return 0
}
function end1 {
echo "apache end ......... [OK]"
}
# 调用函数
start1
end1
nginx启动关闭重启脚本
[root@centOS7 function_test]# cat nginx_install.sh
#!/bin/bash
#variable 变量
nginx_install_doc=/usr/local/nginx
nginxd=$nginx_install_doc/sbin/nginx
pid_file=$nginx_install_doc/logs/nginx.pid
#source function library
if [ -f /etc/init.d/functions ]
then
. /etc/init.d/functions
else
echo "not found /etc/init.d/functions file"
exit
fi
### -f 判断此文件是否存在 pid_file是nginx的进程文件,里面存储进程号
if [ -f $pid_file ]
then
nginx_process_id=`cat $pid_file`
nginx_process_num=`ps aux | grep $nginx_process_id | grep -v "grep" | wc -l`
fi
# function 函数
start (){
# 判断nginx是否启动
if [ -f $pid_file ] && [ $nginx_process_num -ge 1 ]
then
echo "nginx running ......"
else
if [ -f $pid_file ] && [ $nginx_process_num -lt 1 ]
then
# 删除进程文件
rm -f $pid_file
# 重启nginx
echo "nginx start ` daemon $gninxd` "
fi
echo "nginx start `daemon $nginxd`"
fi
}
stop () {
if [ -f $pid_file ] && [ $nginx_process_num -ge 1 ]
then
action "nginx stop" killall -s QUIT nginx
rm -f $pid_file
else
action "nginx stop" killall -s QUIT nginx 2>/dev/null
fi
}
restart () {
stop
sleep 1
start
}
reload () {
if [ -f $pid_file ] && [ $nginx_process_num -ge 1 ]
then
action "nginx stop" killall -s HUP nginx
rm -f $pid_file
else
action "nginx stop" killall -s HUP nginx 2>/dev/null
fi
}
status () {
if [ -f $pid_file ] && [ $nginx_process_num -ge 1 ]
then
echo "nginx running ....."
else
echo "nginx stop ......."
fi
}
case $1 in
start) start;;
stop) stop;;
restart) restart;;
status) status;;
reload) reload;;
*) echo "USE: $0 start stop restart reload status";;
esac
正则表达式
# 正则表达式介绍
正则表达式是一种文本模式匹配,包括普通字符(a-z)和特殊字符(元字符)。它是一种字符串匹配模式,可以用来检查一个字符串是否含有某种子串,将匹配的子串替换或者从某个字符串中取出某个条件的子串。
shell也支持正则表达式,但不是所有的命令都支持正则表达式,常 见的命令只有grep、sed、awk命令支持正则表达式
### 特殊字符
定位符使用技巧:同时锚定开头和结尾,做精确匹配;单一锚定开头和结尾,做模糊匹配。
定位符 说明
^ 锚定开头^a以a开头 ,默认锚定一个字符
$ 锚定结尾$a以a结尾 ,默认锚定一个字符
##### 测试 egrep 等价于 grep -E
[root@centOS7 regular_expression]# egrep "^ac$" file ###匹配以a开头,以c结尾的字符串
ac
## 匹配符 匹配字符串
. 匹配除回车以外任意字符
() 字符串分组
[] 定义字符类,匹配括号中的一个字符
[^] 表示否定括号中出现字符类中的字符,去翻
\ 转义字符
| 管道
[roo t@centOS7 regular_expression]# egrep "^(a|b)c$" file
ac
bc
[root@centOS7 regular_expression]# egrep "^a[0-9]c$" file
a3c
[root@centOS7 regular_expression]# egrep "^a[^0-9]c$" file
acc
abc
a_c
[root@centOS7 regular_expression]# egrep "^a.c$" file
acc
abc
a_c
aZc
a c
[root@centOS7 regular_expression]# egrep "^a\*c$" file 使用\进行转义
a*
## 限定符:对前面的字符或者字符串做限定说明
* 某个字符之后加星号表示该字符不出现或出现多次,只要出现就都是这个字符
? 与星号相似,表示该字符出现一次或不出现
+ 与星号相似,表示前面的字符出现一次或多次,但必须出现一次
{n,m} 某个字符之后出现,表示该字符最少n次,最多m次
{m} 正好出现m次
### 测试
[root@centOS7 regular_expression]# egrep "^ab*c$" file
ac
abbc
abbbc
abc
[root@centOS7 regular_expression]# egrep "^ab?c$" file
ac
abc
[root@centOS7 regular_expression]# egrep "^ab+c$" file
abbc
abbbc
abc
[root@centOS7 regular_expression]# egrep "^ab{1,2}c$" file
abbc
abc
[root@centOS7 regular_expression]# egrep "^ab{2}c$" file
abbc
###POSIX特殊字符
[root@centOS7 regular_expression]# egrep "^a[[:digit:]]c$" file
a3c
[root@centOS7 regular_expression]# egrep "^a[[:alpha:]]c$" file
acc
abc
aZc
apc
[root@centOS7 regular_expression]# egrep "^a[[:alnum:]]c$" file
acc
abc
aZc
a3c
apc
## IP地址的正则表达式 x.x.x.x
"^((25[0-5]|2[0-4][[:digit:]]|[01]?[[:digit:][[:digit:]]?).){3}(25[0-5]|2[0-4][[:digit:]]|[01]?[[:digit:][[:digit:]]?)"
### 分解((25[0-5]|2[0-4][[:digit:]]|[01]?[[:digit:][[:digit:]]?).){3}
25[0-5] 250-255
2[0-4][[:digit:]] 200-249
[01]?[[:digit:][[:digit:]]? 0-199
{3} 出现三次
shell对文件操作
### sed命令
sed是linux中提供的一个外部命令,它是一个行(流)编辑器,非交互式的对文件内容进行增删改查的操作,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。它和文本编辑器有本质的区别。
文本编辑器:编辑对象是文件
行编辑器:编辑对象是文件中的行
sed语法:sed [options] '{commands}[flags]'[filename]
命令选项(options):
-e script 将脚本中指定的命令添加到处理输入时执行的命令中,多条件,一行中有多个操作
-f script 将文件中指定的命令添加到处理输入时执行的命令中
-n 抑制自动输出 只会打印需要打印的行
-i 编辑文本内容,直接改变原文件内容,不打印
-i.bak 修改时同时创建.bak备份文件,原文件不改变,备份文件为修改后文件
-r 使用扩展的正则表达式
! 取反(跟在模式条件后与shell有所区别)
sed常用内部命令(commands):
a 在匹配后面添加(追加)
i 在匹配前面添加(插入)
p 打印
d 删除
s 查找替换 只替换第一次查找到的匹配字符串
c 更改
y 转换 N D P
### 测试
[root@centOS7 shell_sed]# sed 'aHello world' data ### 每一行后面添加hello world(换行后添加)
[root@centOS7 shell_sed]# sed '3aHello world' data ### 第三行后面添加
[root@centOS7 shell_sed]# sed '2,4aHello world' data ###第二到四行添加
[root@centOS7 shell_sed]# sed '/3 the/a\Hello world' data ###在//中将添加匹配字符串
[root@centOS7 shell_sed]# sed 'i\Hello world' data ###在每行前面添加
[root@centOS7 shell_sed]# sed 'd' data ### 删除所有行
[root@centOS7 shell_sed]# sed '3d' data ### 删除第三行
[root@centOS7 shell_sed]# sed -r '/(^#|#|^$)/d' nginx.conf ##删除所有#开头、包含#、空格的所有行
[root@centOS7 shell_sed]# sed 's/dog/cat/' data ##将所有dog换为cat
[root@centOS7 shell_sed]# sed '/3 the/s/dog/cat/' data ##把第三行的dog换为cat
[root@centOS7 shell_sed]# sed 'y/abcdef/ABCDEF/' data ##把a转换成A,把b转换成B...把f转换成F
flags:
数字 表示新文本替换的模式
g 表示用新文本替换现有文本的全部实例
p 表示打印原始内容
w filename 将替换的结果写入文件
[root@centOS7 shell_sed]# sed 's/dog/cat/2' data ##把每一行第二个dog换为cat
[root@centOS7 shell_sed]# sed 's/dog/cat/g' data ##把每一行所有dog换为cat
[root@centOS7 shell_sed]# sed 's/dog/cat/w newfile' data ##把每一行第二个dog换为cat,写入新文件
[root@centOS7 shell_sed]# sed -e 's/dog/cat/;s/brown/green/' data # -e支持多条件,多操作
sed小技巧:
$= 统计文本有多少行
= 打印文本内容时加上行号
[root@centOS7 shell_sed]# sed -n '$=' data
5
[root@centOS7 shell_sed]# sed '=' data
1
1 the quick brown fox jumps over the lazy dog
2
2 the quick brown fox jumps over the lazy dog
3
3 the quick brown fox jumps over the lazy dog
4
4 the quick brown fox jumps over the lazy dog
5
5 the quick brown fox jumps over the lazy dog
shell对输出流的处理
[root@centOS7 shellstudy]# head /proc/meminfo #计算机内存信息
MemTotal: 1867048 kB
MemFree: 1001308 kB
MemAvailable: 1228012 kB
Buffers: 2116 kB
Cached: 348292 kB
SwapCached: 0 kB
Active: 332572 kB
Inactive: 290484 kB
Active(anon): 273604 kB
Inactive(anon): 9628 kB
[root@centOS7 shell_awk]# head -3 /proc/meminfo | awk 'NR==1{print $2}'
1867048
awk介绍
awk介绍
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk的工作方式是读取数据,将每一行数据视为一条记录(record),每条记录以字段分隔符分成若干字段,然后输出各个字段的值。
awk语法:[options][BEGIN]{program}[END][file]
options命令选项:
-F fs 指定描述一行中数据字段的文件分隔符。默认是空格
-f file 指定读取程序的文件名
-v var=value 定义awk程序中使用的变量和默认值
#注意:awk程序脚本由左大括号和右大括号定义,脚本命令必须放在两个大括号之间。由于awk命令行假脚本是单文本字括在单引号中。
awk运行优先级:
1)BEGIN:在开始处理数据流之前执行,可选项
2)program:如何处理数据流,必选
3)END:处理完数据流后执行,可选。
awk基本用法
awk对字段(列)的提取
字段提取:提取一个文本中的一列数据并打印输出
字段相关内置变量
$0 表示整行文本
$1 表示文本行中第一个数据字段
$2 表示文本行中第二个数据字段
$N 表示文本行中第N个数据字段
$NF 表示文本行中最后一个数据字段
[root@centOS7 shell_awk]# awk '{print $1}' data
1
2
3
4
5
[root@centOS7 shell_awk]# awk '{print $NF}' data
dog
[root@centOS7 shell_awk]# awk 'NR==3{print $1,$3,$5}' data # 打印第三行1,3,5列
3 quick fox
[root@centOS7 shell_awk]# awk 'NR==3{print $1 "-" $3 "-" $5}' data
3-quick-fox
awk对行(记录)的提取
记录提取:提取一个文本中的一列数据并打印输出
提取的方法有两种:通过行号;通过正则匹配
记录相关内置变量
NR 指定行号
# 打印第三行所有
[root@centOS7 shell_awk]# awk 'NR==3{print $0}' data
3 the quick brown fox jumps over the lazy dog
awk执行优先级
[root@centOS7 shell_awk]# awk 'BEGIN{print "begin"}NR==3{print $1,$3}END{print "end"}' data
begin
3 quick
end
awk高级用法
awk定义数组
数组定义方式:数组名[索引]=值
[root@centOS7 shell_awk]# awk 'BEGIN{array1[0]="hello";print array1[0]}'
hello
awk运算
1.赋值运算 =
2.比较运算 > >= < <= == !=
3.数学运算 + - * / % ** ++ --
4.逻辑运算 && ||
5.匹配运算 ~ !~ 模糊匹配
1.赋值运算
变量运算:name="" 数组赋值:array[1]=100
[root@centOS7 shell_awk]# awk 'BEGIN{array1[0]="hello";print array1[0]}'
hello
[root@centOS7 shell_awk]# awk 'BEGIN{name="hello";print name}'
hello
2.比较运算
如果比较的是字符串则按ASCII编码顺序表比较,结果为真返回1,结果为假返回0
[root@centOS7 shell_awk]# awk 'BEGIN{ print "a" >= "b" }'
0
[root@centOS7 shell_awk]# awk 'BEGIN{ print "a" <= "b" }'
1
[root@centOS7 shell_awk]# awk 'BEGIN{ print 100!=400 }'
1
[root@centOS7 shell_awk]# awk 'BEGIN{ print 1+8 }'
9
[root@centOS7 shell_awk]# awk 'BEGIN{ print 100>=2 && 100>=3 }'
1
[root@centOS7 shell_awk]# awk 'BEGIN{ print 100<2 || 100<3 }'
0
[root@centOS7 shell_awk]# awk 'BEGIN{count=1; print ++count }'
2
[root@centOS7 shell_awk]# awk -v count=0 'BEGIN{count--; print count }'
-1
awk环境变量
FIELDWIDTHS 以空格分隔的数字列表,用空格定义每个数据字段的精确宽度
FS 输入字段分隔符号
OFS 输出字段分隔符号
RS 输入记录分隔符号
ORS 输出记录分隔符号
FIELDWIDTHS:重定义列宽并打印,不可以使用$0打印所有
[root@centOS7 shell_awk]# awk 'BEGIN{FIELDWIDTHS="5"}NR==1{print $1}' data
1 th
[root@centOS7 shell_awk]# awk 'BEGIN{FS="fox"}NR==1{print $1}' data # 以fox为分隔符
1 the quick brown
[root@centOS7 shell_awk]# awk 'BEGIN{FS="fox";OFS="-"}NR==1{print $1,$2}' data # 以-为分隔符输出
1 the quick brown - jumps over the lazy dog
awk流程控制
1.if判断语句
2.for循环语句
3.while循环语句
4.do...while语句
5.循环控制
if语句
[root@centOS7 shell_awk]# awk '{if($1>5) print $1}' num
6
7
8
9
10
[root@centOS7 shell_awk]# awk '{if($1<5) print $1*2 ;else if($1>5)print $1-2}' num
2
4
6
8
4
5
6
7
8
for语句
[root@centOS7 shell_awk]# cat num1
1 2 3
4 5 6
7 8 9
[root@centOS7 shell_awk]# awk '{sum=0;for(i=1;i<4;i++){sum+=$i}print sum}' num1
6
15
24
while语句
[root@centOS7 shell_awk]# cat num1
1 2 3
4 5 6
7 8 9
[root@centOS7 shell_awk]# awk '{sum=0;i=1;while(i<4){sum+=$i;i++}print sum}' num1
6
15
24
do while语句
[root@centOS7 shell_awk]# cat num1
1 2 3
4 5 6
7 8 9
[root@centOS7 shell_awk]# awk '{sum=0;i=1;do{sum+=$i;i++}while(i<4);print sum}' num1
6
15
24
控制循环
[root@centOS7 shell_awk]# cat num1
1 2 3
4 5 6
7 8 9
[root@centOS7 shell_awk]# awk '{sum=0;i=1;while(i<4){sum+=$i;if(sum>6){break};i++}print sum}' num1
6
9
7
awk小技巧
# 打印行数
[root@centOS7 shell_awk]# awk 'END{print NR}' num1
3
# 打印最后一行文本
[root@centOS7 shell_awk]# awk 'END{print $0}' num1
7 8 9
# 打印文本列数
[root@centOS7 shell_awk]# awk 'END{print NF}' num1
3