1. shell基础 #

1.1 查看支持的shell #

查看shell的帮助信息

命令 作用
man bash 查看bash的命令帮助
info bash 查看bash的文档
help 命令显示bash支持的命令
help cd 如果想看某个命令的帮助可以 help 命令

1.2 echo #

控制字符 作用
\n 换行符
\r 回车键
\t 制表符,也就是Tab键
\v 垂直制表符
\onnn 按照八进制ASCII码表输出字符,其中0为数字零,nnn是三位八进制数
\xhh 按照十六进制ASCII码表输出字符,其中hh是两位十六进制数
符号 颜色
#30m 黑色
#31 红色
#32 绿色
#33 黄色
#34 蓝色
#35 洋红
#36 青涩
#37 白色
echo -e "12\r\n34\t56\v78"
echo -e "\0141"
echo -e "\x61"
echo -e "\e[1;31m warning \e[0m"

1.3 编写执行shell #

#!/bin/bash
echo -e "\e[1;34m hello world \e[0m"

赋予执行权限,直接运行

chmod 755 hello.sh
./hello.sh

通过Bash调用执行脚本

bash hello.sh

1.4 别名 #

1.5 命令的生效顺序 #

1.6 命令快捷键 #

命令 含义
ctrl+c 强制终止当前命令
ctrl+l 清屏
ctrl+a 光标移动到命令行首
ctrl+e 光标移动到命令行尾
ctrl+u 从光标所在的位置删除到行首
ctrl+z 把命令放入后台
fg 把任务带回前台
ctrl+r 在历史命令中搜索

1.7 历史命令 #

1.8 调用 #

history -c
1  echo 1
2  echo 2
3  echo 3
!2
!!
!echo

1.9 输出重定向 #

1.9.1 标准输入输出 #

设备 设备文件名 文件描述符 类型
键盘 /dev/stdin 0 标准输入
显示器 /dev/stdout 1 标准输出
显示器 /dev/stderr 2 标准错误输出
类型 符号 作用
标准输出重定向 命令 > 文件 以覆盖的方式,把命令的正确输出输出到指定的文件或设备当中
标准输出重定向 命令 >> 文件 以追加的方式,把命令的正确输出输出到指定的文件或设备当中
错误输出重定向 命令>文件 以覆盖的方式,把命令的错误输出输出到指定的文件或设备当中
错误输出重定向 命令>>文件 以追加的方式,把命令的错误输出输出到指定的文件或设备当中
正确输出和错误输出同时保存 命令>文件 2>&1 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中
正确输出和错误输出同时保存 命令>文件 2>>&1 以追加的方式,把正确输出和错误输出都保存到同一个文件当中
正确输出和错误输出同时保存 命令&>文件 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中
正确输出和错误输出同时保存 命令&>>文件 以追加的方式,把正确输出和错误输出都保存到同一个文件当中
正确输出和错误输出同时保存 命令>>文件1 2>文件2 以覆盖的方式,正确的输出追加到文件1中,把错误输出追加到文件2中

1.9.2 输入重定向 #

- wc < access.log 
[root@localhost ~]# wc <<!
> hello world
> !
 1  2 12

1.10 管道符号 #

1.10.1 多命令顺序执行 #

多命令执行符 格式 作用 案例
; 命令1;命令2 多个命令执行,命令之间没有任何逻辑联系 echo 1;echo 2;
&& 命令1&&命令2 逻辑与 当命令1正确执行,则命令2才会执行 当命令1执行不正确,则命令2不会执行 echo 1&&echo 2;
\\ 命令1\\ 命令2 逻辑或 当命令1执行不正确,则命令2才会执行 当命令1正确执行,则命令2不会执行 echo 1\\echo 2;
- date;ls;date;ls
- ls && echo yes || echo no

1.10.2 管道符号 #

1.10.3 通配符 #

匹配文件名和目录名

通配符 作用
? 匹配一个任意字符
* 匹配0个或任意字符,也就是可以匹配任意内容
[] 匹配中括号中任意一个字符
[-] 匹配中括号中任意一个字符,-代表范围
[^] 匹配不是中括号中的一个字符

1.10.4 其它符号 #

符号 作用
'' 单引号。在单引号中所有的特殊符号,如$和`都没有特殊含义
"" 双引号,在双引号里特殊符号都没有特殊含义,但是 $ ` \ 例外,拥有调用变量值,引用命令和转义的含义
反引号,扩起来的是系统命令
$() 和反引号一样
# 在shell脚本中,#开头的行代表注释
$ 用于调用变量的值
\ 转义符号
-  a=`ls`
-  b=$(ls)

