shell编程 -- exec、xargs、shift、trap、split、paste、sort、cut、tr、wc、vmstat、sar、pash

一、exec

使用exec调用其他命令或脚本,语法如下:

exec  [命令]  [参数]

1)如下脚本,exec调用ls命令,执行以后就结束了整个脚本。但是可以看出exec之前的命令正常被执行。

[root@localhost ~]# ./exec.sh 
开始
2  a  anaconda-ks.cfg  chess.sh  exec.sh  jiaofan  mysql  subshell_6.sh  test  test.txt  ver1.txt  ver2.txt
[root@localhost ~]# ls
2  a  anaconda-ks.cfg  chess.sh  exec.sh  jiaofan  mysql  subshell_6.sh  test  test.txt  ver1.txt  ver2.txt
[root@localhost ~]# 

2)上述情况有一个特例:当exec 后面的参数是文件重定向时,不会替换当前shell 环境,脚本后续的其他命令不会受任何影响。

二、xargs

前面说的使用管道命令可以将前一个命令的输出结果存入管道,然后别的命令就可以从管道中读取数据作为输入。
1)但是有些程序是不支持使用管道传递参数的,比如find、cut 这样的程序。

[root@www ~]# cut -d: -f1 /etc/passwd | echo    #<==输出为空

[root@www ~]# find /etc -name *.conf  | echo    #<==输出为空

[root@www ~]# 

2)有些程序仅可以从命令参数中读取输入的数据,无法从管道中读取数据,如:kill、rm

[root@www ~]# cat /var/run/crond.pid  | kill         #<==报错
kill: 用法:kill [-s 信号声明 | -n 信号编号 | -信号声明] 进程号 | 任务声明 ... 或 kill -l [信号声明]
[root@www ~]# touch /tmp/test.txt
[root@www ~]# echo /etc/test.txt | rm                #<==报错
rm: 缺少操作数
Try 'rm --help' for more information.
[root@www ~]# 
xargs的参数描述
-0配合find的-print0一起使用,find -print0 在输出文件名后自动添加一个NULL来代替换行符,xargs -0 指定使用NULL作为换行符,而不是空格、tab制表符或者换行符作为结束符。对xargs来说空格就变成了一个普通字符,只有null才被识别为参数的结束符。
-a从文件中读取参数传递给其他程序
-n指定一次读取几个参数,默认读取所有参数
-d指定任意字符为分隔符,默认以空格、Tab制表符或换行符为分隔符
-I(小写的L)指定一个替换字符串,xargs会用读取到的参数替换掉这个替换字符串

3)xargs命令就可以读取标准输入或管道中的数据,并将这些数据传递给其他程序作为参数,不指定程序时 xargs 默认会将数据传递给echo命令。

[root@www ~]# cat /etc/centos-release | xargs
CentOS Linux release 7.9.2009 (Core)
[root@www ~]# cat /etc/centos-release | xargs echo
CentOS Linux release 7.9.2009 (Core)
[root@www ~]# find /etc -name *.conf | xargs grep yum     #<==过滤查找的文件
/etc/yum/pluginconf.d/langpacks.conf:# - any previously installed langpacks (stored in /var/lib/yum/plugins/langpacks)
/etc/yum/version-groups.conf:[yum]
[root@www ~]# find /etc -name *.conf | xargs wc -l        #<==查看每个文件的行数
     3 /etc/resolv.conf
    24 /etc/pki/ca-trust/ca-legacy.conf
    12 /etc/yum/pluginconf.d/fastestmirror.conf
    12 /etc/yum/pluginconf.d/langpacks.conf

4)特殊情况,有些文件自身就包含空格。

[root@www ~]# touch "aa bb.txt"
[root@www ~]# find ./ -name "*.txt" | xargs rm
rm: 无法删除"./aa": 没有那个文件或目录
rm: 无法删除"bb.txt": 没有那个文件或目录
[root@www ~]# find ./ -name "*.txt" -print0 | xargs -0 rm 
[root@www ~]# 

5)其他参数案例:

[root@www ~]# xargs -a /etc/centos-release echo
CentOS Linux release 7.9.2009 (Core)
[root@www ~]# xargs -a /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.91.157 www.centos.vbird 192.168.91.159 clientlinux.centos.vbird
[root@www ~]# 
[root@www ~]# seq 6 | xargs
1 2 3 4 5 6
[root@www ~]# seq 6 | xargs -n 3
1 2 3
4 5 6
[root@www ~]# seq 6 | xargs -n 4
1 2 3 4
5 6
[root@www ~]# 
[root@www ~]# echo "hellojsdjsdjosihfso" | xargs
hellojsdjsdjosihfso
[root@www ~]# echo "hellojsdjsdjosihfso" | xargs -ds
helloj dj djo ihf o

