shell养成计划之易筋经篇(持续更新中)

简介: shell脚本养成计划(持续更新总结容易被忽略的细节……非文本堆砌)

标题:shell脚本养成计划

1、shell篇

1.1、变量

1.1.1、特殊变量

  • !:指定如下解释程序是一个可执行文件,需要指定的的shell去运行它;

  • $?:每一个命令都有自己的返回值,为0表示成功异常,非0则表明执行异常;
  • $0:当前执行脚本的名称,或者也可以看作执行命令的第一个参数(即脚本文件);
  • $1-9:脚本执行时,依次传递的参数1-9;
  • $#:脚本执行时,传递参数的个数;
  • $*:输入参数的具体内容,(将多个参数并作一个单词处理);
  • $@:输入参数的列表对象;
  • $$:当前进程的PID;
  • $!:上一个后台进程的PID

如下所示:测试脚本。执行:bash 1.sh hah heh hihi

#!/bin/bash

systemctl restart docker.service
echo "\$?: $?"
echo "\$0: $0"
echo "\$1: $1, \$2: $2, \$3: $3"
echo "\$#: $#"
echo "\$*: $*"
arr=$@
for "${str}" in ${arr}; do echo "${"${str}"}"; done

测试查看运行的对应结果。

1.1.2、普通变量

  • name=ike,定义普通变量,只在当前shell中有效;