2. 变量 #

2.1 什么是变量 #

2.2 变量的分类 #

2.3 用户自定义变量 #

2.3.1 定义变量 #

name="zhufeng"
age=10

2.3.2 输出变量值 #

echo $变量名

2.3.3 值默认都是字符串 #

$ x=1
$ y=2
$ z=3
$ z=$x+$y+$z
$ echo $z

2.3.4 在赋值的时候引用变量 #

y="$y"2
y=${y}2

2.3.5 set #

set | grep zhufeng
$ set -u
$ echo $a
bash: a: unbound variable
`

2.3.6 unset #

unset a

2.4 环境变量 #

bash 
pstree

2.4.1 自定义环境变量 #

export 变量名=变量值
export envname=prod

2.4.2 env #

2.4.3 常用环境变量 #

变量名 含义 示例
HOSTNAME 主机名 HOSTNAME=localhost
SHELL 当前的shell SHELL=/bin/bash
TERM 终端环境 TERM=xterm
HISTSIZE 历史命令条数 HISTSIZE=1000
SSH_CLIENT 当前操作环境如果是用SSH连接的话,这里会记录客户端IP SSH_CLIENT=192.168.1.100 57596 22
SSH_TTY SSH连接的终端 SSH_TTY=/dev/pts/1
USER 当前登录的用户 USER=root

2.4.4 path #

# echo $PATH
/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

如果想把一个自定义的脚本直接可以执行,或者把这个文件拷贝到目标目录下,或者把脚本所在目录添加到环境变量中的PATH路径中

hello.sh

#!/bin/bash
echo hello
./hello.sh
/root/myshell/hello.sh
export PATH="$PATH":/root/myshell   临时生效
hello.sh

2.4.5 $PS1 #

# echo $PS1
[\u@\h \W]\$
root@localhost myshell]#
变量 提示符
\d 显示日期,格式为"星期 月 日"
\H 完整的主机名
\t 24小时制时间,格式为 "HH:MM:SS"
\A 24小时制时间,格式为 "HH:MM"
\u 显示当前用户名
\w 显示所在目录完整名称
\W 显示所在目录的最后一个目录
\$ 提示符,root为#,普通用户为$
export PS1='[\u@\h \w]\$ '

2.4.6 语系环境变量 #

locale
LANG=zh_CN.UTF-8

echo $LANG

下次开机之后我们系统环境
cat /etc/sysconfig/i18n

2.4.7 中文支持 #

2.5 位置参数变量 #

位置参数变量 作用
$n n为数字,$0代表命令本身,$1-$9代表第1到第9个参数,10以上的参数需要用大括号包含,如${10}
$* 这个变量代表命令中所有的参数,$*把所有的变看数看成一个整体
$@ 这个变量也代表命令行中所有的参数,不过$@把每个参数进行区分
$# 这个变量代表命令行中所有参数的个数
#!/bin/bash
num1=$1
num2=$2
sum=$((num1+num2))
echo $sum
#!/bin/bash
for i in "$@"
 do
   echo "i=$i"
 done

2.6 预定义变量 #

位置参数变量 作用
$? 最后一次执行的命令的返回状态。0表示正确执行,非0表示不正确执行
$$ 当前进程的进程号(PID)
$! 后台运行的最后一个进程号(PID)
ls && echo yes

2.7 read #

read [选项] [变量名]

选项 含义
-p 提示信息,在等待read输入时,输出提示信息
-t 秒数: read命令会一直等待用户输入,使用此选项可以指定等待时间
-n 字符数,read命令只接受指定的字符数,就会执行
-s 隐藏输入的数据,适用于机密信息的输入
#!/bin/bash
read -p 'please input your name:' -t 5 name
echo -e "\n"
read -p 'please input you gender[m/f]:' -n 1 gender
echo -e "\n"
read -p 'please input your password:' -s password
echo -e "\n"
echo $name,$gender,$password

3. 运算符 #

3.1 declare命令 #

3.1.1 declare命令 #

选项 含义
- 给变量设定类型属性
+ 取消变量的类型属性
-a 将变量声明为数组类型
-i 将变量声明为整数型(integer)
-x 将变量声明为环境变量
-r 将变量声明为只读变量
-p 显示指定变量的被声明的类型
//声明成整型
# a=1
# b=2
# c=$a+$b
# echo $c
1+2
# declare -i c=$a+$b
# echo $c
3
# declare +i c
# c=$a+$b
# echo $c
1+2
# declare -p c
declare -i c="3"

//声明环境变量
# declare -x kk=1
# bash
# set | grep kk

//只读
# declare -r x
# x=2

3.1.2 数组 #

names[0]=zhangsan
names[1]=lisi
# 声明为数组类型
declare -a names;
# 默认只打印第一个元素
echo ${names}
zhangsan
打印第2个元素
# echo ${names[1]}
lisi
# 打印全部
echo ${names[*]}
zhangsan lisi

3.1.3 声明环境变量 #

export NAME=zhufeng
declare -x NAME=zhufeng

3.1.4 只读属性 #

#declare -r gender=m
#gender=f
-bash: gender: readonly variable

3.1.5 查询变量属性 #

3.2 数值运算的方法 #

#num1=2
#num2=3
#s=$(expr $num1 + $num2)
#echo $s
5
#s=$(($num1+$num2))
#echo $s
5
#s=$[$num1+$num2]
#echo $s
5

d=$(date)
echo $d

3.2.2 优先级 #

priority

result=$(((1+2)*4/2))
6
`