[root@www ~]# 
[root@www jiaofan]# touch {a,b,c}.txt
[root@www jiaofan]# ls *.txt | xargs -I{}  cp {} /tmp/      #<==复制所有txt文件到/tmp下
[root@www jiaofan]# rm -rf /tmp/{a,b,c}.txt
[root@www jiaofan]# ls *.txt | xargs -I[]  cp [] /tmp/      #<==设置[]为替换字符串
[root@www jiaofan]# rm -rf /tmp/{a,b,c}.txt
[root@www jiaofan]# ls *.txt | xargs -I%  cp % /tmp/        #<==设置%为替换字符串

三、shift

shift 可以左移位置参数,shift后面跟一个非负数。

[root@localhost ~]# ./parameter.sh 1 2 3 4 5 6
a1=1 a2=1 a3=3 a4=4  a5=5 a6=6 conut=6
a1=2 a2=2 a3=4 a4=5  a5=6 a6= conut=5
a1=4 a2=4 a3=6 a4=  a5= a6= conut=3
a1=5 a2=5 a3= a4=  a5= a6= conut=2
[root@localhost ~]# cat parameter.sh 
#!/bin/bash
#功能描述:shift参数左移
echo "a1=$1 a2=$1 a3=$3 a4=$4  a5=$5 a6=$6 conut=$#"
shift            #位置参数左移1位
echo "a1=$1 a2=$1 a3=$3 a4=$4  a5=$5 a6=$6 conut=$#"
shift  2         #位置参数左移2位
echo "a1=$1 a2=$1 a3=$3 a4=$4  a5=$5 a6=$6 conut=$#"
shift  1         #位置参数左移1位
echo "a1=$1 a2=$1 a3=$3 a4=$4  a5=$5 a6=$6 conut=$#"
[root@localhost ~]# 

案例一:空文件测试脚本

[root@localhost ~]# ./empty.sh  a.txt
a.txt 为空文件,正在删除该文件
[root@localhost ~]# cat empty.sh 
#!/bin/bash
#功能描述:读取位置参数,测试是否空文件并删除空文件