变量的引用方式(上下文同)

  • $key,${key}:可以解决歧义,${#key}:输出变量值的定义长度;
  • '$key',"$key":单引号输出为$key,双引号则为变量值;
[root@VM-218-88-centos ~/]# name=hehe
[root@VM-218-88-centos ~/]# echo "$name"
hehe
[root@VM-218-88-centos ~/]# echo '$name'
$name

1.1.3、环境变量

  • export name=ike;定义系统的环境变量,在当前shell和其他子shell中都可以引用;
  • env,查看当前shell全体的环境变量;
  • unset name,清除指定的环境变量;
  • source xxx.sh,在当前shell中执行脚本,可以引用当前shell所有变量;

1.2、符号处理

1.2.1、排序与或

  • ; :命令的排序执行,无论成功失败与否
  • && :逻辑与,按照命令排序的顺序,成功后进入下一个命令的执行;
  • || :逻辑或,按照命令排序的顺序,失败后进入下一个命令的执行;

如下所示:

[root@VM-218-88-centos /]# go tls_test_0.js ; echo "success"
go tls_test_0.js: unknown command
Run 'go help' for usage.
success
[root@VM-218-88-centos /]# go tls_test_0.js && echo "success"
go tls_test_0.js: unknown command
Run 'go help' for usage.
[root@VM-218-88-centos /]# go tls_test_0.js || echo "success"
go tls_test_0.js: unknown command
Run 'go help' for usage.
success

1.2.2、重定向

  • 覆盖:> :标准输出的结果覆盖目标文件;
  • 追加:>>:标准输出的结果追加到目标文件;
  • 覆盖:2>:错误输出的结果覆盖目标文件;
  • 追加:2>>:错误输出的结果追加到目标文件;
  • 合并:&>:标准和错误信息都直接覆盖目标文件;
  • 合并:&>>:标准和错误信息都直接追加目标文件;
  • <:将目标文件的内容作为执行命令的输入参数
  • <<END:从标准键盘(控制台)中读取数据,换行分隔,直到遇见分界符END才终止(分界符可以是任意自定义字符串)
  • &>/dev/null:清空命令的输出,即不要它,/dev/null,磁盘特殊块,可以看作黑洞,永久为空

特殊使用:command < file > 1.log,将file作为命令的输入参数,然后将执行结果输出到1.log

如下所示:执行一个mongo批量操作数据的脚本,然后操作记录输出到1.log文件中;

docker exec -i mongo mongo < mongo_update.js > 1.log

1.2.3、管道

与重定向不同的是,管道可以将两个甚至多个不同的命令(程序或者进程)连接到一起,将上一个命令的输出作为下一个命令的输入,依次执行,连接方式为|,称为管道符。即:它改变了数据输入输出的方向

下一个命令只能处理上一条命令正确的输出,

1、查找文件中xxxx内容:cat fileName |grep 'xxxx';

2、查找xxxx相关服务列表:systemctl list-units |grep xxxx

3、假如知道日志文件的结构,要筛选它指定分隔列表的带有web内容字段:

[root@VM-218-88-centos /]# cat 20220808.access_12.csv |awk -F , '{print $2}' |grep "web"
"rio3_internal_web"
"rio3_internal_webapi"
"rio3_internal_web"
"rio3_internal_web"
"rio3_internal_webapi"
"rio3_internal_web"
"rio3_internal_webapi"

1.3、条件判断

1.3.1、if

基本语法:

if [command]; then 
    # 符合该条件的执行语句
fi

if [ command ];then
  # 符合该条件执行的语句
elif [ command ];then
  # 符合该条件执行的语句
else
  # 符合该条件执行的语句
fi
  • command可以是条件,也可以是执行命令(中括号两边必须要有空格,强制),如果command为命令执行后,返回的$? = 0,那么往下执行then,否则跳到下一个判断或者跳出if,
  • then和fi是分开的语句,如果要在一行展示,则它俩之间必须要有分号隔开;
  • 条件判断对于变量之间的比对需要加双引号,方便处理;
  • 单独使用><(大于小于)时,会被当成命令的重定向,需要使用&gt,&lt转译代替;
  • 使用-z或者-n来检查长度的时候,没有定义的变量也为0,所以:空变量和没有初始化的变量可能会干扰shell,在不确定变量的内容的时候,可以使用-n或者-z提前判断一下;
  • 条件可以是双圆括号(( )):表示数学表达式,允许在比较中进行简单的算术操作,双圆括号里面的'>','<'号不需要转意;
  • 条件可以是双方括号[[ ]]:表示高级字符串处理函数,使用标准的字符串比较,还可以使用匹配模式,从而定义与字符串相匹配的正则表达式。

常用针对文件的条件判断

  1. [ -a file ]: 如果 file 存在则为真。
  2. [ -d file ]: 如果 file 存在且是一个目录则返回为真。
  3. [ -e file ]: 如果 指定的文件或目录存在时返回为真。
  4. [ -f file ]: 如果 file 存在且是一个普通文件则返回为真。
  5. [ -r file ]: 如果 file 存在且是可读的则返回为真。
  6. [ -w file ]: 如果 file 存在且是可写的则返回为真。(一个目录为了它的内容被访问必然是可执行的)
  7. [ -x file ]: 如果 file 存在且是可执行的则返回为真。

字符串判断

  1. [ -z "${str}" ] :如果str的长度为零则返回为真,即空是真;
  2. [ -n "${str}" ] :如果str的长度非零则返回为真,即非空是真;
  3. [ "${str}" ] :如果字符串不为空则返回为真,与-n类似;
  4. [ "${str1}" == "${str2}" ]: 如果两个字符串相同则返回为真;
  5. [ "${str1}" != "${str2}" ]: 如果字符串不相同则返回为真;

逻辑判断

  1. [ ! expr ] :逻辑非,如果 expr 是false则返回为真。
  2. [ expr1 -a expr2 ] :逻辑与,如果 expr1 and expr2 全真则返回为真。
  3. [ expr1 -o expr2 ] :逻辑或,如果 expr1 或者 expr2 为真则返回为真。
  4. [ ] || [ ] :两个条件取或,用OR来合并两个条件
  5. [ ] && [ ] :两个条件取与,用AND来合并两个条件

1、判断一个目录(文件夹)是否存在,不存在的话创建

#!/bin/bash
if [ ! -d "$1" ];then
  mkdir -pv "$1"
fi

1.3.2、while

都是条件判断执行,while用于循环,基本语法:

while condition
do
    statements
done

condition:与上文的if类似,同理do和done是分开的语句,如果要在一行展示,则它俩之间必须要有分号隔开;

1、如下所示(1~100的累加):

shell中,默认都是字符串操作。(())声明内部为算术表达式,变量引用不需$;let可以指定语句为算术表达式,语句内变量无需$

#!/bin/bash

# (())用法,表明内部为算术表达式,变量引用不需$
i=0
num=0
while ((i <= 100))
do
  ((num+=i))
  ((i+=1))
done
echo "1+2+3+……+100=$num"

# []:变量引用必须加""
i=0
num=0
while [ "$i" -le 100 ]
do
  let num+=i;
  let i+=1
done
echo "1+2+3+……+100=$num"

# [[]]:使用标准的字符串比较,无需给变量引用添加""
i=0
num=0
while [[ $i -le 100 ]]
do
  let num+=i;
  let i+=1
done
echo "1+2+3+……+100=$num"

1.4、时区&时间

1.4.1、date

查看系统时间:date,查看系统时区:date -R;+0800表示东八区

[root@VM-165-128-centos /]# date
2022年 08月 13日 星期六 13:22:14 CST
[root@VM-165-128-centos /]# date -R
Sat, 13 Aug 2022 13:22:18 +0800

修改系统时间:date -s "20220809 11:32"

1.4.2、timedatectl

操作系统的时区命令,

查询系统时区信息;timedatectl 或者 timedatectl status

[root@VM-165-128-centos /]# timedatectl status
      Local time: 六 2022-08-13 13:26:23 CST
  Universal time: 六 2022-08-13 05:26:23 UTC
        RTC time: 六 2022-08-13 05:26:24
       Time zone: Asia/Shanghai (CST, +0800)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

罗列出所有的时区列表;timedatectl list-timezones

# -i:不屈分大小写过滤
[root@VM-165-128-centos /]# timedatectl list-timezones |grep -i shanghai
Asia/Shanghai

设置系统时区:timedatectl set-timezone Asia/Shanghai;(多为保证多台机器时区一致);

设置系统时间:timedatectl set-time "2022-08-13 13:27:33"

  • UTC:整个地球分为24时区,每个时区有本地时间,在国际通信上使用统一时间称为通用协调时:UTC;
  • GMT:格林威治时间,英国皇家天文台标准时区,本初子午线所在地;
  • CST:中国标准时间(china standard time);
  • DST:夏令时,夏天日出较早,将时钟拨快一小时;

UTC + 8 = GMT + 8 = CST;(故:有些日志信息判断故障时间时,需要+8)

1.4.3、time

测量指定命令&脚本的耗时长;

[root@VM-165-128-centos /]# time sleep 10s

real    0m10.001s
user    0m0.001s
sys     0m0.000s
  • real:指定命令&脚本 实际运行耗时;
  • user:用户态代码运行耗时;
  • sys:系统态代码运行耗时;

1.4.4、sleep

将目前命令&脚本,在此暂停一段时间后再执行,即休眠;

[root@VM-165-128-centos /]# date;sleep 20s;date
2022年 08月 13日 星期六 13:46:50 CST
2022年 08月 13日 星期六 13:47:10 CST
  • s 为秒,m 为 分钟,h 为小时,d 为日数

1.5、下载&安装&网络

1.5.1、scp

完整名称:secure copy。在本地服务器上,将指定文件复制到指定机器的指定目录中。(传输过程加密)

  • -P:指定ssh端口;
  • -p:保留源文件的时间,权限相关参数;
  • -4:强制只使用ipv4寻址;-6:强制使用ipv6寻址;
  • -r:递归复制整个目录;
  • -q:隐藏进度条;
  • -v:调试模式显示连接,传输的详细信息;

如下:指定ssh端口3000,显示调试模式信息,递归将ikejcwang/workspace/grpc_test/目录复制到主机9.135.218.88的/root/ikejcwang/目录中。执行过程中会提示输入密码:

^C[root@VM-153-56-centos ~]# scp -P 3000 -v -r ikejcwang/workspace/grpc_test/ root@9.135.218.88:/root/ikejcwang/
Executing: program /usr/bin/ssh host 9.135.218.88, user root, command scp -v -r -t /root/ikejcwang/
OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013
debug1: Reading configuration data /root/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 52: Applying options for *
……………………………………

1.5.2、wget

文件下载的工具命令。通过给定的URL,将远程文件下载到本地的当前目录中,支持http,https,ftp。命令为:wget [options] url。

  • -O:指定其他名称来保存下载的文件,eg:wget -O haha.tar url
  • -o:将下载的日志信息存入指定文件,注意是下载信息,而不是下载的内容;eg:wget -o 1.log url
  • -P:将文件下载到指定目录;eg:wget -P /data/ url
  • --spider:测试链接是否有效;statusCode:200/404;

1.5.1、rpm

软件包管理工具,根据提供的.rpm源代码文件自动编译、安装;

  • -i:--install,安装(指定源文件);
  • -v:--verbose,显示详细信息,
  • -h:--hash,显示进度;eg:安装时显示进度及详细信息,rpm -ivh xxxx.rpm
  • --nodeps:不检测依赖性;
  • -U:upgrade,升级包;
  • -e:erase,卸载指定包;
  • -q:查询是否安装(以下皆须配合-q使用);
  • -a:所有,eg:查询已经安装的所有rpm包:rpm -qa
  • -i:查询软件信息,eg:查询指定包信息:rpm -qi python-javapackages-3.4.1-11.el7.noarch
  • -l:列表,eg:查看包安装位置:rpm -ql trousers-0.3.13-1.el7.x86_64
  • -f:查询系统文件属于哪个rpm包:rpm -qf 系统文件名
  • -R:检测包的依赖性,rpm -qR 包名

注意:涉及依赖性问题的话,需依次解决(安装,正向逐个安装,卸载,反向逐个卸载)

[root@localhost Packages]# rpm -e httpd
错误:依赖检测失败:
        httpd = 2.4.6-67.el7.centos 被 (已安裝) httpd-devel-2.4.6-67.el7.centos.x86_64 需要
[root@localhost Packages]# rpm -e httpd-devel 
[root@localhost Packages]# rpm -e httpd

1.5.2、yum

基于rpm包管理,能够从指定的服务器自动下载rpm包安装,并且自动处理好依赖关系,一次性的安装所有依赖的软件包,无需繁琐的逐个处理:yum [options] [command] [packages……]

[root@VM_0_15_centos ~]# cd /etc/yum.repos.d/
[root@VM_0_15_centos yum.repos.d]# ls
CentOS-Base.repo  CentOS-Epel.repo  docker-ce.repo  mysql-community.repo  mysql-community-source.repo  yarn.repo

如果系统能够联网,使用默认的网络源文件CentOS-Base.repo,

image-20220807225752803

  • gpgcheck:1指RPM的数字证书生效,写成0就是不生效;
  • gpgkey:数字证书的公钥文件保存位置。
  • enable:此容器是否生效(1),默认生效;
  • baseurl:yum源服务器的地址。
  • name:说明

配置文件见/etc/yum.conf,各项操作命令如下:

  • yum list:列出所有可安装的列表;
  • yum check-update:列出所有可更新的软件列表;
  • yum update :更新所有软件;
  • yum install -y :安装指定软件,-y:自动yes,下同;
  • yum update -y :更新指定软件
  • yum remove -y :卸载
  • yum search 关键词:查找
  • yum clean packages:清除缓存目录下的软件包
  • yum clean headers:清除缓存目录下的 headers
  • yum clean oldheaders: 清除缓存目录下旧的 headers
  • yum clean:yum clean all,皆等于:yum clean packages && yum clean oldheaders

软件组:

  • yum grouplist:列出所有可用的软件组列表
  • yum groupinstall :安装指定软件组
  • 卸载,更新……类似

1.5.3、dig

域名查询工具,从DNS服务器查询主机IP地址,该命令属于Bind的一部分,并没有在Linux即成,需要:yum install bind-utils

dig www.wangjc.vip,默认依次使用/etc/resolv.conf文件配置的地址作为DNS服务器,若/etc/resolv.conf没有配置,则使用网卡配置的DNS服务器;(注:它不会去解析本地hosts文件);

dig @10.123.119.98 www.baidu.com:指定dns服务器进行查询;

1.5.4、host

同在bind-utils下面,还有一个host命令,也是做域名解析,只不过用起来比较简单(注:也不会去解析本地hosts)

hosts www.baidu.com

  • -v:显示查询的详情信息

1.6、系统相关

1.6.1、cpu信息

lscpu

查看cpu相关信息,厂商,型号,频率,核数……原理是从sysfs和/proc/cpuinfo收集cpu体系结构信息

cat /proc/cpuinfo

也可以使用这样查看,然后定向过滤字段即可;

1.6.2、磁盘空间

df

查看Linux文件系统磁盘的使用情况

# 或者使用df -Bg,
[root@VM-165-128-centos /]# df -h
文件系统        容量  已用  可用 已用% 挂载点
devtmpfs        7.7G     0  7.7G    0% /dev
tmpfs           7.7G     0  7.7G    0% /dev/shm
tmpfs           7.7G  2.2M  7.7G    1% /run
tmpfs           7.7G     0  7.7G    0% /sys/fs/cgroup
/dev/vda1        99G   23G   73G   24% /
tmpfs           1.6G     0  1.6G    0% /run/user/0
/dev/vdb1       197G  4.0G  183G    3% /data
overlay          99G   23G   73G   24% /var/lib/docker/overlay2/***/merged
overlay          99G   23G   73G   24% /var/lib/docker/overlay2/***/merged
overlay          99G   23G   73G   24% /var/lib/docker/overlay2/***/merged
overlay          99G   23G   73G   24% /var/lib/docker/overlay2/***/merged
  • -h:单位换算成G,方便阅读模式;
  • -B:指定单位,M,G……
  • -a:显示全部文件系统;
  • -i:显示本地文件系统;

du

查看文件/文件夹的磁盘空间占用情况(可以精细化到文件);

[root@VM-218-88-centos ~/ikejcwang]# du -sh soft/ workspace/
3.9G    soft/
22G     workspace/
[root@VM-218-88-centos ~/ikejcwang]# du -h -d1
8.0G    ./rio_work
3.9G    ./soft
498M    ./redis_cluster
11M     ./ssh_cert
14G     ./rio_install
22G     ./workspace
48G     .
  • -s:统计指定文件&文件夹的占用大小,统计总量;
  • -h:自动单位换算,方便阅读性;
  • -a:依次递归显示指定目录下,每个文件的占用大小;
  • -c:除了依次递归显示指定目录下的文件&文件夹,还计算总量;
  • -d:依次显示指定目录下,指定层级的占用大小,也可以改为2层,3层;eg:du -hd1 / ;统计根目录下每个文件&文件夹大小;

1.7、文件操作

1.7.1、cat 和 tac

tac是cat的反过来,所以其功能与cat类似却是相反,eg:tac文件是倒过来的从下往上,用法不常见;

cat :连接文件,或者标准输入并打印好,主要有三大功能:

  1. 一次显示整个文件的内容:cat fileName;
  2. 创建一个新文件,并从键盘完成输入:cat > fileName;
  3. 将多个文件内容合并为一个文件,或者连接起来查看:cat file1 file2 > newfile

参数用法:

  • -n:--number,对输出的所有行进行编号,从1开始;
  • -s:--squeeze-blank,有连续两行以上的空台,就替换为一行;
  • -b:--number-nonblank,对空行输出编号,从1开始;
  • -E:--show-ends,在每行结束处显示$;

1、创建一个sh文件,并嵌入内容(注意,嵌入的$需要转译处理):

[root@VM-218-88-centos /]# cat > test.sh <<END
> #!/bin/bash
> p=\$1
> echo \${p}
> END
[root@VM-218-88-centos /]#

2、对文件内容加上行号然后

[root@VM-218-88-centos /]# cat -n test.sh > test_new.sh
[root@VM-218-88-centos /]# cat test_new.sh 
     1  #!/bin/bash
     2  p=$1
     3  echo ${p}

3、去掉行号复原($被识别到了,还是不要对.sh文件这么用,此处只是测试)

[root@VM-218-88-centos /]# cat test_new.sh | awk '{print $2}' > test_new2.sh 
[root@VM-218-88-centos /]# cat test_new2.sh 
#!/bin/bash
p=$1
echo

1.7.2、stat

详细的显示文件的状态信息,可以看出文件大小,权限,最近查看,变更时间……

[root@VM-218-88-centos /]# stat httpTest.js 
  文件:"httpTest.js"
  大小:499             块:8          IO 块:4096   普通文件
设备:fc01h/64513d      Inode:2359301     硬链接:1
权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
最近访问:2022-06-29 15:06:40.781116820 +0800
最近更改:2022-06-29 15:06:40.781116820 +0800
最近改动:2022-06-29 15:06:40.789116812 +0800
创建时间:-

1.7.3、cp

文件复制,复制目录时,必须添加-r,或者-R参数;

覆盖替换复制,除了使用mv之外,还可以cp -rf

1.7.4、file

查看文件/文件夹的类型;file fileName

1.7.5、basename

给basename一个指定的路径,basename会删掉所有的前缀,包括路径最后一个/,然后将后缀字符串显示出来,且可选择是否去掉文件后缀;

如下所示:

[root@VM-165-128-centos ~/]# basename /root/ikejcwang/dist.tar .tar
dist
[root@VM-165-128-centos ~/]# basename /root/ikejcwang/dist.tar 
dist.tar
[root@VM-165-128-centos ~/]# basename /root/ikejcwang/
ikejcwang

1.8、文本处理利器

1.8.1、awk

优秀的智能文本处理工具:打印文件中的某一列,它会智能的去切分数据,不管是tab,还是空格……或者指定分隔符;

  • -F:指定分隔符,eg:指定分隔符为,:-F ","
  • -v:指定变量和默认值;
  • $NF:代表最后一个字段;
  • NR:代表第几行;
  • FS:输入分隔符(即-F的意思);
  • OFS:输出字段分隔符;
  • RS:输入记录分隔符;
  • $0:显示整行;
  • 1…N:第一个字段到第N个字段;

eg:查找用户名列表:

[root@VM-218-88-centos /]# cat /etc/passwd |awk -F ":" '{print $1}'
root
bin
daemon

指定行号,采用变量自增,打印最后一列($NF)

[root@VM-218-88-centos /]# cat /etc/passwd |awk -F ":" -v "i=0" '{i++;print i,$NF}'
1 /bin/bash
2 /sbin/nologin
3 /sbin/nologin
4 /sbin/nologin

根据上文,打印第33行的最后一列(NR==33):

[root@VM-218-88-centos /]# cat /etc/passwd |awk -F ":" 'NR==33{print $NF}'
/sbin/nologin

输出字段的分隔符(OFS="--";),一般与-F(或者FS)配合使用,重新定义内容的分隔:

[root@VM-218-88-centos /]# cat /etc/passwd |awk -F ":" -v "i=0" '{OFS="--";i++;print i,$NF,$1}'
1--/bin/bash--root
2--/sbin/nologin--bin
3--/sbin/nologin--daemon
4--/sbin/nologin--adm

优先级判定

  • BEGIN:最高优先级,最先执行,位于PROGRAM之前,不依赖数据源;
  • PROGRAM:默认,对数据流操作的,必选(默认)代码块;
  • END:处理数据流之后,如果需要END,就必须事先有PROGRAM的支持
注意:如果只用BEGIN或者END,然后跟上数据源是没有效果的,数据源只对PROGRAM生效

如下所示:

# BEGIN后面不需要加任何数据源,也可以打印内容
[root@VM-218-88-centos /]# awk -v "name=ike" 'BEGIN{print name}'
ike
[root@VM-218-88-centos /]# awk -v "name=ike" -v "age=27" 'BEGIN{OFS="--";print name,age}'
ike--27

其余的小技巧;

  • 打印一个文件的行数:awk 'END{print NR}' /etc/passwd
  • 打印最后一行:awk 'END{print $0}' /etc/passwd
  • 打印按指定分隔符分隔的列数:awk -F ":" 'END{print NF}' /etc/passwd

1.8.2、grep

全局搜索的一个正则表达式,并且输出到屏幕上,在文件中对指定的关键词进行查找,并且高亮显示所在行的位置;

参数列表:

  • -i:忽略大小写;
  • -v:取反匹配,即筛选出不满足的行;
  • -n:输出时显示行号;
  • -r:递归查找,一般针对整个文件夹下的内容进行检索时,对应还有个命令rgrep;

还可以配合正则表达式使用-E

[root@VM-218-88-centos /]# grep -E "(/?)wang" /etc/passwd
ikejcwang:x:1001:0::/home/ikejcwang:/bin/bash
wang:x:1002:1000::/home/wang:/bin/bash
[root@VM-218-88-centos /]# grep -E "^wang" /etc/passwd
wang:x:1002:1000::/home/wang:/bin/bash

1.8.3、sed

作为快速文本的处理利器,应用简单实用广泛;工作流程:读取->执行->显示;

命令格式为:set [options] '编辑命令' file1 file2…

  • -e:使用指定的命令&脚本来处理输入的文本文件;
  • -f:使用指定的脚本文件来处理输入的文本文件;
  • -n:表示仅显示处理后的结果;
  • -i:直接编辑文本文件;
  • -r,-E:使用扩展正则表达式;
  • -s:将多个文件视为独立文件,而不是单个的长文件流;

常见的操作动作如下:

  • a:增加,在当前行下面增加一行指定内容;
  • c:替换,将选定行替换为指定内容
  • d:删除,删除选定的行;
  • i:插入,在选定行上面插入一行指定内容;
  • p:打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印出所有内容;如果有非打印字符,则以ASCII码输出。其通常与"-n"选项一起使用;
  • s:替换,替换指定字符;
  • y:字符转换。
# 创建一个文件,并输入内容
[root@VM-218-88-centos /]# cat <<end >text.txt
> haha,1
> hehe,2
> hihi,3
> huhu,4
> end
# -n(显示执行结果),p:全量打印文件内容
[root@VM-218-88-centos /]# sed -n 'p' text.txt 
haha,1
hehe,2
hihi,3
huhu,4
# 只显示第二行
[root@VM-218-88-centos /]# sed -n '2p' text.txt 
hehe,2
# 显示第二道第四行的内容
[root@VM-218-88-centos /]# sed -n '2,4p' text.txt 
hehe,2
hihi,3
huhu,4
# 第二个n,表示显示下一行的内容,(输出偶数行)
[root@VM-218-88-centos /]# sed -n 'n;p' text.txt 
hehe,2
huhu,4
# 输出1-4行之间的奇数行
[root@VM-218-88-centos /]# sed -n '1,4{p;n}' text.txt 
haha,1
hihi,3

删除的用法,注意:只是删除输出文本,并未删除源文本内容

sed:-e 表达式 #1,字符 3:命令后含有多余的字符
[root@VM-218-88-centos ~/ikejcwang]# sed -n "1d;p" text.txt 
hehe,2
hihi,3
huhu,4
[root@VM-218-88-centos ~/ikejcwang]# sed -n "1,3d;p" text.txt 
huhu,4

替换,/g全量,/gi全量且忽略大小写,替换的特殊字符,需要转译(同样支持针对特定行内容替换)

[root@VM-218-88-centos ~/ikejcwang]# sed -n "s/h/ike/;p" text.txt 
ikeaha,1
ikeehe,2
ikeihi,3
ikeuhu,4
[root@VM-218-88-centos ~/ikejcwang]# sed -n "s/h/ike/g;p" text.txt 
ikeaikea,1
ikeeikee,2
ikeiikei,3
ikeuikeu,4

set -i,编辑文本文件,(无需p输出打印了);

sed -i 's/https:\/\/真实的域名/http:\/\/9.133.222.55/g' host-template
sed -i 's/真实的域名/9.135.218.88/g' host-template
sed -i 's/真实的签名/KpRklaXpaoTeVTm/g' host-template

1.8.4、vim

强大的文本编辑器(值得总结的太多太多),系统没有的话安装:yum -y install vim*

此处记录的多是常用且复杂的操作:

  • 多行注释:在ESC模式下,按Ctrl+V,滑动选择多行,再按Shift+i进入插入模式,输入注释符号,完成后ESC,加鼠标点一下
  • 多行取消注释:在ESC模式下,按Ctrl+V,滑动选择多行,再按d即可完成去注释;
  • 替换模式:正常模式,按r,然后输入替换字符。(替换一堆,先按v,进入可视模式选中,然后按r,输入替换字符);
  • 清空文件:ggdG,(gg:到文件头部,G:到文件尾部);
  • :set spell / nospell:开启/关闭拼写检查功能;

插入模式:

  • gI:在当前行的头部插入;
  • A:在当前行的尾部插入;
  • a:在光标后插入;
  • O:在上面新建一行插入;
  • o:在下面新疆一行插入;
  • :r filename:在当前位置插入指定文件内容;
  • :[n]r filename:在指定行位置插入指定文件内容;

复制粘贴删除:

  • y:复制可视模式下选中的文本;
  • yy 或 Y:复制当前行;
  • y$,y0:从光标当前位置复制到文件尾部,从光标当前位置复制到文件头部;
  • d:删除(剪切)可视模式下选中的文本,没选中就是光标处文本;
  • dd :删除(剪切)1行(当前行);
  • d$ 或 D:删除(剪切)当前位置到行尾的内容;
  • p:在光标之后粘贴;
  • P:在光标之前粘贴;

替换:

  • :s/old/new/,替换当前行的第一个,加/g替换当前行的全部

撤回与反撤回:

  • u:撤回,一直到初始打开状态;
  • ctrl+r:反向撤回,一直到最新编辑状态;

1.8.5、wc

word count的缩写,用于文本内容的统计。单词条目,行数,字符数,字节数……

wc test.txt:执行后显示,第一个是行数,第二个单词数(空格分隔),第三个是字节数。

  • -l:只统计行数;
  • -w:只统计单词数;
  • -c:只统计字节数;
  • -m:只统计字符数;

1.8.6、base64

base64:加密,

base64 -d:解密

base64 file.txt
cat file.txt | base64

1.8.7、md5sum

计算指定文本,文件的md5值,可用来对比文件内容是否不一致;

# 判断压缩包的md5值,与真实版本是否一致
[root@VM-165-128-centos /]# time md5sum nstall-v1.2.2.zip
9966218540ef813f1673b5913f984c1c  install-v1.2.2.zip

real    0m1.829s
user    0m1.672s
sys     0m0.156s

time计算命令执行的耗时。

1.8.8、jq

json文本格式处理的神器。curl url | jq

wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
chmod +x ./jq
cp jq /usr/bin

1.9、进程&任务

1.9.1、w

查看当前系统正在登录的用户有哪些(开启的ssh连接数量),以及它们各自的休眠时长,行为动作

[root@VM-218-88-centos ~/ikejcwang]# w
 17:53:20 up 6 days, 17:29,  4 users,  load average: 0.06, 0.08, 0.08
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    10.91.79.167     10:15   41:55   0.11s  0.00s -bash
root     pts/1    10.91.79.167     10:15    0.00s  0.02s  0.02s -bash
root     pts/2    10.91.79.167     10:16    6.00s  0.01s  0.01s -bash
root     pts/3    10.91.79.167     10:16    6:49m  0.00s  0.00s -bash
  • 17:53:20:当前时间;
  • up 6 days,17:29:系统的正常运行时间(距离上一次重启);
  • 4 users:目前有4个user/from在线上;
  • load average: 0.06, 0.08, 0.08:系统的平均负载值(统计3个时间段),1分钟为0.06,5分钟为0.08, 15分钟为0.08;
  • USER:登录的用户名;
  • TTY:终端名称;
  • FROM:开启ssh访问的客户端IP地址;
  • LOGIN@:当前会话登录的开始时间;
  • IDLE:会话多久没用活跃(s秒,m分钟……);
  • JCPU:当前会话所有进程使用的CPU时间,进程结束停止计时;开启新的进程重新计时;
  • PCPU:当前会话的CPU执行当前程序花的时间;当前程序即为当前会话的WHAT值。

1.9.2、top

动态的显示系统当前资源的利用率和进程运行实况

top,常用参数如下:

  • -p:指定进程号来监控,eg:top -p 6328
  • -i:过滤掉任何闲置或者僵尸进程,eg:top -i
  • -c:显示进程完整的命令;eg:top -c
  • -d:设置动态刷新的时间间隔,eg:每秒刷一次:top -d 1,(默认3秒)
  • top -p 320 -p 330 -d 5 -c:间隔5秒,完整命令显示进程号330和320的实时运行情况;

image-20220811200927949

先说交互命令(简单介绍):

  • 1:切换显示每个cpu的状态;
  • E:切换内存显示的单位:K,M,G,T,P;
  • M:根据内存占用的大小来进行排序降序;
  • P:根据CPU使用的百分比大小进行排序;

然后各项参数配置:

  1. 第一行(系统参数):top:当前时间;up:机器运行时间(距上次重启);user:当前ssh会话数;系统负载平均值(1,5,15)分钟
  2. 第二行(当前task分类):total:当前有进程数;running:正在运行进程;sleeping:正在休眠进程;stopped:停止进程数;zombie:僵尸进程数;
  3. 第三行(CPU信息,按1展示所有cpu信息)

    us:用户空间占用cpu的百分比(各种脚本,应用,webserver……都算作运行在用户空间的进程);

    sy:内核空间占用cpu的百分比(所有进程使用系统资源时都有Linux内核处理,当大量IO操作,或者IO阻塞时,sy会增大);

    ni:用户进程空间改变过优先级;

    id:空闲cpu的百分比;

    wa:等待输入输出占用cpu百分比,通过wa可以判断系统瓶颈是否在IO上面;

    hi:硬中断占用百分比;si:软中断占用百分比;

    st:超分(超卖)的判断指标。如果远大于0(1、需要额定更多CPU资源的虚拟机;2、物理机超卖,多个虚拟机之间在疯狂竞争资源)

  4. 第四行(物理内存信息,按E切换换算单位)

    total:物理内存总量;

    free:目前空闲内存量;

    used:目前已使用的内存量;

    buffer/cache:目前用作内核缓存的内存量;

  5. 第五行(交换区内存信息,按E切换换算单位)

    total:交换区内存总量;

    free:空闲交换区内存量;

    used:目前使用的交换区内存量;

    buffer/cache:缓冲的交换区内存量;

    第4,5行分别是物理内存与swap交互区的信息,所有程序都运行在内存中,但是当内存的free变少时不用大惊小怪,有使用就会有释放,并不一定代表物理内存不够用了,而swap才是衡量的重要条件,swap是由硬盘提供支撑的,当物理内存不够使用时,操作系统才会把数据临时放到swap中,当swap的used上升严重,则说明物理内存资源枯竭。

  6. 第六行(进程信息,按i过滤调所有闲置 或者僵尸进程)

    PID:进程ID;

    USED:启动该进程的操作用户;

    PR:优先级;

    NI:nice值,值越小,优先级越高;

    VIRT:进程使用的虚拟内存总量,(按E切换换算单位,同下)VIRT=SWAP+RES;

    RES:进程使用的未被换出的物理内存。RES=CODE+DATA;

    SHR:共享内存大小;

    S:进程状态。D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程;

    %CPU:实时更新,上个更新到现在的CPU时间占用百分比;

    %MEM:进程使用的物理内存百分比;

    TIME+:进程使用的CPU时间总计,单位1/100秒;

    COMMAND:命令名/命令行

1.9.3、kill

终止进程的运行,kill [参数] PID

  • -l:不加参数会列出信号全部名称,加参数会显示信号编号,eg:kill -l kill,输出9;

杀死指定进程:kill -9 PID

高级命令:killall node,杀死所有的同名进程;

1.9.4、nohub

运行指定进程不受终端关闭&挂断的影响,可以配合&关键词使用(&:表示将该任务放到后台执行)

nohub node httpServer.js &

1.9.5、ps

静态的列出系统当前运行的进程列表;

  • -aux:显示所有用户的进程(unix形式);
  • -ef:显示所有用户的进程(Linux形式);
  • -u:列出当前用户的进程;
  • -aux --sort -pcpu:按cpu使用率降序显示;
  • -aux --sort -pmem:按内存使用率降序显示;

1.9.6、systemd

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 8月05 ?       00:01:57 /usr/lib/systemd/systemd --switched-root --system --deserialize 22

系统基础服务组件的集合,PID为1,负责启动其他程序(服务),可在/etc/systemd/system/查看并新建&编辑服务,然后systemctl daemon-reload,然后启动&重启指定服务;

命令格式:systemctl [command] [serviceName]

  • reload:重新加载服务配置文件;
  • enable:设置服务开机自启;
  • disable:设置服务开机不自启;
  • Is-enabled:查看服务是否开机自启;
  • systemctl list-units:列出正在运行的units,eg:systemctl list-units |grep wukong (筛选所有wukong服务)
  • systemctl -a:列出所有服务,eg:systemctl -a | grep wukong |grep dead(查看死掉的wukong服务)

1.9.7、lsof

多用来查看端口情况,也可以查看当前端口连接数,进程连接;

lsof -i:portlsof -i tcp:port losf -p pid

[root@VM-165-128-centos ~]# lsof -i:80
COMMAND   PID USER   FD   TYPE     DEVICE SIZE/OFF NODE NAME
node    20642 root   22u  IPv4 2880945779      0t0  TCP *:http (LISTEN)
node    20661 root   20u  IPv4 2949532751      0t0  TCP VM-165-128-centos:http->10.99.17.135:24667 (ESTABLISHED)

1.9.8、netstat

一个监控 TCP / IP 网络的非常有用的工具,它可以显示实际的网络连接以及每一个网络接口设备的状态信息;

查看机器的tcp连接数;

[root@VM-218-88-centos /]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
ESTABLISHED 299
FIN_WAIT2 1
TIME_WAIT 113

查看tcp端口是否被监听:

[root@VM-218-88-centos /]# netstat -tunlp|grep 808
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      12463/node          
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN      10742/node          
tcp        0      0 0.0.0.0:8082            0.0.0.0:*               LISTEN      10742/node          
tcp        0      0 127.0.0.1:8088          0.0.0.0:*               LISTEN      16368/webapi

查看端口,协议,PID相关信息:

netstat -a    # 显示所有端口
netstat -at # 显示所有tcp端口
netstat -au # 显示所有udp端口
netstat -s  # 显示协议(所有端口)的统计信息
netstat -st # 显示tcp协议(所有端口)的统计信息
netstat -su # 显示udp协议(所有端口)的统计信息
  • -a:列出所有连线的socket;
  • -c:持续动态列出当前网络状态;
  • -e:显示网络其他相关信息;
  • -l:列出所有listen的socket;
  • -p:显示正在运行的程序名称和识别信息;
  • -n:直接使用的是IP地址;
  • -o:显示计时器;
  • -r:显示路由列表;
  • -t:显示tcp协议的连线列表;
  • -u:显示udp协议的连线列表;

1.10、归档与压缩

1.10.1、tar

压缩打包工具,正常流程是:先使用tar 将多个文件归档为一个总文件(archive),然后再用gzip将archive压缩成更小的文件,但是日常很多操作都是一步到位;

  • -xvf:(x解开,x细节展示,f文件)解压缩,-C:解压缩到指定目录;
  • -tf:显示归档文件的内容,不解开;
  • -cvf:(c创建,x细节展示,f文件)打包,
  • -z:归档+压缩;解压gz格式的压缩文件(省略了gzip,gunzip,一步到位)

tar -cvf file.tar file/:将file文件夹打包归档成file.tar,并展示归档细节

tar -xvf file.tar -C file_new:将file.tar解压缩至file_new目录中;

如果压缩包本身就为gz格式

tar -zcvf file.tar.gz file/:将file文件夹打包归档成file.tar.gz,并展示归档细节

tar -zxvf file.tar.gz -C file_new:将file.tar.gz解压缩至file_new目录中;

(日常多为-z使用,但并没有标注压缩文件后缀.gz,可以使用file命令查看)

少见的.tar.xz格式:

tar -Jcvf name.tar.xz ./:压缩,tar -Jxvf name.tar.xz :解压

1.10.2、zip/unzip

  • -r:压缩目录(必选),采用递归方式;
  • -q:不显示执行过程;
  • -d:解压到指定目录;
  • -o:覆盖解压

zip -r mydata.zip mydata/unzip -q -o mydata.zip -d mydata_new

2、工具篇

2.1、压测工具

2.1.1、wrk

需要先下载源码包编译,然后使用。(可以选择cp到/usr/bin下面)

git clone https://github.com/wg/wrk
cd wrk
make    # 需要事先安装gcc依赖

压测说明:

./wrk -t100 -c10 -d20s url
  • -c:跟服务器建立并保持的tcp连接数量;
  • -d:压测时间;
  • -t:使用多少个线程进行压测,即并发值;
  • -s:指定lua脚本路径;
  • -H:为每一个HTTP请求添加头;
  • -v:显示当前wrk详细信息

结果说明:

  • Non -2xx or -3xx response:表示报错请求数量;
  • 压测的qps计算:(完成请求数 - 报错请求数) / -d
相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
目录
相关文章
|
25天前
|
弹性计算 Shell Perl
ecs服务器shell常用脚本练习(二)
【4月更文挑战第1天】shell代码训练(二)
106 1
|
28天前
|
Java Shell
SpringBoot启动脚本Shell
SpringBoot启动脚本Shell
18 0
|
5天前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
33 3
|
2天前
|
监控 Shell 应用服务中间件
第十二章 Shell脚本编写及常见面试题(二)
第十二章 Shell脚本编写及常见面试题(二)
|
2天前
|
监控 关系型数据库 Shell
第十二章 Shell脚本编写及常见面试题(一)
第十二章 Shell脚本编写及常见面试题(一)
|
2天前
|
监控 Shell
生产环境Shell脚本Ping监控主机是否存活(多种方法)
生产环境Shell脚本Ping监控主机是否存活(多种方法)
|
2天前
|
运维 Shell
Shell脚本判断IP是否合法性(多种方法)
Shell脚本判断IP是否合法性(多种方法)
|
8天前
|
运维 监控 Shell
利用Shell脚本编写局域网监控软件:实时监测主机连接情况
本文介绍了如何使用Shell脚本创建一个局域网监控工具,以实时检查主机连接状态。脚本包括扫描IP地址范围检测主机可达性及使用`netstat`监控ESTABLISHED连接。此外,还展示了如何每60秒将连接数数据自动提交到指定网站API,以便实时跟踪网络活动。这个自动化监控系统有助于提升网络安全性和故障排查效率。
32 0