4. 环境变量配置文件 #

4.1 source 命令 #

4.2 环境变量配置文件简介 #

路径 说明
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
~/.bash_profile 只会对当前用户生效
~/.bashrc 只会对当前用户生效

loadenv

4.3 环境变量配置文件的功能 #

4.3.1 /etc/profile #

cat  /etc/profile | grep USER
变量名 含义
USER 用户名
LOGNAME 登录名
MAIL 邮箱地址
PATH 查找路径
HOSTNAE 主机名
umask 权限掩码
/etc/profile.d/星.sh

4.3.2 ~/.bash_profile #

4.3.3 ~/.bashrc #

4.3.4 /etc/bashrc #

4.3.5. 其它配置文件 #

4.3.5.1 注销时生效的环境变量配置文件 #

~/.bash_logout

4.3.5.2 脚本历史 #
4.3.5.3 Shell登录信息 #

本地终端欢迎信息 /etc/issue 远程终端欢迎信息 /etc/issue.net 不管远程还是本地都可以生效 /etc/motd

参数 含义
\d 当前系统日期
\s 显示操作系统名称
\l 显示登录的终端号
\m 显示硬件体系结构,如i386等
\n 显示主机名
\o 显示域名
\r 显示内核版本
\t 显示当前系统时间
\u 显示当前登录用户的序列号
vi /etc/ssh/sshd_config
Banner /etc/issue.net
service sshd restart

4.正则表达式 #

4.1 概念 #

4.2 通配符 #

符号 含义
? 匹配任意一个字符
* 匹配任意多个字符
[] 匹配中括号中范围内的一个字符

4.3 正则表达式 #

4.4 元字符 #

alias grep='grep --color=auto'

元字符 作用 示例
* 前一个字符匹配 0 次或任意多次 grep 1* reg.txt
. 匹配除换行符外的任意一个字符 grep . reg.txt
^ 匹配行首。例如,^hello 会匹配以 hello 开头的行 grep ^a reg.txt
$ 匹配行尾。例如,hello& 会匹配以 hello 结尾的行 grep a$ reg.txt
[] 匹配屮柄号屮指定的任意一个字符,而且只匹配一个字符。
例如.[aoeiu]匹配任意一个元音字母, [0-9] 匹配任意一位数字,
[a-z][0-9] 匹配由小写字母和一位数字构成的两位字符
grep ab[bc]c reg.txt
[^] 匹配除中括号中的字符以外的任意一个字符。例如,[^0-9] 匹配任意一位非数字字符,
[^a-z] 匹配任意一位非小写字母
grep a[^fg]c reg.txt
\ 转义符,用于取消特殊符号的含义 grep \.$ reg.txt
{n} 表示其前面的字符恰好出现 n 次。例如,[0-9]{4} 匹配4位数字,[1][3-8][0-9]{9} 匹配手机号码 grep "a{1}" reg.txt
(n,} 表示其前面的字符出现不少于 n 次。例如,[0-9]{2,} 匹配两位及以上的数字 grep "a{1,}" reg.txt
{n,m} 表示其前面的字符至少出现 n 次,最多出现 m 次。例如,[a-z]{6,8} 匹配 6〜8 位的小写字母 grep "a{2,3}" reg.txt

