1. vim文本编辑器

三个模式:编辑模式、尾行模式、命令模式

切换方式:ESCi (insert)、a (从光标后一个位置开始)、o (从下一行开始)

表 1 Vim 中常用的命令
命令 作用
dd 删除(剪切)光标所在整行
5dd 删除(剪切)从光标处开始的 5 行
yy 复制光标所在整行
5yy 复制从光标处开始的 5 行
n 显示搜索命令定位到的下一个字符串
N 显示搜索命令定位到的上一个字符串
u 撤销上一步的操作
p 将之前删除( dd)或复制( yy)过的数据粘贴到光标后面

注意:

  • :wq 强制性写入文件并退出。即使文件没有被修改也强制写入,并更新文件的修改时间。
  • :x 写入文件并退出。仅当文件被修改时才写入,并更新文件修改时间,否则不会更新文件修改时间,这可以避免对未修改的文件因时间戳?变化而重新编译。
表 2 末行模式中可用的命令
命令 作用
:w 保存
:q 退出
:q! 强制退出(放弃对文档的修改内容)
:wq! 强制保存退出
:set nu 显示行号
:set nonu 不显示行号
:命令 执行该命令
:整数 跳转到该行
:s/one/two 将当前光标所在行的第一个 one 替换成 two
:s/one/two/g 将当前光标所在行的所有 one 替换成 two
:%s/one/two/g 将全文中的所有 one 替换成 two
?字符串 在文本中从下至上搜索该字符串
/字符串 在文本中从上至下搜索该字符串

2. 编辑配置文件举例

  • 修改主机名hostname

    • 传统方法 vim /etc/hostname
  • CentOS8 hostnamectl set-hostname TestNode --static

  • 配置网卡信息

    vim /etc/sysconfig/network-scripts

    关键配置:

    1
    2
    3
    4
    5
    BOOTPROTO=static
    ONBOOT=yes
    IPADDR=192.168.1.100
    NETMASK=255.255.255.0
    GATEWAY=192.168.1.1

    重启网卡

    systemctl restart network

  • 配置yum源(后面单独出个blog

    cd /etc/yum.repo.d/,在这里添加仓库配置文件*.repo。一般有两种,本地盘或者在线源:

    1. 挂载镜像iso,配置本地源
    2. 配置网络源,如清华云、华为云、阿里云

    配置完成后,就可以直接通过yum install安装软件

3. shell脚本编写

3.1 内置的参数变量

特殊变量 含义
$0 当前脚本名
$1 第一个参数,依次类推$2,$3,…第2个,第3个
$# 传递给脚本或函数的参数的个数
$* 传递给脚本或函数的所有参数
$@ 传递给脚本或函数的所有参数,同上
$? 上个命令的退出状态或执行的返回值
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID

$*和$@的区别:

​ 当参数是用" "括起来的时候,$*会将所有的参数最为一个字符串整体;$@会将各个参数分开,每个参数是一个子字符串。

3.2 参数判断

格式[ 条件判断 ]

注意:括号两边各空1格,条件成立返回数字0!

按照判断类型来划分,条件判断语句可以分为4类:

  • 文件判断:是否存在、文件类型、读写权限等
  • 逻辑判断:判断是否成立
  • 数值判断:整数大小比较
  • 字符比较:字符串内容是否相同,或者是否为空
  1. 文件测试判断

    运算符 描述
    -e 文件是否存在
    -d / -f 是否为目录;是否为一般文件
    -r / -w / -x 是否有读、写、执行权限
  2. 与、或、非

    1
    2
    3
    4
    # 举例
    [ -d /etc/fstab ]
    echo $?
    1 # 不是目录,而是文件,条件不成立,返回1

    常利用与、或语句的短路作用:

    1
    2
    3
    4
    5
    6
    7
    [root@local ~]# [ $USER = root ] || echo "Not root" && echo "root"
    root
    [root@local ~]# [ ! $USER = root ] && echo "Not root" || echo "root"
    root

    # 实际应用举例
    [ -e result.log ] && echo "File Exist" || echo "File not found"
  3. 整数比较

    注意,以下运算符只能用于整数判断,不能与字符串、文件等混在一起操作

    运算符 作用
    -eq / -ne 等于 / 不等于
    -gt / -lt 大于 / 小于
    -ge / -le 小于或等于 / 大于或等于
  4. 字符串判断

    运算符 作用
    = 字符串是否相同 [ $(uname -m) = “aarch64” ] && echo “ARM arch”
    != 字符串是否不同 [ $(uname -m) != “aarch64” ] && echo “x86 arch”
    -z 判断字符串是否为空,常用与判断是否有参数输入

3.3 流程控制语句

常见的流程结构,包含2大类,即分支结构和循环结构

  • if 分支:关键字 ifthenelifelsefi
  • case 分支:关键字caseinesac
  • for 循环:关键字forindodone
  • while 循环:关键字whiledodone

1. if分支

1
2
3
4
5
6
7
if [ $(uname -m) = 'x86_64' ] ; then
echo "Arch: x86"
elif [ $(uname -m) = 'aarch64' ] ; then
echo "Arch: arm"
else
echo "Not support!"
fi

2. case分支

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
read -p "请输入一个字符, 按Enter键确认:" CHAR
case "$CHAR" in
[a-z]|[A-Z])
echo "字母"
;;
[0-9])
echo "数字"
;;
*)
echo "特殊字符"
esac

3. for循环

1
2
3
for LINE in $(cat result.log) ; do
echo $LINE
done

4. while循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
echo "猜数字游戏"
NUMBER=$(expr $RANDOM % 100)
TIMES=0
while true ; do
read -p "请输入一个(0-99)数字, 按Enter键确认:" INT
let TIMES++
if [ $NUMBER = $INT ] ; then
echo "$TIMES次就猜对了"
exit 0
elif [ $INT -gt $NUMBER ] ; then
echo "太大了"
else
echo "太小了"
fi
done

4. 实例

4.1 测试各个主机是否连通

  • IP列表:cat ip.txt
1
2
3
4
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
  • 检测列表IP
1
2
3
4
5
6
7
8
9
#!/bin/bash
for IP in $(cat ip.txt) ; do
ping -c 3 -i 0.5 -W 3 $IP &> /dev/null
if [ $? -eq 0 ] ; then
echo "$IP is Online."
else
echo "$IP is Offline"
fi
done

4.2 数组遍历

  • 只有一维数组
  • 下标从0开始
  • 元素用空格分隔开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash

# 定义和修改值
array=( a b 1 22 hello "hi, good" )
array[3]=33

# 1.按照index读取
echo ${array[0]}
echo ${array[1]}
echo ${array[2]}
echo ${array[3]}
echo ${array[4]}
echo ${array[5]}

# 2. 打印所有元素
echo ${array[@]}
echo ${array[*]}

# 3. for循环遍历
for((i=0;i<${#array[@]};i++)); do
echo ${array[$i]}
done

# 4. for in 遍历
for element in ${array[@]}; do # 如果字符串中有空格,会自动拆成多个元素
echo $element
done

# 5. for in 带数组下标
echo "all: ${array[@]}"
echo "index: ${!array[@]}"
for i in "${!array[@]}"; do
printf "%s\t%s\n" "$i" "${array[$i]}"
done

# 6. while循环遍历
i=0
while [ $i -lt ${#array[@]} ]; do
echo ${array[$i]}
let i++
done

部分结果打印:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
a
b
1
33
hello
hi, good

a
b
1
33
hello
hi,
good

all: a b 1 33 hello hi, good
index: 0 1 2 3 4 5
0 a
1 b
2 1
3 33
4 hello
5 hi, good