if [ $# -eq 0 ];then
	echo "用法:$0 文件名..."
	exit 1
fi
#测试位置变量个数,个数为0时循环结束
while (($#))
do
	if [ ! -s $1 ];then
		echo -e "\e[31m$1 为空文件,正在删除该文件\e[0m"
		rm -f $1
	else
		[ -f $1 ] && echo -e "\e[32m$1 为非空文件\e[0m"
		[ -f $1 ] && echo -e "\e[32m$1 为目录,不是文件\e[0m"
	fi
	shift
done
[root@localhost ~]# 

四、trap

trap  '命令'  信号列表

当trap接收到kill发来的信号时,就会执行’'中的命令

kill本质上是在给进程发送特定的信号,这个信号可以告诉进程终止运行、暂停、继续运行、切换日志等,而进程在收到这些信号后就会执行具体动作,在shell 脚本中我们可以通过 trap 命令捕获传递过来的信号。

[root@localhost ~]# ps -aux | grep loop.sh
root       1858  0.0  0.1 113280  1408 pts/0    S+   14:15   0:00 /bin/bash ./loop.sh
root       1861  0.0  0.1 112824  1000 pts/1    R+   14:15   0:00 grep --color=auto loop.sh
[root@localhost ~]# kill -19 1858          #<==传递暂停信号
[root@localhost ~]# kill -CONT 1858        #<==传递恢复信号
[root@localhost ~]# kill -SIGINT 1858      #<==终端结束循环脚本

案例一:ctrl+c组合键会发送INT的信号。

[root@localhost jiaofan]# ./loop.sh 
^C我接受到了kill发来的信号                #<==ctrl+c组合键会发送INT的信号。
^C我接受到了kill发来的信号
^C我接受到了kill发来的信号
[root@localhost jiaofan]# cat loop.sh 
#!/bin/bash
trap 'echo "我接受到了kill发来的信号"'  INT

while :
do
	sleep 10
done

案例二:kill的信号列表

[root@localhost jiaofan]# kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	
[root@localhost jiaofan]# 

五、split

选项解释
-l设置分割行数
-d设置后缀为数字
-a设置后缀为几位
-C 10K把文件切割为10k大小的文件,但是切割的时候会保证文件行内容的完整性
-b 4按4个字节容量进行切割
[root@localhost jiaofan]# split file                           #<==默认将文件以每5000行进行分割, 生成的文件名为xaa xab xac xad ....
[root@localhost jiaofan]# split -l 100 file                    #<==设置文件以每 100 行进行分割,后缀默认为两个字符,前缀默认为x,生成的文件名为xaa xab xac xad ....
[root@localhost jiaofan]# split -d -l 100 file                 #<==设置文件以每 100 行进行分割,后缀默认为两位数字,前缀默认为x,生成文件为x00 x01 x02 x03 ....
[root@localhost jiaofan]# split -d -l 100 file prefix          #<==设置文件以每 100 行进行分割,后缀默认为两位数字,前缀设置为prefix,生成文件为prefix00 prefix01 prefix02 pefix03 ....
[root@localhost jiaofan]# split -d -l 100 -a 3 file prefix     #<==设置文件以每 100 行进行分割,后缀为3位数字,前缀为prefix,生成文件为prefix000 prefix001 prefix002 pefix003 ....

六、paste

paste 组合数据列
使用
paste file1 file2 file3 > file  将文件1,2,3按列组合在一起为新的文件,默认间隔字符为8个空格
paste -d ' ' file1 file2 file3 > file 将文件1,2,3 按列组合在一起,设置间隔字符为一个空格
paste -d '|%' file1 file2 file3 > file 将文件1,2,3按列组合在一起,设置间隔符号为’|’ 和'%'.

七、sort

1、sort

选项说明
-b忽略每行前面的空白区域
-d只考虑处理空格和字母字符,数字
-f忽略字母大小写
-m合并已经排序的文件,不排序
-n根据字符串的数字比较
-o将排序后的结果写入文件
-r以相反的顺序来排序(sort默认排序是从上往下是从小到大,加使用-n选项可以翻转排序)
-t指定排序时所用的分隔字符
-k指定需要排序的栏位(列,域)
-u忽略相同行

八、cut

[root@www ~]# cut -d'分隔字符' -f1,2,5 fields       <==用于有特定分隔字符
[root@www ~]# cut -c 字符区间                  <==用于排列整齐的信息
选项与参数:
-d  :后面接分隔字符。与 -f 一起使用;
-f  :依据 -d 的分隔字符将一段信息分割成为数段,用 -f 取出第几段的意思;
-c  :以字符 (characters) 为单位取出固定字符区间;

范例一:将 PATH 变量取出,我要找出第五个路径。

[root@www ~]# echo $PATH
/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
# 1                 |    2          |  3           |    4    |    5   |   6    |  
[root@localhost jiaofan]# echo $PATH | cut -d ':' -f 5      #<==以:为分隔符输出第5列
/usr/bin
[root@localhost jiaofan]# echo $PATH | cut -d ':' -f 3,5    #<==以:为分隔符输出第3列和第5列
/usr/local/bin:/usr/bin
[root@localhost jiaofan]# 

范例二:将 export 输出的信息,取得第 12 字符以后的所有字符串

[root@localhost jiaofan]# export
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="localhost.localdomain"
declare -x LANG="zh_CN.UTF-8"
.....(其他省略).....

#注意看,每个数据都是排列整齐的输出!如果我们不想要『 declare -x 』时,就得这么做:

[root@localhost jiaofan]# export | cut -c 12-
HISTCONTROL="ignoredups"
HISTSIZE="1000"
HOME="/root"
HOSTNAME="localhost.localdomain"
LANG="zh_CN.UTF-8"
.....(其他省略).....

知道怎么回事了吧?用 -c 可以处理比较具有格式的输出数据!
我们还可以指定某个范围的值,例如第 12-20 的字符,就是 cut -c 12-20 等等!

案例三:用 last 将显示的登陆者的信息中,仅留下用户大名

[root@localhost jiaofan]# last
root     pts/0        192.168.91.1     Fri Feb 18 10:37   still logged in   
reboot   system boot  3.10.0-1160.el7. Fri Feb 18 10:36 - 13:40  (03:03)    
root     pts/0        192.168.91.1     Thu Feb 17 09:05 - crash (1+01:30)   
.....(其他省略).....

last 可以输出『账号/终端机/来源/日期时间』的数据,并且是排列整齐的

[root@localhost jiaofan]# last | cut -d ' ' -f 1 | sort -u
reboot
root
wtmp

九、tr

  1. tr a A < old 将old文件中所有小写a替换为大写A
  2. tr a A < old > new 将old文件中所有小写a替换为大写A并保存到new文件中
  3. tr abc ABC < old > new 按照字符映射进行替换 a => A , b => B, c => C
  4. tr abcde AX < old > new 第二组字符少于第一组字符,所以bcde均被替换为X
  5. tr ‘:;?’ . < old > new 将冒号分号和问号都替换为点号
  6. tr A-Z a-z < old > new 将大写字母全部替换为小写字母
  7. tr [:upper:] [:lower:] < old > new 将大写字母全部替换为小写字母
  8. tr 0-9 A-J < old > new 将数字0-9替换为字母A-J
  9. tr [:digit:] A-J < old > new 将数字0-9替换为字母A-J
  10. tr ‘\r’ ‘\n’ < macfile > unixfile 将回车改变成新行
  11. tr ‘\015’ ‘\012’ < macfile > unifile 将回车改变成新行
  12. tr ‘\t’ ’ ’ < old > new 将制表符改变为空格
  13. tr ‘\011’ ’ ’ < old > new 将制表符改变为空格
    选项:
    -s : 将第一组中多个连续字符替换为一个单独的字符
    tr -s 0-9 X < old > new 将连续数字替换为一个X
    tr -s ’ ’ ’ ’ < old > new 将多个连续空格合并为一个空格
    -d : 删除指定字符
    tr -d ‘()’ < old > new 删除左右圆括号
    tr -d 0-9 < old > new 删除所有数字
    -c : 匹配所有不在第一组中的字符
    tr -c ’ \n’ x < old > new 将除空格和新行字符之外的所有字符都替换为x
选项功能描述
-s删除连续的多个重复数据
-d删除包括特定集合的数据
-c使用数据集1的差集

用法:

tr  [选项]  数据集1 [数据集2]
[root@localhost jiaofan]# echo "hello the world" | tr 'h' 'H'         #<==小写h转为大写H
Hello tHe world
[root@localhost jiaofan]# echo "hello the world" | tr 'a-z' 'A-Z'     #<==小写字母变为大写
HELLO THE WORLD
[root@localhost jiaofan]# echo "hello the world" | tr 'hello' '12345' #<==1替换h,2替换e,以此类推
12445 t12 w5r4d
[root@localhost jiaofan]# echo "hello the world" | tr 'hello' 'wo'    #<==w替换h,o替换e,由于没有了替换项,所以l、l、o都会被替换成o
woooo two worod
[root@localhost jiaofan]# tr 'a-z' 'A-Z' < /etc/passwd | head -2      #<==从标准输入中读取数据
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN

[root@localhost jiaofan]# echo "aaa" | tr -s a                        #<==删除重复的a
a
[root@localhost jiaofan]# echo "aaabbb" | tr -s ab                    #<==删除重复的ab
ab
[root@localhost jiaofan]# echo "aaabbbabab" | tr -s ab                #<==非连续的a不会删除
ababab
[root@localhost jiaofan]# echo "hello the world" | tr -d 'h'          #<==删除字母h
ello te world
[root@localhost jiaofan]# echo "hello the world" | tr -d 'ho'         #<==删除字母ho
ell te wrld
[root@localhost jiaofan]# echo "hello the world" | tr -d 'a-e'         #<==删除字母a-e
hllo th worl
[root@localhost jiaofan]# echo "hello the world" | tr -cd 'to'         #<==删除取反就是保留t、o,回车键都被删除了
oto[root@localhost jiaofan]# 
[root@localhost jiaofan]# echo "hello 666" | tr -cd a-z                #<==保留字母
hello[root@localhost jiaofan]# echo "hello 666" | tr -cd 0-9           #<==保留数字
666[root@localhost jiaofan]# echo "hello 666" | tr -cd '0-9\n'         #<==保留数字和回车键
666
[root@localhost jiaofan]# echo "hello 666" | tr -c '0-9' x             #<==x替代所有数字
xxxxxx666x[root@localhost jiaofan]# 

十、wc

-c :输出数据的字节数
-l:小写的L,输出数据的总行数
-w:输出数据的单词数

十一、vmstat

vmstat监视内存性能:该命令用来检查虚拟内存的统计信息,并可显示有关进程状态、空闲和交换空间、调页、磁盘空间、CPU负载和交换,cache刷新以及中断等方面的信息。
注释:vmstat输出结果中第一行展示的是自最后一次启动以来的平均值,所以此行可以忽略。
命令参数
              -V  显示版本
              -n  只在开始时显示一次各字段名称
              -a  显示活跃和非活跃内存
              -d  显示磁盘相关统计信息
              -D  以表格的形式显示磁盘信息
              -p  显示指定磁盘分区相关信息
              -s   显示内存相关统计信息及多种活动数量
                  delay:刷洗时间间隔。如果不指定,只显示一条结果
                  count:刷新次数,如不指定刷新次数,但不指定刷新时间间隔,默认为无穷
              -m 显示slabinfo
              -t 显示统计信息的同时打印出时间,该参数和上面的参数同时使用
              -S 指定单位显示,如,k,K,m,M
[root@localhost jiaofan]# vmstat
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      0 620804   2184 219628    0    0    82    10   57  140  0  0 99  0  0
[root@localhost jiaofan]# 

1、Procs

名称描述备注
r运行和等待cpu时间片的进程数这个值如果长期大于系统CPU的个数,说明CPU不足,需要增加CPU。
b等待资源的进程数比如正在等待I/O、或者内存交换等。

2、memory

名称描述备注
swpd切换到内存交换区的内存数量(以k为单位)如果swpd的值不为0,或者比较大,比如超过了100M,只要si、so的值长期为0,这种情况下一般不用担心,不会影响系统性能。
free当前空闲的物理内存数量(以k为单位)
buffbuffers cache的内存数量一般对块设备的读写才需要缓冲
cachepage cached的内存数量一般作为文件系统cached,频繁访问的文件都会被cached,如果cache值较大,说明cached的文件数较多,如果此时IO中bi比较小,说明文件系统效率比较好。

3、swap

名称描述备注
si由磁盘调入内存,也就是内存进入内存交换区的数量从磁盘交换到内存的交换页数量,单位:KB/秒
so由内存调入磁盘,也就是内存交换区进入内存的数量从内存交换到磁盘的交换页数量,单位:KB/秒

1、内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。
2、有些朋友看到空闲内存(FREE)很少的或接近于0时,就认为内存不够用了,实际上不能光看这一点,还要结合si,so,如果free很少,但是si,so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

4、IO

名称描述备注
bi从块设备读入的数据总量(读磁盘)(KB/S)
bo写入到块设备的数据总量(写磁盘)(KB/S)

注:随机磁盘读写的时候,这2个值越大(如超出1M),能看到CPU在IO等待的值也会越大。(这里我们设置的bi+bo参考值为1000KB/s,如果超过1000KB/s,而且wa值较大应该考虑均衡磁盘负载,可以结合iostat输出来分析。)

5、System

名称描述备注
in每秒的中断数,包括时钟中断。
cs每秒的环境(上下文)切换次数例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。

注:上面2个值越大,会看到由内核消耗的CPU时间会越大

6、Cpu

名称描述备注
us显示了用户进程消耗的CPU 时间百分比us的值比较高时,说明用户进程消耗的cpu时间多,但是如果长期大于50%,就需要考虑优化程序或算法。
sy显示了内核进程消耗的CPU时间百分比Sy的值较高时,说明内核消耗的CPU资源很多。
idCPU处于空闲状态时间百分比
waIO等待消耗的CPU时间百分比wa的值高时,这里wa的参考值为30%,如果wa超过30%,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈(块操作)

注:

  1. 根据经验,us+sy的参考值为80%,如果us+sy大于 80%说明可能存在CPU资源不足。
  2. us:花费在非内核代码的CPU 时间 (用户时间,包括Nice时间)
  3. sy:花费在内核代码的CPU 时间(系统时间)
  4. id:空闲时间
  5. wa:IO等待时间
  6. 标准情况下r和b值 r<5,b≈0 。如果user%+sys%< 70%,表示系统性能较好;如果user%+sys%>=85%,表示系统性能比较糟糕
  7. user%表示CPU处在用户模式下的时间百分比。
  8. sys%表示CPU处在系统模式下的时间百分比。

*注意:
NFS由于是在内核里面运行的,所以NFS活动所占用的cpu时间反映在sy里面。这个数字经常很大的话,就需要注意是否某个内核进程,比如NFS任务比较繁重。如果us和sy同时都比较大的话,就需要考虑将某些用户程序分离到另外的服务器上面,以免互相影响。
CPU问题现象:

  1. 如果在processes中运行的序列(process r)是连续的大于在系统中的CPU的个数表示系统现在运行比较慢,有多数的进程等待CPU。
  2. 如果r的输出数大于系统中可用CPU个数的4倍的话,则系统面临着CPU短缺的问题,或者是CPU的速率过低,系统中有多数的进程在等待CPU,造成系统中进程运行过慢。
  3. 如果空闲时间(cpu id)持续为0并且系统时间(cpu sy)是用户时间的两倍(cpu us) 系统则面临着CPU资源的短缺。
    解决办法:
    当发生以上问题的时候请先调整应用程序对CPU的占用情况。使得应用程序能够更有效的使用CPU。同时可以考虑增加更多的CPU。
    关于CPU的使用情况还可以结合mpstat, ps aux top prstat等等一些相应的命令来综合考虑关于具体的CPU的使用情况,和那些进程在占用大量的CPU时间。一般情况下,应用程序的问题会比较大一些。比 如一些SQL语句不合理等等都会造成这样的现象。

情景分析:
vmstat的输出哪些信息值得关注?
–proc r:运行的进程比较多,系统很繁忙
–IO bo:磁盘写的数据量稍大,如果大文件的写,10以内基本不用担心,如果是小文件2M以前基本正常,
–CPU us:持续大于50,服务高峰期可以接受
–CPU wa:稍微有些同
–CPU id:持续小于50,服务高峰期可以接受

十二、sar

在这里插入图片描述
参数:

-a:文件读写情况
-A:所有报告的总和
-B:分页状况
-b:显示I/O和传送速率的统计信息
-c:输出进程统计信息,每秒创建的进程数
-d:块设备状况
-F [ MOUNT ]:文件系统统计信息
-H:交换空间利用率
-I { <中断> | SUM | ALL | XALL }:中断信息状况
-n:汇报网络情况
-P:设定CPU
-q:队列长度和平均负载
-R:输出内存页面的统计信息
-r [ ALL ]:输出内存和交换空间的统计信息
-S:交换空间利用率信息
-u [ ALL ]:输出CPU使用情况的统计信息
-v:输出inode、文件和其他内核表的统计信息
-W:输出系统交换活动信息
-w:任务创建与系统转换信息
-y:终端设备活动情况

参考:https://zhuanlan.zhihu.com/p/362338572

十二、pssh

可以看到pssh这个包主要功能就是提供了各种基于ssh和scp的命令行工具,包里包含了pssh、pscp、pnuke、prsync、pslurp,这五个工具。这个包来源epel,所以在查看和安装之前请先配好自己的epel源。

1、-h:主机文件列表,内容格式"[user@]host[:port]"

[root@rabbitmq1 pssh]# cat iplist.txt
root@192.168.65.175
root@192.168.65.176
root@192.168.65.129
root@192.168.65.156
root@192.168.65.176
root@192.168.65.177
[root@rabbitmq1 pssh]# pssh -h iplist.txt 'ls -l /etc/passwd'
[1] 19:43:49 [SUCCESS] root@192.168.65.156
[2] 19:43:49 [SUCCESS] root@192.168.65.129
[3] 19:43:49 [SUCCESS] root@192.168.65.177
[4] 19:43:49 [SUCCESS] root@192.168.65.176
[5] 19:43:49 [SUCCESS] root@192.168.65.176
[6] 19:43:49 [SUCCESS] root@192.168.65.175
[root@rabbitmq1 pssh]#

2、-H:主机字符串,内容格式"[user@]host[:port]"。

[root@rabbitmq1 pssh]# pssh -H 192.168.65.156 'ls -l /etc/passwd'
[1] 19:46:38 [SUCCESS] 192.168.65.156
[root@rabbitmq1 pssh]# pssh -H 192.168.65.156 -H 192.168.65.129 'ls -l /etc/passwd'
[1] 19:46:41 [SUCCESS] 192.168.65.156
[2] 19:46:41 [SUCCESS] 192.168.65.129

说明:-H是指定某一台主机的选项,当然要指定多台主机,可以用-H一一指定,也可以用-H 指定很多主机,但是每个主机用空格隔开,且多个主机要用引号引起来。

** 3、-A:手动输入密码模式 **

[root@rabbitmq1 pssh]# pssh -H 192.168.65.156 -A 'ls -l /etc/passwd'
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 19:47:55 [SUCCESS] 192.168.65.156

4、-i:每个服务器内部处理信息输出

[root@rabbitmq1 pssh]# pssh -H 192.168.65.156 -i  'ls -l /etc/passwd'
[1] 19:49:43 [SUCCESS] 192.168.65.156
-rw-r--r-- 1 root root 1026 625 2023 /etc/passwd

说明:在我们不指定选项-i,pssh默认只输出执行命令的成功与失败状态,并不会把执行的结果信息打印出来。使用-i我们可以把在每台主机上执行命令的结果和命令执行成功与否一并显示。上面有一个centos6的主机上没有装iproute包所以 默认没有ip这个命令,所以命令没有执行成功。

5、-o:输出的文件目录

[root@rabbitmq1 pssh]# pssh -h iplist.txt -o ./jieguo/  'ls -l /etc/passwd'
[1] 19:52:25 [SUCCESS] root@192.168.65.156
[2] 19:52:25 [SUCCESS] root@192.168.65.129
[3] 19:52:25 [SUCCESS] root@192.168.65.177
[4] 19:52:25 [SUCCESS] root@192.168.65.176
[5] 19:52:25 [SUCCESS] root@192.168.65.176
[6] 19:52:26 [SUCCESS] root@192.168.65.175
[root@rabbitmq1 pssh]# ll ./jieguo/
总用量 24
-rw-r--r-- 1 root root 55 718 19:52 root@192.168.65.129
-rw-r--r-- 1 root root 54 718 19:52 root@192.168.65.156
-rw-r--r-- 1 root root 56 718 19:52 root@192.168.65.175
-rw-r--r-- 1 root root 56 718 19:52 root@192.168.65.176
-rw-r--r-- 1 root root 56 718 19:52 root@192.168.65.176.1
-rw-r--r-- 1 root root 55 718 19:52 root@192.168.65.177
[root@rabbitmq1 pssh]# cat ./jieguo/root@192.168.65.129
-rw-r--r-- 1 root root 1223 619 20:29 /etc/passwd

说明:-o是指定把命令执行的结果输出到以主机命名的文件存放地。也就是说命令执行后的结果保存在以主机命名的一个文件里,-o就是指定一个目录存放这些文件的。

6、-t:TIMEOUT超时时间设置,0无限

[root@rabbitmq1 pssh]# pssh -t 3 -h iplist.txt -i 'ping 8.8.8.8'
[1] 19:54:26 [FAILURE] root@192.168.65.175 Timed out, Killed by signal 9
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=43.3 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=42.8 ms
[2] 19:54:26 [FAILURE] root@192.168.65.176 Timed out, Killed by signal 9
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=43.1 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=45.3 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=128 time=42.7 ms
[3] 19:54:26 [FAILURE] root@192.168.65.129 Timed out, Killed by signal 9
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=42.2 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=43.3 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=128 time=42.5 ms
[4] 19:54:26 [FAILURE] root@192.168.65.156 Timed out, Killed by signal 9
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=43.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=42.6 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=128 time=43.1 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=128 time=43.6 ms
[5] 19:54:26 [FAILURE] root@192.168.65.176 Timed out, Killed by signal 9
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=43.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=43.6 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=128 time=42.9 ms
[6] 19:54:26 [FAILURE] root@192.168.65.177 Timed out, Killed by signal 9
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=43.5 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=43.3 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=128 time=42.8 ms

十三、pscp.pssh

pscp.pssh功能是将本地文件批量复制到远程主机

pscp.pssh [-vAr] [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par] [-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] local remote

pscp.pssh以上很多选项和pssh用法是一样的,比如-A -H -h -l等等
-v:显示复制过程
-r:递归复制目录

1、将本地的单个文件复制到远程主机上

[root@rabbitmq1 pssh]# pscp.pssh -h iplist.txt  ./test.txt  /root/pssh
[1] 20:02:44 [SUCCESS] root@192.168.65.156
[2] 20:02:44 [SUCCESS] root@192.168.65.129
[3] 20:02:44 [SUCCESS] root@192.168.65.177
[4] 20:02:44 [SUCCESS] root@192.168.65.175
[5] 20:02:44 [SUCCESS] root@192.168.65.176
[6] 20:02:44 [SUCCESS] root@192.168.65.176

2、将本地多个文件复制到远程主机上

[root@rabbitmq1 pssh]# pscp.pssh -h iplist.txt  ./test.txt  ./ iplist.txt  /root/pssh
[1] 20:09:15 [FAILURE] root@192.168.65.156 Exited with error code 1
[2] 20:09:15 [FAILURE] root@192.168.65.177 Exited with error code 1
[3] 20:09:15 [FAILURE] root@192.168.65.176 Exited with error code 1
[4] 20:09:15 [FAILURE] root@192.168.65.175 Exited with error code 1
[root@rabbitmq1 pssh]# pssh -h iplist.txt -i  'ls -lth  /root/pssh/ '
[1] 20:09:20 [SUCCESS] root@192.168.65.156
总用量 8.0K
-rw-r--r-- 1 root root 80 718 20:09 iplist.txt
-rw-r--r-- 1 root root  4 718 20:09 test.txt
[2] 20:09:21 [SUCCESS] root@192.168.65.177
总用量 8.0K
-rw-r--r-- 1 root root 80 718 20:09 iplist.txt
-rw-r--r-- 1 root root  4 718 20:09 test.txt
[3] 20:09:21 [SUCCESS] root@192.168.65.175
总用量 8.0K
-rw-r--r--. 1 root root 80 718 20:09 iplist.txt
-rw-r--r--. 1 root root  4 718 20:09 test.txt
[4] 20:09:21 [SUCCESS] root@192.168.65.176
总用量 8.0K
-rw-r--r--. 1 root root 80 718 20:09 iplist.txt
-rw-r--r--. 1 root root  4 718 20:09 test.txt

3、将本地目录批量复制到远程主机上

[root@rabbitmq1 pssh]# pscp.pssh -h iplist.txt -r jiaotxt  /root/pssh
[1] 20:10:26 [SUCCESS] root@192.168.65.156
[2] 20:10:26 [SUCCESS] root@192.168.65.177
[3] 20:10:26 [SUCCESS] root@192.168.65.176
[4] 20:10:26 [SUCCESS] root@192.168.65.175

十四、pslurp

pslurp命令的功能是将远程主机的文件批量复制到本地

pslurp [-vAr] [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par][-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] [-L localdir] remote local(本地名)
  说明:这个工具的用法和pscp.pssh的用法很类似,都是对文件的操作,pscp.pssh是往远程主机上推送,pslurp是从远程主机上拉去文件到本地。

-L:指定从远程主机下载到本机的储存的目录,-L 后面必须指定拉去文件存储的目录,repos 是拉去过来的文件的重命名,yum.repos.d 是被拉去的文件
-r:递归复制目录

## 把远程/etc/yum.repos.d 复制到本地/root/repos 下
[root@rabbitmq1 pssh]# pslurp -h iplist.txt  -r -L ./jieguo/  /etc/yum.repos.d  repos
[1] 21:55:22 [SUCCESS] root@192.168.65.156
[2] 21:55:22 [SUCCESS] root@192.168.65.177
[3] 21:55:22 [SUCCESS] root@192.168.65.176
[4] 21:55:22 [SUCCESS] root@192.168.65.175

十五、pnuke

pnuke命令的功能是能在多个主机上并行杀死进程的程序

pnuke  [-vA]  [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par] [-o outdir] [-e errdir] [-t timeout] [-O options] [-x args] [-X arg] pattern

杀死远程主机httpd进程

[root@docker test]#pssh -h iplist -i 'ss -ntl |grep 80'
[1] 01:17:48 [SUCCESS] root@192.168.0.128
LISTEN     0      128                      :::80                      :::*    
[2] 01:17:48 [SUCCESS] root@192.168.0.218
LISTEN     0      128                      :::80                      :::*    
[3] 01:17:48 [SUCCESS] root@192.168.0.217
LISTEN     0      128         :::80                      :::*                 
[root@docker test]#pnuke -h iplist httpd
[1] 01:18:18 [SUCCESS] root@192.168.0.128
[2] 01:18:19 [SUCCESS] root@192.168.0.217
[3] 01:18:19 [SUCCESS] root@192.168.0.218
[root@docker test]#pssh -h iplist -i 'ss -ntl |grep 80'
[1] 01:18:23 [FAILURE] root@192.168.0.128 Exited with error code 1
[2] 01:18:23 [FAILURE] root@192.168.0.218 Exited with error code 1
[3] 01:18:23 [FAILURE] root@192.168.0.217 Exited with error code 1

十六、prsync

prsync命令的功能是将文件并行复制到多个主机

prsync  [-vAraz] [-h hosts_file] [-H [user@]host[:port]] [-l user] [-p par] [-o outdir] [-e errdir] [-t time‐out] [-O options] [-x args] [-X arg] [-S args] local remote

说明:prsync的用法和pscp.pssh的用法类似,它两的区别在于,pscp.pssh不支持创建目录(在远端服务器上若没有指定目录,则创建),而prsync支持。pscp.pssh 支持将本地的不同多个文件同时复制到远程服务端,而prsync 不支持。
1、复制文件到服务器

## 把/etc/passwd 复制到/root/pssh/jieguo/下
[root@rabbitmq1 pssh]# prsync -h iplist.txt /etc/passwd /root/pssh/jieguo/
[1] 22:05:45 [SUCCESS] root@192.168.65.156
[2] 22:05:45 [SUCCESS] root@192.168.65.177
[3] 22:05:45 [SUCCESS] root@192.168.65.175
[4] 22:05:45 [SUCCESS] root@192.168.65.176

注:必须是绝对路径

2、复制目录到服务器

### 把/etc/yum.repos.d  移动到/root/pssh/jieguo/下,如果没有jieguo文件,会自动创建
[root@rabbitmq1 pssh]# prsync -h iplist.txt -r /etc/yum.repos.d /root/pssh/jieguo/
[1] 22:07:34 [SUCCESS] root@192.168.65.156
[2] 22:07:35 [SUCCESS] root@192.168.65.177
[3] 22:07:35 [SUCCESS] root@192.168.65.175
[4] 22:07:35 [SUCCESS] root@192.168.65.176
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值