4.5 cut #

cat /etc/passwd | grep /bin/bash | cut -f 1,2 -d :

df -h | grep /dev/sda5 | cut -f 5

4.6 printf #

参数 含义
%ns 输出字符串,n是数字指代输出几个字符
%ni 输出整数,n是指输出几个数字
%m.nf 输出浮点数,m和n是数字,指代输出的整数位数和小数位数,如%6.2f代表输出6位位,2位小数,4位整数
printf "%s\t%s\t%s\t%s\t%s\t\%s\n" $(df -h | grep /dev/sda5) | cut -f 5

4.7 awk #

 df -h | grep /dev/sda5 |awk '{print $5}'| cut -d '%' -f 1

4.7.1 begin end #

4.7.2 FS #

awk 'BEGIN{FS=":"}{print $1"\t"$2}' /etc/passwd

4.7.3 声明变量 #

awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}' numbers.txt 

4.7.4 多条件 #

awk '$2>90{print $1"\t优秀"}$2>80{print $2"\t良好"}' score.txt

4.7.5 NR #

awk '{print NR,$0}' file1 
awk 'NR=3{print $0}' file1 

4.7.6 OFS #

echo "i love you" | awk 'BEGIN{ FS=" ";OFS="-" }{ print $1,$2,$3}'

4.8 sed命令 #

选项

参数 含义 示例
-n 一般sed命令会把所有的数据都输出到屏幕上,如果加入此选项则只会把处理过的行输出到屏幕上 sed -n '2p' score.txt
-e 允许对输入数据应用多条sed编辑命令 sed -e 's/75/70/g;s/55/50/g' score.txt
-i 用sed的修改直接修改编辑的文件,而不是在屏幕上输出 sed -i '1i newline' score.txt

动作

参数 含义 示例
a 追加,在每一行或者指定行下面添加一行或多行 sed '1a newline' score.txt
c 行替换,用c后面的字符串替换掉原始整个数据行 sed 'c newline' score.txt
s 字符串替换,用一个字符串替换另外一个字符串,格式为 "行范围s/旧字符串/新字符串/g" sed '3s/lisi/lisisi/g' score.txt
i 插入,在当前行插入一行或多行 sed '1i newline' score.txt
d 删除指定的行 sed '1,2d' score.txt
p 打印,输出指定的行 sed -n '2p' score.txt

4.9 排序命令sort #

选项 含义
-f 忽略大小写 sort -f -t ":" -n -k 5,5 /etc/passwd
-n 以数值型进行排序,默认使用字符串顺序 sort -t ":" -n -k 3,3 /etc/passwd
-r 反向排序,默认从小到大 sort -r /etc/passwd
-t 指定分割符,默认分割符是制表符 sort -t ":" -k 3,3 /etc/passwd
-k n[,m] 按照指定的字段范围排序。从第n个字段开始,到第m个字段结束,默认是到行尾 sort -t ":" -k 3,3 /etc/passwd
sort /etc/passwd
sort -r /etc/passwd
sort -t ":" -k 3,3 /etc/passwd

4.10 wc #

选项 含义
-l 只统计行数
-w 只允许单词数
-m 只统计字符数
wc wc.txt 

5. 流程控制 #

5.1 条件判断 #

5.1.1 按照文件类型进行判断 #

选项 含义
-d 文件是否存在并且是目录
-e 文件是否存在
-f 文件是否存在并且是普通文件
-b 文件是否存在并且是块设备文件
-c 文件是否存在并且是字符设备文件
-L 文件是否存在并且是链接文件
-p 文件是否存在并且是管道文件
-s 文件是否存在并且是否为非空
-S 文件是否存在并且是套接字文件
test -e 1.txt
[-e 1.txt]
echo $?
# [ -e 1.txt ]&&echo "yes"|| echo "no"
yes
# [ -e 11.txt ]&&echo "yes"|| echo "no"
no

5.1.2 按照文件权限进行判断 #

选项 含义
-r 文件是否存在,并且是否拥有读权限
-w 文件是否存在,并且是否拥有写权限
-x 文件是否存在,并且是否拥有执行权限
echo read  > read.txt
echo write  > write.txt
echo execute  > execute.txt

chmod u+w write.txt 
chmod u+x execute.txt

[ -e read.txt ]&&echo "read yes"|| echo "no"
[ -e write.txt ]&&echo "write yes"|| echo "no"
[ -e execute.txt ]&&echo "execute yes"|| echo "no"

5.1.3 两个文件间的比较 #

选项 含义
文件1 -nt 文件2 判断文件1的修改时间是否比文件2的新
文件1 -ot 文件2 判断文件1的修改时间是否比文件2的旧
文件1 -ef 文件2 判断文件1和文件2的inode号是否一致,可用于判断硬链接
[ write.txt -nt read.txt ]&&echo "write is older than read"|| echo "no"
[ read.txt -ot write.txt ]&&echo "read is older than write"|| echo "no"
ln execute.txt execute2.txt
[ execute.txt -ef execute2.txt ]&&echo "execute and execute2.txt are the same"|| echo "no"

5.1.4 两个整数间的比较 #

选项 含义
整数1 -eq 整数2 判断整数1是否和整数2相等
整数1 -ne 整数2 判断整数1是否和整数2不相等
整数1 -gt 整数2 判断整数1是否大于整数2
整数1 -lt 整数2 判断整数1是否小于整数2
整数1 -ge 整数2 判断整数1是否大于等于整数2
整数1 -le 整数2 判断整数1是否小于等于整数2
[ 2 -eq 2 ]&&echo "2==2"|| echo "no"
[ 3 -ne 2 ]&&echo "2!=2"|| echo "no"
[ 3 -gt 2 ]&&echo "2>2"|| echo "no"
[ 1 -lt 2 ]&&echo "2<2"|| echo "no"
[ 2 -ge 2 ]&&echo "2>=2"|| echo "no"
[ 2 -le 2 ]&&echo "2<=2"|| echo "no"

5.1.5 字符串的判断 #

选项 含义
-z 字符串 判断字否串是否为空
-n 字符中 判断字符串是否为非空
字符串1 == 字符串2 判断字符串1是否和字符串2相等
字符串1 != 字符串2 判断字符串1是否和字符串2不相等

name=zhufeng
[ -z "$name" ]&&echo "yes"|| echo "no"
name2=zhufeng
[ "$name" == "$name2" ]&&echo "yes"|| echo "no"

5.1.6 多重条件判断 #

选项 含义
判断1 -a 判断2 逻辑与
判断1 -o 判断2 逻辑或
!判断 逻辑非
[ 2 -gt 1 -a 3 -gt 2 ]&&echo "yes"|| echo "no"
[ 2 -gt 1 -a 3 -gt 4 ]&&echo "yes"|| echo "no"
[ 2 -gt 1 -o 3 -gt 4 ]&&echo "yes"|| echo "no"
[ ! 3 -gt 4 ]&&echo "yes"|| echo "no"

5.2 单分支if语句 #

5.2.1 语法 #

if [条件判断];then
 代码体
fi
if [条件判断]
then
 代码体
fi
if [ 2 -gt 1 ];then echo bigger; fi

5.2.2 判断当前用户是否是root用户 #

#!/bin/bash
user=$(whoami)
user=`whoami`
if [ "$user" == root ]
then
echo "I am root"
fi

5.3 双分支if语句 #

5.3.1 语法 #

if [条件判断]
then
 代码体1
else
 代码体2 
fi

5.3.2 判断是否目录 #

#!/bin/bash
read -t 10 -p "please input a filename" dir
if [ -d "$dir" ]
then
  echo "is directory"
else 
  echo "not a direcotry"
fi

5.4 多分支if语句 #

5.4.1 语法 #

if [条件判断1]
then
 代码体1
elif [条件判断2] 
 代码体2
else
 代码体3
fi
#!/bin/bash
read -p "please input a grade" grade
if [ "$grade" -gt 90 ]
 then
  echo great
elif [ "$grade" -gt 80 ]
  then
   echo good
else
   echo bad
fi

5.5 case 语句 #

#!/bin/bash
read -p "yes or no?" -t 30 choose
case $choose in 
  "yes")
    echo 'yes'
    ;;
  "no")
    echo "no"
   ;;
  *)
    echo other
   ;;
esac

5.6 for循环 #

5.6.1 语法 #

for 变量 in123
do
代码块
done
#!/bin/bash
for i in 1 2 3
do
 echo $i
done

5.6.2 语法 #

#!/bin/bash  

for((i=1;i<=10;i++));  
do   
 echo $(($i));  //加不加$都一样
done 

5.7 while循环 #

while [条件判断式]
do
 代码块
done
#!/bin/bash
i=1
result=0
while [ $i -le 100 ]
 do
   result=$(($result+i))
   i=$(($i+1))
 done
echo $result

5.8 until循环 #

#!/bin/bash
i=1
result=0
until [ $i -gt 100 ]
 do
   result=$(($result+i))
   i=$(($i+1))
 done
echo $result

6. 函数 #

6.1 简单函数 #

[ function ] funcname [()]
{
    action;
    [return int;]
}
start(){
>  echo start
> }
 start
#!/bin/bash
start(){
 echo start
}
start

6.2 返回值 #

> sum4(){
> r=$(($1+$2))
> return $r
> }
# sum4 2 3
echo $?
5

6.3 参数说明 #

参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$- 显示Shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误

6.4 profile #

6.4.2 打印当前shell的选项 #

#  echo $-
himBH
set -x
[root@localhost ~]# echo $-
+ echo himxBH
himxBH

6.4.3 选项 #

6.4.3.2 H - history expand #
6.4.3.3 B - brace expansion #
echo g{a,b,c}$
6.4.3.4 m - monitor mode #
 sleep 10s
6.4.3.5 h - hashal #

6.4.4 删除 #

从左往右看,删除掉 $- 变量的值中第一个 i 字符以及之前的内容

${-#*i}

%与#号的意义刚好相反,从右往左看,删除掉 $- 变量的值中最后一个 i 字符以及之后的内容

${-%i*}

7.shell实战 #

7.1 注意事项 #

7.2 获取随机字符串或数字 #

7.2.1 获取随机8位字符串 #

echo $RANDOM |md5sum|cut -c 1-8
cat /proc/sys/kernel/random/uuid | cut -c 1-8

7.2.2 获取随机8位数字 #

echo $RANDOM |cksum|cut -c 1-8
date +%N | cut -c 1-8

7.3 定义一个颜色输出字符串函数 #

数值 含义
0 默认值
1 高亮
22 非粗体
4 下划线
24 非下划线
5 闪烁
25 非闪烁
7 反显
27 非反显

前景色

数值 含义
30 黑色
31 红色
32 绿色
33 黄色
34 蓝色
35 洋红
36 青色
37 白色

背景色

数值 含义
40 黑色
41 红色
42 绿色
43 黄色
44 蓝色
45 洋红
46 青色
47 白色
echo -e "\033[m hello \033[m"
显示方式: 正常    字体前景色:红色  背景色:青色
echo -e "\033[0;31;46m hello \033[m" 
#!/bin/bash
#description: test
function echo_color(){
  if [ $1 == "green" ]; then
     echo -e "\033[32;40m$2\033[0m"
  elif [ $1 == "red" ]; then
     echo -e "\033[31;40m$2\033[0m"  
  fi    
}

echo -e "\033[32;40mshell\033[0m"
echo -e "\033[33;40mshell\033[0m"

echo_color red hello

7.4 批量创建用户 #

符号 含义
> 代表重定向到哪里
/dev/null 代表空设备文件
2 表示stderr标准错误
& 表示等同于的意思,2>&1,表示2的输出重定向等同于1
1 1表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于 "1>/dev/null"
#!/bin/bash
USER_FILE=users.txt
for USER in user{1..5}; do
  if ! id $USER &>/dev/null; then
    PASS=$(echo $RANDOM | md5sum | cut -c 1-8)
    useradd $USER
    echo $PASS | passwd --stdin $USER &> /dev/null
    echo -e "$USER\t$PASS" >> $USER_FILE
    echo "$USER user create successfully."
  else
    echo_color red "$USER already exists.";  
  fi
done

7.5 检查主机存活状态 #

#!/bin/bash
for IP in $@; do
  if ping -c 1 $IP &>/dev/null; then
     echo "$IP is ok."
  else
     echo "$IP is wrong!"
  fi
done       

7.6 系统监控 #

7.6.1 系统命令 #

7.6.1.1 vmstat #
vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0    532 329932  99388 459768    0    0    16    81   59   50  3  1 96  0  0    
7.6.1.1.1 (procs)进程信息字段 #
分类 参数 含义
procs r 等待运行的进程数,数量越大,系统就越繁忙
procs b 不可被唤醒的进程数量,数量越大,系统越繁忙
7.6.1.1.2 memory(内存信息字段) #
分类 参数 含义
memory swpd 使用的Swap空间的大小,单位KB
memory free 空闲的内存容量,单位KB
memory buff 缓冲的内存容量,单位KB
memory cache 缓存的内存容量,单位KB
7.6.1.1.3 swap(交换分区信息) #
分类 参数 含义
swap si(in) 从磁盘中交换到内存中的数据的数量,单位KB
swap so(out) 从内存中交换到硬盘中的数据的数量,单位KB
7.6.1.1.4 io(磁盘读写) #
分类 参数 含义
io bi(in) 从块设备读入数据的问题,单位是块
io bo(out) 写到块设备的数据的总量,单位是块
7.6.1.1.5 system(系统信息字段) #
分类 参数 含义
system in(interrupt) 每秒被中断的进程次数
system cs(switch) 每秒钟进行的事件切换次数
7.6.1.1.6 CPU(CPU信息字段) #
分类 参数 含义
CPU us(user) 非内核进程消耗CPU运算时间的百分比
CPU sy(system) 内核进程消耗CPU运算时间的百分比
CPU id(idea) 空闲CPU的百分比
CPU wa(wait) 等待I/O所消耗的CPU百分比
CPU st(steal) 被虚拟机偷走的CPU百分比
7.6.1.2 free #

选项 |参数名称|参数含义| |:----|:----| |-b|以字节为单位| |-k|以KB字节为单位| |-m|以MB字节为单位| |-g|以GB字节为单位|

# free -m
             total       used       free     shared    buffers     cached
Mem:          1006        687        319          0         98        449
-/+ buffers/cache:        139        866
Swap:         1999          0       1999
7.6.1.2.1 第一行 #
分类 参数 含义
total 内存总数,total=used+free
used 已经使用的内存数
free 空闲的内存数
shared 多个进程共享的内存数,0,废弃,永远为0
buffers 缓冲区内存数,buffer用于作为写入磁盘的内容缓冲区
cached 缓存内存数,用于从磁盘中读取的内容缓存
7.6.1.2.2 第二行 #
参数 算法 含义
- buffers/cache 第一行的used-buffers-cached 已经使用的要减去缓存和缓冲的内存量
+ buffers/cache 第一行的free+buffers+cached 空闲的要加上缓存和缓冲的内存量
7.6.1.2.3 第三行 #
分类 参数 含义
total swap总数,默认单位是K
used 已经使用的swap数,默认单位是K
free 空闲的swap数,默认单位是K
7.6.1.3 查询网络状态 #
选项 含义
-t 列出TCP协议端口
-u 列出UDP协议端口
-n 不使用域名与服务名,而使用IP地址和端口号
-l 仅列出在监听状态网络服务
-a 列出所有的网络连接
netstat -tlun
netstat -an | more
netstat -unt | grep  ESTABLISHED

7.6.2 函数 #

7.6.2.1 cpu #
#!/bin/bash
cpu(){
    local user system idle cwait
    user=$(vmstat | awk 'NR==3{print $13}')
    system=$(vmstat | awk 'NR==3{print $14}')
    idea=$(vmstat | awk 'NR==3{print $15}')
    cwait=$(vmstat | awk 'NR==3{print $16}')
    echo "user cpu: $user%"
    echo "system cpu: $system%"
    echo "idle cpu: $idea%"
    echo "wait: $cwait%"
}
cpu
7.6.2.2 memory #
memory(){
  local total used free
  used=$(free -m | awk 'NR==3{print $3}')
  free=$(free -m | awk 'NR==3{print $4}')
  total=$(($used+$free))
  echo "内存总计: ${total}M"
  echo "内存使用: ${used}M"
  echo "内存剩余: ${free}M"
}
memory
7.6.2.3 disk #
disk(){
  local mount total used used_percent free
  partitions=$(df -h|awk 'BEGIN{OFS="="}/^\/dev/{print $6,$2,$3,$4,$5}')
  echo $p
  for p in  $partitions; do
    mount=$(echo $p | cut -d"=" -f1)
    total=$(echo $p | cut -d"=" -f2)
    used=$(echo $p | cut -d"=" -f3)
    free=$(echo $p | cut -d"=" -f4)
    used_percent=$(echo $p | cut -d"=" -f5|cut -d"%" -f1)
    if [ $used_percent -ge 5 ]; then
      echo "挂载点=$mount,总大小=$total,使用大小=$used,空闲大小=$free,使用百分比=$used_percent%"
    fi  
  done
}

7.7 监控网络流量 #

network(){
    local old_in old_out new_in new_out
    old_in=$(ifconfig ens33 | awk '/RX/&&/bytes/{print $5}')
    old_out=$(ifconfig ens33 | awk '/TX/&&/bytes/{print $5}')
    sleep 1s
    new_in=$(ifconfig ens33 | awk '/RX/&&/bytes/{print $5}')
    new_out=$(ifconfig ens33 | awk '/TX/&&/bytes/{print $5}')
    in=$(($new_in-$old_in))
    out=$(($new_out-$old_out))
    echo "$1 入口流量=${in}bytes/s 出口流量=${out}bytes/s"
}
network

7.8 监控网站状态 #

curl -o /dev/null -s -w "%{http_code}" http://www.baidu.com


function check_url(){
    HTTP_CODE=$(curl -o /dev/null -s -w "%{http_code}" $1)
    if [ $HTTP_CODE -ne 200 ]; then
      echo "$1不可达"
    else
      echo "$1状态正常"  
    fi
}

7.9 监控nginx状态 #

7.9.1 本地安装nginx #

rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum install -y nginx
systemctl start nginx.service
systemctl status  nginx.service

7.9.2 监控脚本 #

#!/bin/bash
local nginx
nginx=`ps -ef |grep nginx|grep -v grep|wc -l`
 if [ $nginx -gt 2 ];then
    echo "your nginx is running"
    exit 0
 else
    /bin/systemctl start nginx.service
    exit 1
fi

7.10 监控mysql状态 #

7.10.1 本地安装mysql #

wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
yum -y install mysql57-community-release-el7-10.noarch.rpm
yum -y install mysql-community-server
systemctl start  mysqld.service
systemctl status mysqld.service


mysql -uroot -p

7.10.2 默认密码和忘记密码 #

cat  /var/log/mysqld.log | grep  temporary

1. 修改/etc/my.conf, 添加参数skip-grant-tables
systemctl restart mysqld.service
mysql -uroot
use mysql
update user set authentication_string=PASSWORD('123456') where User='root';
alter user 'root'@'localhost' identified by 'Zfpx2019@qq.com';

7.10.3 监控脚本 #

#!/bin/sh
PortNum=`netstat -lnt|grep 3306|wc -l`
if [ $PortNum -eq 1 ]
then
 echo "mysqld is running."
else
 echo "mysqld is stoped."
fi

7.11 mysql备份脚本 #

#!/bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=127.0.0.1
DB=test
USER=root
PASS=Zfpx2019@qq.com
MAIL="83687401@qq.com"
BACKUP_DIR=/data/db_backup
if [ ! -d "$BACKUP_DIR" ];then
 mkdir -p $BACKUP_DIR
fi
SQL_FILE=${DB}_FULL_$DATE.sql
BAK_FILE=${DB}_FULL_$DATE.zip
cd $BACKUP_DIR
if mysqldump -h$HOST -u$USER -p$PASS -B $DB > $SQL_FILE; then
  zip $BAK_FILE $SQL_FILE && rm -rf $SQL_FILE
  if [ ! -s $BAK_FILE ]; then
    echo "$DATE 备份失败" | mail -s "备份失败" $MAIL
  fi
else
  echo "$DATE 备份失败" | mail -s "备份失败" $MAIL
fi
find $BACKUP_DIR -name '*.zip' -ctime +14 -exec rm {} \;

8. 附录 #

8.1. Linux特殊文件 #

8.1.1 块设备 #

# ll /dev/sr0
brw-rw----.   /dev/sr0

8.1.2 字符设备 #

# ll /dev/input/mouse0
crw-r-----.   /dev/input/mouse0
# ll /dev/input/event0
crw-r-----.  /dev/input/event0

8.1.3 管道文件 #

find / -type p
ll /var/run/autofs.fifo-misc

8.1.4 套接字 #

[root@localhost input]# ll /tmp/mysql.sock
srwxrwxrwx. 1 mysql mysql 0 4月   6 12:18 /tmp/mysql.sock
[root@localhost input]# ll /var/run/cups/cups.sock
srwxrwxrwx. 1 root root 0 4月   6 17:51 /var/run/cups/cups.sock