跳转至

Linux 大法


牢记

  • Linux 下一切皆是文件,一切从 / 开始
  • 不需要的权限一律不给,不用的端口一律不开;权利越大责任越大
  • 别以为你的安全策略能有系统自带的防火墙SELinux 好,所以不要随便关闭防火墙SELinux
  • 修改默认端口:FTP(21)、SSH(22)、Telnet(23) 等服务默认端口,其中 Telnet 不建议长期开启

发行版

  • Linux 其实是内核,但现下环境下,我们所说的 Linux 一般都是 GNU/Linux。
  • 目前 Linux 发行版有两大阵营,即 CentOS/RedHat 系 和 Debian/Ubuntu 系,两者间最明显的区别就是软件包管理方式上的不同。
  • 常见的发行版:CentOSRockyLinuxRedHatDebianUbuntuDeepin统信OS (Deepin 和 统信OS 是国产操作系统,其是基于 Debian 开发而来,其中目前 Deepin 是社区版本,统信OS 是商业版)
  • 如果你学习 Linux,那么学习 CentOS 就可以,如果你想体验桌面发行版,推荐 Deepin 和 Ubuntu。
  • 就目前而言,大部分服务器都跑着 CentOS,即使第三方公司自己的OS大部分也是基于 CentOS 开发定制的(比如华为、海康等),所以学习就要选择大众的,小众的只能用来练手、专研啥的。

终端工具

序号 名称 功能/介绍 免费/收费 语言 官网
01 Mobaxterm 全能
免费
小巧免安装
免费+收费 英语 Mobaxterm官网
02 XShell 国内用的较多
功能没有Mobaxterm强大
收费 中文+英文 XShell官网
03 SecureCRT 收费
需要安装
功能弱
收费 英文 SecureCRT官网
04 PuTTY 免安装
免费
绿色
功能单一
免费 英文 PuTTY官网

概念

  • 用户
    用户就是实实在在的用户账户,存在系统中的账户(根据实际业务需求并不是所有用户都可以登录)
    
  • 用户组
    用户组 可以理解为群,就好比你可以加入不同的群,这样你就会有对应的权限
    
  • 用户权限
    用户权限常规的分为:读(r)、写(w)、执行(x)
    权限除了用英文表示(rwx),还可以用数字表示,对应数值如下
    
    r = 4
    w = 2
    x = 1
    
    
    假如某个文件权限如下 ( ls -l 可以查看文件权限信息)
    
    -rw-r--r-- 1 www  www
    
    解读(从左到右,第一个字符除外,后面3个为一组):
    -     第一个 “-” 表示普通文件,如果是 “d” 则表示文件
    rw-   表示用户自己的权限,代表读写权限,没有执行权限
    r--   表示用户组权限,代表只有读权限,没有写和执行权限
    r--   其它组/用户权限,代表只有读权限,没有写和执行权限
    
    www   第一个 www ,代表用户名;第二个代表用户组名
    
    文件权限
  • 文件
  • 目录


系统管理

  • Linux 运行级别( 7 个
级别 表述 备注
0 关机,系统默认运行级别不能设置为 0 否则无法开机 ---
1 单用户;root 权限;用于系统修复、无网络功能 字符模式
2 多用户,没有 NFS 字符模式
3 全功能多用户(有NFS) 字符模式
4 系统保留,未定义未使用 ---
5 图形界面(前提得安装了GUI) 图形界面
6 正常关闭系统并重新启动,系统默认运行级别不能设置为 6 否则一直重启 ---

linux_level


  • 配置文件
  • 常用命令
systemctl restart network   # 重启网卡,当更新网卡配置时需要
ifconfig | less # 查看网络配置信息,当网卡较多的时候 加上 less 是比较有用的
ifconfig eth0 up    # 启用 eth0
ifconfig eth0 down  # 关闭 eth0
ifconfig eth0 add 192.168.1.2 netmask 255.255.255.0 # 给 eth0 设置 IP地址,推荐直接修改配置文件 /etc/sysconfig/network-script/ 
route add default gw 192.168.1.1    # 设置默认网关
ifconfig eth mtu 1500           # 设置 eth0 最大传输单元 1500 bytes

# net-tools 已经过时,如果没有 ifconfig 命令,请安装 net-tools 工具 #

ip a show   # 查看IP
ifdown eth0 # 关闭 eth0
ifup eth0   # 启用 eth0
ip route    # 查看路由

ip link show    # 查看网卡详细信息
ip link set eth0 down   # 关闭 eth0
ip link set eth0 up # 启用 eth0

ip route add 192.168.2.0/24 dev eth0    # 增加路由
ip route add 192.170.0/24 via 192.168.2.1 dev eth0  # 外部路由,via可以理解为 下一跳
ip route del 192.168.2.0/24 # 删除路由
# 借用身份
sudo dnf install vim    # 以管理员身份安装 vim
su - root   # 切换 root 身份

useradd -r test     # 创建系统用户 test
useradd -g root test    # 创建用户 test,用户组为 root
useradd -g test test -G root    # 创建用户他test,并指定默认组为test(这个组必须存在),同时test用户加入 root 组
useradd test -u 1002    # 创建用户 test,并指定 UID 为 1002

userdel -r test     # 删除用户test 以及它的home文件目录
userdel -f test     # 强制删除用户 test,即使用户已经登录

passwd test # 给用户 test 设置密码,需要输入2次密码
passwd -d test  # 删除用户test 密码
passwd -l test  # 禁止用户 test 修改密码
passwd -S test  # 查看用户 test 密码状态
echo "admin123" | passwd --stdin test   # 给用户 test 设置密码,不用输入2次,编写脚本经常用的语法

groupadd test   # 创建组 test
groupadd -r test    # 创建系统组 test
groupdel test       # 删除组 test
groupmod -n test01 test # 把组 test 更名为 test01
groupmod -g 1005 test   # 把组 test GID 改为 1005

gpasswd -a test root    # 把 test 加入 root 组,同时自己的组 test 保持不变
gpasswd -d test root    # 把 test 从 root 组删除
# CentOS 系列,8 以后可以使用 dnf,8 以前用 yum
dnf | yum provides ifconfig # 查询某个命令属于哪个软件包
dnf | yum install vim       # 安装软件 vim
dnf | yum remove vim        # 卸载 vim
  • 概念
    • "三表五链"
      • Filter表:过滤数据包,默认表
        • INPUT链: 过滤所有目标地址是本机的数据包(对进入本机的数据包进行过滤)
        • INPUT链: 过滤所有目标地址是本机的数据包(对进入本机的数据包进行过滤)
        • FORWARD链:过滤所有路过本机的数据包(源地址和目标地址都不是本机的数据包)
      • NAT表:网络地址转换
        • DNAT:改变数据包的目的地址包能从路由到某台机器(使得公网能够访问局域网的服务器)
        • DNAT:改变数据包的目的地址包能从路由到某台机器(使得公网能够访问局域网的服务器)
        • NASQUERADE:和SNAT一样使得局域网能访问公网,无固定ip使用PPP.PPPoE等拨号上网接入
        • PREROUTING链:数据包到达防火墙时改变包的目的地地址
        • OUTPUT链:改变本地产生数据包的目标地址
        • POSTROUTING:在数据包离开防火墙时改变数据包的源地址
      • Mangle表:修改数据包,改变包头中的内容(TTL,TOS,MARK)
        • PREROUTING链
        • POSTROUTING链
        • OUTPUT链
        • INPUT链
        • FORWARD链
    • 动作
      • ACCEPT:允许防火墙接收数据包
      • DROP:拒绝但不响应石沉大海
      • REJECT:拒绝并告知对方礼貌拒绝
    • 逻辑
      • 防火墙处理是从上往下匹配,匹配到就停止往下匹配
      • 匹配不到规则则放行,即 默认放行所有

  • Iptables
    • 默认规则文件:/etc/sysconfig/iptables
    • 检查状态
      ## 状态
      systemctl status iptables
      
      ## 启动
      systemctl start iptables
      ## 停止
      systemctl stop iptables
      
    • 查看规则信息
      ## 查看全部信息
      iptables --list 或者 iptables -L
      
      ## 查看指定表信息
      iptables -t filter --list
      
    • 删除规则
      ## 删除所有
      iptables --flush  或 iptables -F
      
      ## 删除指定
      iptables -D INPUT -s 192.168.1.5 -j DROP
      
      ## 删除第几行 , 比如第 5 行
      iptables -D INPUT 5
      
    • 添加规则
      ## 末尾追加一条规则
      iptables -A INPUT -s 192.168.1.5 -j DROP
      
      ## 第三行插入一条规则
      iptables -I INPUT 3 -s 192.168.1.3 -j DROP
      
    • 修改
      ## 将第三行规则改为 ACCEPT
      iptables -R INPUT 3 -j ACCEPT
      
    • 保存
      ## 保存
      iptables save 或 iptables-save
      
      ## 重启iptables
      systemctl restart iptables
      
    • 备份/导入
      ## 导出规则
      iptables save > iptables_rlues.list
      或
      iptables-save > iptables_rlues.list
      
      ## 恢复
      iptables-restore < iptables_rlues.list
      
      ## 重启
      systemctl restart iptables
      

  • Firewalld
  • at

    • 说明:at 是用来执行一次性任务的,比如下午 15:30 重启系统
    • 语法:
      # 如果没有安装 at
      yum install at  或 apt-get install at
      
      # 启动
      systemctl start atd
      
      # 查看版本
      at -V
      
      # 定时任务
      Ⅰ.
      at 20:00 2022-01-07
      at>reboot   # 任务,如果没有任务了,按按回车然后 Ctrl+D 即可保存退出       
      
      Ⅱ.
      ping www.baidu.com >> /root/pinglog.txt | at 21:55 2022-01-06
      # 查看定时任务
      atq
      
      # 删除任务
      atrm 任务ID 
      
  • crond

    • 说明:Linux 下用来周期性执行一系列任务的程序
    • 语法:
          # 如果没有安装
      yum/dnf install crond   或 apt-get install crond
      
      # 启动
      systemctl start crond
      
      # 查看版本
      crontab -V
      
      # 查看任务列表
      crontab -l
      
      # 编辑任务
      crontab -e  # 这里会调用 vim 或者 vi 编辑器
      0 1 * * * ping -c 4 www.baidu.com   # 时间写法为: 分 时 日 月 星期 ,* 代表所有;周和日月不可同时存在
      */5 * * * * ps -ef | grep ssh       # 每5分钟查一次进程并过滤出 ssh
      
      # 指定任务列表文件
      crontab list.txt    # 文件路径要写绝对路径
      
      # 删除任务
      crontab -r 任务ID # 也可以直接 crontab -e ,然后删除对应的行即可
      
    • crontab 时间
      • 语法格式:分 时 日 月 星期 动作 对象
      • 示例
        # 每10分钟
        */10 * * * * /bin/bash /var/ping.sh
        
        # 每天凌晨 3:10 
        10 3 * * * /bin/bash /var/ping.sh
        
        # 每月 7 号 3:10
        10 3 7 * * /bin/bash /var/ping.sh
        
        # 每周一、周三 3:10
        10 3 * * 1,3 /bin/bash /var/ping.sh
        


系统配置

  • 网卡
    • 一般配置
  • V8 以前
    TYPE=Ethernet    # 网络类型,这里表示以太网
    PROXY_METHOD=none
    BROWSER_ONLY=no
    BOOTPROTO=static   # IP获取方式 dhcp(自动获取) 或 static(静态IP)
    DEFROUTE=yes
    IPV4_FAILURE_FATAL=no
    NAME=enp0s3  # 网卡名称,一般不改
    UUID=ea773efc-e3ed-4bda-87a8-8e7ee3d1846f  # 设备 UUID,一般不改
    DEVICE=enp0s3  # 设备名称,一般不改
    ONBOOT=yes  # 开机自启
    IPADDR=192.168.1.10   # IP 地址
    PREFIX=24  # 子网掩码,两种写法 NETMASK=255.255.255.0  或 PREFIX=24
    GATEWAY=192.168.1.1  # 网关地址,如果只是一个段内互通,可以省略
    
  • V8及以后
    ## 配置文件在 /etc/NetworkManager/system-connections
    ## 这里以IPv4 为例,找到 [ipv4] 标签,改成如下
    [ipv4]
    method=manual  ## 手动配置 manual ,自动配置 auto
    address1=192.168.56.10/24,192.168.56.1
    dns1=119.29.29.29
    dns2=182.254.116.116
    
    ## 加载配置文件
    nmcli c reload 或 nmcli c reload xxx(配置文件名称)
    
    ## 生效网卡
    nmcli c up xxx(网卡名称)
    

auto eth0 # 网卡名称
iface eth0 inet static  # IP获取方式 dhcp(自动获取) 或 static(静态IP)
address 192.168.1.2
netmask 255.255.255.0
gateway 192.168.1.1
* bond 配置:多张网卡虚拟成一张网卡,增加带宽,提供不间断服务(这里假定 eth0 和 eth1 )

Bond 模式( 1、5、6 不需要交换机配合设置 ) 参考

mode 说明
mode=0 round-robin(轮转策略): 轮流在 eth0 和 eth1 上发数据,提供负载和容错能力
mode=1 active-backup(主备策略): 只有 eth0 工作,只有当 eth0 down,eth1 才工作
mode=2 XOR(hash策略): 取决于所选的传输策略 hash
mode=3 broadcast(广播策略): 向 eth0 和 eth1 发送数据,提供容错
mode=4 802.3ad(动态链路聚合): eth0 和 eth1 出口取决传输的 hash(可以通过 xmit_hash_policy 选项配置),默认是 XOR简单策略,需要交换机配合设置
mode=5 balance-tlb(自适应传输负载均衡): 根据负载决定从哪张网卡发送数据,当前网卡接收数据,如果当前网卡故障,其它网卡接管它的MAC地址继续接收数据;每张网卡必须支持ethtool获取速率
mode=6 balance-alb(自适应负载): 每张网卡必须支持ethtool获取速率;每张网卡必须支持启用时重新设置MAC地址
vim  /etc/sysconfig/network-scripts/ifcfg-bond0         # 建立虚拟网卡bond0
DEVICE=bond0
IPADDR=10.10.10.1
NETMASK=255.255.255.0
ONBOOT=yes
BOOTPROTO=none
USERCTL=no
GATEWAY=10.10.10.254

vim  /etc/sysconfig/network-scripts/ifcfg-eth0          # eth0 配置 
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
USERCTL=no
MASTER=bond0
SLAVE=yes 

vim  /etc/sysconfig/network-scripts/ifcfg-eth1          # eth1 配置
DEVICE=eth1
BOOTPROTO=none
ONBOOT=yes
USERCTL=no
MASTER=bond0
SLAVE=yes 

# 设置完成后,重启网络服务来使用bond0生效

service network restart  # bond模块会自动加载 ;条件运行可以直接重启服务器

cat /proc/net/bonding/bond0  # 查看目前bonding的状态
modprobe -r bonding;service network restart   # 让bond模式生效

  • 设置主机名

    查看主机名
    hostname 或 cat /etc/hostname
    
    设置主机名
    hostname xxxx (临时)
    hostnamectl set-hostname xxx  (永久)
    vim /etc/hostname   (直接修改文件)
    

  • 开机启动

    • /etc/rc.d/rc.loacl 方式

      ## 给权限
      chmod +x /etc/rc.d/rc.loacl
      
      ## 在文末添加需要执行的脚本
      echo '<脚本绝对路径>' >> /etc/rc.d/rc.local
      

    • cron 方式

      @reboot <脚本绝对路径>
      

    • systemd 方式

      ## 在 /etc/systemd/system 创建 <你的服务名称>.service 的脚本
      ## 脚本内容如下
      
      [Unit]
      
      Description=Run a Custom Script at Startup
      
      After=default.target
      
      [Service]
      ExecStart=<脚本绝对路径>
      [Install]
      WantedBy=default.target
      
      ## 脚本内容结束
      
      ## 重载 systemd 服务
      systemctl daemon-reload
      
      ## 加入开机启动项
      systemctl enable <你的服务名称>.service
      


Shell编程

  • Bourne Shell ( /usr/bin/sh 或 /bin/sh )
  • Bourne Again Shell ( /usr/bin/bash/bin/bash ) 常用
  • C Shell ( /usr/bin/csh )
  • K Shell ( /usr/bin/ksh )
  • Shell for Root ( /sbin/sh )
cat /etc/shells 或者 chsh -l  # 查看当前系统可用的 Shell
echo $SHELL     # 查看当前使用的 Shell 环境

bash        # 切换 Shell 为 bash
sh      # 切换 Shell 为 sh

bash t.sh   # 以 bash 运行 t.sh 脚本
sh t.sh     # 以 sh 运行 t.sh 脚本
  • 所谓 Shell脚本 就是把一系列命令按照一定逻辑写入一个文件
  • Shell 脚本通常以 .sh 为后缀,这个只是为了让人看到,对计算机而言无关紧要
  • Shell 脚本 第一句为 Shell 环境语句: #!/bin/bash ,你需要什么环境就怎么写,写绝对路径
  • 如果脚本文件没有执行权限,那边需要 bash xxx.sh 方式运行脚本
  • 调试脚本用 bash -x xxx.sh,这个在写脚本很有用
  • Shell 变量不用声明,赋值即表示声明,如 a=5,引用变量 $a,变量定义等号两边不能有空格
  • 脚本中调用命令方式有两种: $( 你的命令 ) 或者 ` 你的命令 `
  • 数组语法
    • 常规数组用小括号表示 (),元素之间用空格隔开,元素从 0 开始
      • arr_str=(1 5 A C 6) ===> 定义一个数组
      • ${arr_str[0]} ===> 表示第一个元素
      • ${#arr_str[@]}${#arr_str[*]} ===> 数组长度
      • ${arr_str[@]}${arr_str[*]} ===> 所有元素
      • echo ${arr_str[*]} | grep -w "123" ===> 123 是否已存在数组中
      • arr_str[0]=123 ===> 元素赋值
      • unset arr_str[0] ===> 删除元素 arr_str[0]
      • unset arr_str ===> 删除整个数组
      • arr_str[${#arr_str[@]}]='456' ===> 添加元素
      • arr_str=(${arr_str[@]/xxx}) ===> 删除指定元素,xxx 是元素的值
    • 关联数组
      • 定义数组
        declare -A arr_test
        arr_test["iquan"]="iquan.fun"
        arr_test["deyun"]="deyun.fun"
        arr_test["baidu"]="baidu.com"
        arr_test["runoob"]="runoob.com"
        
        OR
        declare -A arr_test=(["iquan"]="iquan.fun" ["deyun"]="deyun.fun" ["biadu"]="baidu.com" ["runoob"]="runoob.com")
        
      • 访问某个元素
        echo ${arr_test["iquan"]}
        
      • 获取数组所有键值
        echo ${!arr_test[*]}
        
      • 除上述外,其他操作方式与普通数组相同
  • 删除/替换 变量中某个字符
    • 删除 nulla='123null456';${a//null/}
    • 删除 空格a='123 456';${a// /}
    • 替换字符串:a='123 456';${a/23/88}23 替换为 88
    • 删除最后一个字符串:a=123456;echo ${a%?} 删除最后2个字符串就是2个 ?
  • 截取操作 参考 bdy博客
    • 截取匹配的第一个后的所有字符串
      • 从左往右:result=${string#*chars}
      • 从右往左:result=${string%chars*}
    • 截取匹配的最后一个后的所有字符串
      • 从左往右:result=${string##*chars}
      • 从右往左:result=${string%%chars*}
  • 算术运算用 $(()) 表示,如 $(( 1+2 )) 表示 1+2,算式两边有空格
  • Shell 正则用 [] 表示,不是所有 Shell 都支持这种写法
  • Shell 处理 json 数据用 jq,一般需要单独安装:yum/dnf install jqapt-get install jq
  • Shell test
参数 用途 参数 用途
-eq 数字比较:相等 = 字符:等于
-ge 数字比较:大于等于 != 字符:不等
-gt 数字比较:大于 < 字符:小于
-le 数字比较:小于等于 > 字符:大于
-lt 数字比较:小于 -z 字符:长度为 0
-ne 数字比较:不等于 -n 字符:长度非 0
-d 是否存在且是目录 -s 是否存在且非空
-e 是否存在 -o 是否存在且所有者属于当前用户
-f 是否存在且是普通文件 -G 是否存在且默认组与当前用户组相同
-r 是否有可读权限 -nt 左边文件是否比右边文件新
-w 是否有可写权限 -ot 左边文件是否比右边文件旧
-x 是否有可执行权限
  • 循环那些事儿

    • if
      ## example 1
      if [ $a -eq 5 ];then
        todo something
      fi
      
      ## example 2
      if [ $a -eq 10 ];then
        todo something
      else
        todo something
      fi
      
      ## example 3
      if [ $a -le 10 ];then
        todo somethin
      elif [[ $a -ge 10 && $a -le 99 ]];then
        todo something
      fi
      
    • for
      ## example 1
      for i in a b c
      do
        todo something
      done
      
      ## example 2
      for i in $(cat aa.txt)
      do 
        todo something
      done
      
      ## example 3
      for (( i = 0;i < 10;i++ ))
      do
        todo somethin
      done
      
    • while

      ## example 1
      while $a < 10
      do
        todo something
      done
      
      ## example 2
      while true 
      do
      
        todo something
      done
      
      ## example 3
      while read line < a.txt
      do
        todo something
      done
      

    • case ... esac

      ## example 1
      case $a in
      1 )
        todo something
      ;;
      2 )
        todo something
      ;;
      * )
        todo someting
      esac
      

参数形式 说明
$# 传递给脚本的参数个数
$* 打印所有参数 ;不换行输出
$$ 脚本运行的当前进程ID
$! 后台运行的最后一个进程的ID
$@ 与 $* 相同,但使用时需要加 引号,换行输出参数
$- 显示Shell 使用的当前选项
$? 显示最后一条命令的退出状态:0 表示成功,非0 则失败
  • 生成随机字符串
    date +%s | md5sum
    
  • 字符串替换
    # 小写 转 大写
    echo '0c0492283321d6f5e4d3faa29510a0dc' | tr 'a-z' 'A-Z'
    
    # 空格 转 换行
    echo '0c 04 92 28' | tr ' ' '\n'
    
  • grep 匹配行并返回后面的行信息
    # 返回匹配后面的 1 行
    grep -A 1 "123" t.txt
    
    # 返回匹配行的前面行
    grep -B 2 "123" t.txt
    
  • 在指定行后面添加内容
    # 把文件 b.txt 中的内容插入到 t.txt 的第54行中
    awk '1;NR==53{system("cat b.txt")}' a.file > t.txt
    
  • 获取字符串长度
    # 方法一
    echo '283321d6f5e4d3faa29' | wc -L
    
    # 方法二
    echo '283321d6f5e4d3faa29' | awk '{print length($0)}'
    
    # 方法三
     expr length $(echo '283321d6f5e4d3faa29')
    
  • 日期计算
    # 两个日期相差
    start_date='2022-01-01'
    end_date='2022-01-05'
    a=$(date -d "$start_date" "+%s")
    b=$(date -d "end_date" "+%s")
    differ_days=$(( ($b - $a) / 86400 ))
    
    # 2天以后
    late_date=$(date -d "$start_date 2 days" "+%Y-%m-%d")
    
    # 2天以前
    last_date=$(date -d "$start_date 2 days ago" "+%Y-%m-%d")
    
  • 调用其他 Shell 脚本
    # 方式 一
    source xxx.sh
    
    # 方式 二
    . xxx.sh    # 注意 . 后面有空格
    
  • 获取目录:脚本目录及上一级目录
    # 脚本目录
    dir0=$(cd $(dirname $0);pwd)
    
    # 脚本的上一级目录
    dir1=$(dirname "$dir0")  或 dir1=$(dirname "$(cd $(dirname $0);pwd)")
    
  • 判断参数是否为有效数字
    function isnum(){
      if expr "${1}" '+' 1 > /dev/null 2>&1 ;then
        ## 有效数字
        return 0
      else
        ## 无效数字
        return 1
      fi
    }
    
  • for 遍历行且行内容有空格
    OLDIFS=$IFS
    ## 定义 IFS ,for 语句默认以空格、换行作为分隔符
    IFS=$'\n'
    for i in xxx
    do
      your codes
    done
    ## 还原 IFS
    IFS=$OLDIFS
    
  • 自增和自减
    ## 自增
    num=0
    (( num ++ ))
    
    ## 自减
    num=10
    (( num -- ))
    
  • 颜色字体输出
    ## 字体颜色 30 - 37
    echo -e "\e[30m 黑色 \e[0m"
    echo -e "\e[31m 红色 \e[0m"
    echo -e "\e[32m 绿色 \e[0m"
    echo -e "\e[33m 黄色 \e[0m"
    echo -e "\e[34m 蓝色 \e[0m"
    echo -e "\e[35m 紫色 \e[0m"
    echo -e "\e[36m 青色 \e[0m"
    echo -e "\e[37m 白色 \e[0m"
    
    ## 背景颜色 40 - 47
    echo -e "\e[40m 黑底 \e[0m"
    echo -e "\e[41m 红底 \e[0m"
    echo -e "\e[42m 绿底 \e[0m"
    echo -e "\e[43m 黄底 \e[0m"
    echo -e "\e[44m 蓝底 \e[0m"
    echo -e "\e[45m 紫底 \e[0m"
    echo -e "\e[46m 青底 \e[0m"
    echo -e "\e[47m 白底 \e[0m"
    
    ## 字体属性
    \e[0m 关闭所有属性
    \e[1m 设置高亮度
    \e[4m 下划线
    \e[5m 闪烁
    \e[7m 反显,撞色显示,显示为白字黑底,或者显示为黑底白字
    \e[8m 消影,字符颜色将会与背景颜色相同
    \e[nA 光标上移 n 行
    \e[nB 光标下移 n 行
    \e[nC 光标右移 n 行
    \e[nD 光标左移 n 行
    \e[y;xH 设置光标位置
    \e[2J 清屏
    \e[K 清除从光标到行尾的内容
    \e[s 保存光标位置
    \e[u 恢复光标位置
    \e[?25 隐藏光标
    \e[?25h 显示光标
    
  • 多线程处理任务(任务之间不有依赖关系)
    您的代码
    
    ## 多线程开始
    tmp_fifofile='/tmp/$$.fifo'
    mkfifo "${tmp_fifofile}"
    exec 6<>"${tmp_fifofile}"
    rm -f "${tmp_fifofile}"
    ## 线程数
    thread_num=10
    for (( k=0;k<${thread_num};k++ ))
    do
          echo 
    done >&6
    您的循环体 for while
    do
      read -u6
      {
        您的任务代码
        echo >&6
      } &
    done
    wait && exec 6>&-
    

  • 调用脚本
脚本类型 调用方式
shell . shell脚本文件名[绝对路径]
php /usr/bin/php php脚本文件名[绝对路径]
/usr/bin/php -r "echo 'hellow';" ## 直接加php语句
python /usr/bin/python python脚本文件名[绝对路径]
/usr/bin/python -c "print('hellow')" ## 直接加python语句

自动化搞事情

  • 基础命令
    • spawn 交互程序开始后面跟命令或者指定程序
    • expect 获取匹配信息匹配成功则执行expect后面的程序动作
    • send exp_send 用于发送指定的字符串信息
    • exp_continue 在expect中多次匹配就需要用到
    • send_user 用来打印输出 相当于shell中的echo
    • exit 退出expect脚本
    • eof expect执行结束 退出
    • set 定义变量
    • puts 输出变量
    • set timeout 设置超时时间

  • 代码示例
    • 直接 expect
      #!/bin/expect
      代码开始
      
    • bash 调用 expect
      #!/bin/bash
      
      bash 代码
      
      /bin/expect <<-EOF
      expect 代码
      ...
      expect eof
      EOF
      
      bash 代码
      
  • 知道
    • Ansible 默认通过 SSH 管理主机
    • 不用在被管理主机上安装客户端软件,需要有Python环境(Python2.6Python2.7)
    • 支持 WindowsLinux(Red Hat, Debian, CentOS, OS X, BSD,RockLinux等)Windows不可以做管理机
    • Playbook 核心元素
      • Hosts 执行的远程主机列表
      • Tasks 任务集
      • Varniables 内置变量或自定义变量在playbook中调用
      • Templates 模板,即使用模板语法的文件,比如配置文件等
      • Handlers 和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
      • tags 标签,指定某条任务执行,用于选择运行playbook中的部分代码
  • 命令
  • Playbook
    • Playbook 的格式是 YAML 格式,文件后缀可以是 .yamlyml
    • playbook 由一个或多个 plays 组成,它的内容是一个以 plays 为元素的列表
    • Playbook 用 # 作为注释标记符,# 后面的语句不会被解析(同行)
    • --- 标记单个 play 的开始,也可以选择性的用 ... 标记 play 的结束
    • 缩进必须统一,不能空格和 TAB混用
    • playbook 文件内容是区分大小写的
    • 一个完整的代码块功能需要最少元素包括 name: task
    • 每一个 task 必须有一个名称 name

命令摘要

  • echo
    • 不带换行输出
      echo -n '123'
      
    • 特殊字符输出
      echo -e '123\n456'
      
  • sed
    • 文件插入
      ## 在第一行前插入内容
      sed -i "1i内容" filename
      
      ## 最后一行前插入
      sed -i "$i内容" filename
      
      ## 最后一行后插入(追加)
      sed -i "$a内容" filename
      
      ## 行首添加
      sed -i "s/^host*$/内容&/g"
      
      ## 行末添加
      sed -i "s/^host*$/&内容/g"
      
    • 行删除
      ## 删除第一行
      sed -i "1d" filename
      
      ## 删除匹配行
      sed -i "/字符串/d" filename
      
      ## 删除 xx打头的行
      sed -i "/^xx/d" filename
      
      ## 删除匹配的前2、后3行
      sed -i "-2,+3d" filename
      
      ## 删除第3行到最后一行
      sed -i "3,$d" filename
      
      ## 匹配并替换
      sed -i "s/查找的字符串/替换成的字符串/g" filename
      
    • 字符串首尾空格删除
      ## 删除行首空格
      sed 's/^[ \t]*//g'
      
      ## 删除行尾空格
      sed 's/[ \t]*$//g'
      
      ## 删除所有空格
      sed 's/[[:space:]]//g'
      
    • 批量替换所有文件
      sed -i 's/查找串/替换串/g' `grep -rl '查找的串' 路径或文件`
      
    • 按规律插入字符
      ## 假如字符串为 0a0027000012
          ## 需要改为 0a:00:27:00:00:12
      echo '0a0027000012' | sed 's/.\{2\}/&:/g' | sed 's/:$//g'
      # 0a:00:27:00:00:12
      
      ## 没错,当你需要批量处理mac地址格式时候,非常适用
      
  • awk
    • 分割输出
      ## 默认以 空格、tab 分割
      awk '{print $1}'   // 打印第一列
      
      ## 指定分隔符
      awk -F':' '{print $1}' // 以:分割,打印第一列
      awk -F':' '{print $1","$2}' // 以 : 分割,打印1和2列,并用 , 隔开
      
    • 浮点数计算
      ## 计算 335 除以 77 并保留 2 位小数
      awk 'BEGIN{printf ("%.2f\n",335/777)}'
      
      ## 变量传递法
      echo '678' | awk '{printf ("%.2f\n",$1/777)}'
      awk -v a=68 -v b=33 'BEGIN{printf ("%.2f\n",a/b)}'
      
  • grep

    • 反过滤:grep -v "过滤内容"
    • 匹配行和之前 2 行:grep -B 2 "过滤内容"
    • 匹配行和之后 2 行:grep -A 2 "过滤内容"
    • 正则匹配:grep -E "正则语法"
    • 忽略大小写:grep -i "过滤内容"
    • 显示行号:grep -n "过滤内容"
  • tr

    • 替换字符:tr '老字符串' '新字符串',新字符串不能为空
    • 删除字符串:tr -d '删除的字符'
  • jq

    • Shell 下json数据处理工具,需独立安装 yum install jq 或 apt-get install jq
    • 官方文档
    • 用法
      • 格式化 json
        ## 便于阅读
        jq -r .
        
        ## 字符串化
        jq -c . 
        
      • 创建 json
        ## 创建json
        echo '{}' | jq -c '.name="Zhangsan"|.sex="Man"'
        
        ## 增加/修改字段值,如果字段存在则修改,不存在则增加
        echo '你的json串' | jq -c '.指定字段="需要的值"'
        
        ## 多级操作
        echo '{}' | jq -c '.name="Zhangsan"|.sex="Man"' | jq -c '.age.a="18"'
        # {"name":"Zhangsan","sex":"Man","age":{"a":"18"}}  
        
      • 取出 json 键值
        ## 取出所有 name 的值
        echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq .[].name
        
        ## 取出第一个组的 name 值
        echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq .[0].name
        
      • json 数组长度
        echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '. | length'
        
      • 判断是否存在某个 keys( 如果是数组需要指定下标 )
        ## 返回 true
        echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[0] | has("name")'
        
        ## 返回 false
        echo '{"name":"JSON", "good":true}' | jq '. | has("naml")'
        
      • 取多个keys
        echo '{"name":"kumufengchun","age":"18","city":"beijing","email":"kumufengchun@gmail.com","date":"Thursday","country":"China"}' | jq '.name,.city,.email'
        
      • 删除
        ## 删除指定键值
        echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '. | del(.[0].name)'
        
        ## 删除指定数组
        echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '. | del(.[0])'
        
  • curl

    • 认识

      • 一个利用URL规则在命令行下工作的文件传输工具,它支持文件的上传和下载,所以是综合传输工具
      • 支持包括HTTP、HTTPS、ftp等众多协议,还支持POST、cookies、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征
      • 默认使用 get 方式请求
      • 在请求HTTP时,不想显示速率等信息,可以用安静模式, -s
    • 用法

      • 下载文件
        curl http://soft.vpser.net/lnmp/lnmp1.8.tar.gz -o lnmp1.8.tar.gz --progress
        
      • 用curl设置cookies
        curl https://iquan.fun --cookie "user=root;pass=123456"
        
      • curl进行认证
        curl -u root:123456 https://iquan.fun
        
      • POST 请求
        curl -X POST https://iquan.fun
        
        ## 超时 30 秒
        curl -X POST --connect-timeout 30 https://iquan.fun 
        
        ## 自定义头部信息
        curl -H "accept-language:zh-cn" -X POST --connect-timeout 30 https://iquan.fun
        
  • find

    • 常用参数列表

      参数 作用 参数 作用
      -name 按文件名查找,支持使用通配符 * 和 ? -type 按文件类型查找,可以是 f(普通文件)、d(目录)、l(符号链接)等
      -size 按文件大小查找,支持使用 + 或 - 表示大于或小于指定大小,单位可以是 c(字节)、w(字数)、b(块数)、k(KB)、M(MB)或 G(GB) -user 按文件所有者查找
      -group 按文件所属组查找 -atime 查找在 n*24 小时内被访问过的文件
      -ctime 查找在 n*24 小时内状态发生变化的文件, +n 表示n天以前的文件,-n 表示n天之内 -perm 根据权限查找,比如 -perm 755
    • 时间轴:find_time

    • 常用方式:find "Directory" -option -exec todo {} \;

      • 删除 30 天以前的文件:find / -mtime +30 -exec rm -f {} \;
      • 删除 所有 .log 的文件:find / -name *.log -exec rm -f {} \;
    • 几条常用样例

      • 查找字符串(指定目录下所有包含字符串的文件):find ./ | xargs grep -ri 'xxxx'

vi / vim

  • 快捷键
快捷键 功能 快捷键 功能
Ctrl + f 向上翻一页 ^ 光标跳到行首第一个字符(等同 home 键)
Ctrl + b 向下翻一页 $ 光标跳到行尾最后一个字符(等同 end 键)
Ctrl + u 向上翻半页 gg 光标跳到首行
Ctrl + d 向下翻半页 Shift + g 光标跳到末行
dd 删除光标所在行 p 粘贴在光标行下
Shift + v 选中光标所在行 Shift + p 粘贴在光标行上
Shift + > 右缩进一个 Tab 位 u 撤销
Shift + < 左缩进一个 Tab 位 ~ 当前行切换大小写
i 光标所在位进入插入模式 gg=G 格式化所有代码
o 光标所在位下一行进入插入模式
  • 命令大全

FAQ

  • history 格式化
    • 带时间
      ## 修改 etc/bashrc ,把如下两行代码加在文件末尾 
      ## 也可以修改用户家目录下 .bash_history 文件,注意这里仅对用户有效
      vim /etc/bashrc
      
      HISTTIMEFORMAT="%F %T "
      export HISTTIMEFORMAT
      
    • 清除历史命令
      ## 清除当前登录的历史命令
      history -c -w
      
      ## 清除用户所有命令,比如root
      echo > .bash_history
      

  • Python2.x 升级 Python3.x
    • 说明:
      • 2.x 不能升级 3.x 及以上版本
      • 只能多个版本共存
    • 去官网下载自己需要的 Python 版本
    • 解压并编译安装
      wget https://www.python.org/ftp/python/3.11.0/Python-3.11.0a1.tgz
      tar xvf Python-3.11.0a1.tgz -C /usr/local/src
      cd /usr/local/src/Python-3.11.0a1
      ./configure && make && make install
      

  • 出现 yumdnf not found
    • 说明:一般是由于手动卸载系统自带的 python 导致的,Linux 中很多命令都依赖 python
    • 解法:
      • 卸载 python(以防残留):rpm -qa|grep python|xargs rpm -e --allmatches --nodeps
      • 卸载 yum(以防残留):rpm -qa|grep yum|xargs rpm -e --allmatches --nodeps
      • 创建 rpm 包存放目录:mkdir /usr/local/src/pythonmkdir /usr/local/src/yum
      • 下载 python 包并安装
        cd /usr/local/src/python
        wget http://vault.centos.org/7.2.1511/os/x86_64/Packages/python-2.7.5-34.el7.x86_64.rpm
        wget http://vault.centos.org/7.2.1511/os/x86_64/Packages/python-iniparse-0.4-9.el7.noarch.rpm
        wget http://vault.centos.org/7.2.1511/os/x86_64/Packages/python-pycurl-7.19.0-17.el7.x86_64.rpm
        wget http://vault.centos.org/7.2.1511/os/x86_64/Packages/python-devel-2.7.5-34.el7.x86_64.rpm
        wget http://vault.centos.org/7.2.1511/os/x86_64/Packages/python-libs-2.7.5-34.el7.x86_64.rpm
        wget http://vault.centos.org/7.2.1511/os/x86_64/Packages/python-urlgrabber-3.10-7.el7.noarch.rpm
        wget http://vault.centos.org/7.2.1511/os/x86_64/Packages/rpm-python-4.11.3-17.el7.x86_64.rpm
        
        ## install 
        rpm -ivh python-* rpm-python-* --nodeps --force
        
        ## check python version
        python -V
        
      • 下载 yum 包并安装
        cd mkdir /usr/local/src/yum
        
        ## install
        rpm -ivh yum-* 
        

  • RockyLinux 安装docker 和 docker compose (CentOS 同理)
    • 安装依赖
      dnf install -y yum-utils device-mapper-persistent-data lvm2
      
    • 添加 Docker-CE 源
      ## 官方源
      yum config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
      
      ## 阿里源
      dnf config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
      
    • 安装Docker-CE
      dnf  -y install docker-ce
      
    • 开启Docker服务
      systemctl start docker
      
    • 版本检查
      docker version
      
    • 安装 docker-compose
      ## 下载可执行文件
      curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
      
      ## 赋予执行权限
      chod +x /usr/local/bin/docker-compose
      
      ## 如果下比较慢,可以按如下操作,就可以得到完整链接
      echo "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)"
      # https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-Linux-x86_64
      
      ## 此下载链接随时会丢失
      # curl -s 'https://dl1.serctl.com/downloads8/2023-10-08-14-38-55-compose-docker-compose-Linux-x86_64'
      
      ## 复制上面的链接到文件代理加速网站进线下载即可
      ## 版本查看
      docker-compose version
      # Docker Compose version v2.2.2
      

  • Linux 网络时间同步

    • 安装 ntpd 服务
      dnf install ntp
      
    • 同步时间
      # 国家授时中心
      ntpdate ntp.ntsc.ac.cn
      
    • 定时同步
      crontab -e 
      
      # 添加任务
      */10 * * * * ntpdate ntp.ntsc.ac.cn
      

    上述方法适用于: CentOS 7.x 版本,CentOS 8 及以上 请使用下面方法


    # 检查是否安装 chrony
    rpm -qa | grep chrony
    
    # 如果没安装,则手动进行安装
    dnf install chrony
    
    # 修改配置文件
    vim /etc/chrony.conf     把 pool  `2.pool.ntp.org` iburst 行中 `2.pool.ntp.org` 替换为你要的授时服务器 `IP`或`域名`,比如替换为 `ntp.ntsc.ac.cn` 国家授时中心地址
    
    # 重启 chrony 服务
    systemctl restart chronyd
    systemctl status chronyd
    
    # 查看同步情况
    chronyc sourcestats -v
    
    # 手动同步一下,返还 200 即代表同步成功
    chronyc -a makestep
    
    # 检查系统日期时间
    date
    

  • 忘记 root 密码
    • Redhat系列(资料参考
      • 系统启动后到Grub界面,按住 E
      • 光标移动到 Linux 开头的行末,添加 rd.break console=tty0(注意 rd 前面有空格)
      • 修改完后按住 Ctrl + X 进入单用户模式
      • 挂载文件,并修改root密码
        mount -o remount,rw /sysroot
        chroot /sysroot
        ## 假设密码是 Ab123456
        ## 建议执行两遍
        echo -n 'Ab123456' | passwd --stdin root
        touch /.autorelabel
        ## 同步数据,同样建议敲两遍
        sync
        
      • Ctrl + D 两次 退出(或 Ctrl + Alt + Delete),系统重启后就可以用新该的密码登录了
    • Debian系列(资料参考
      • 系统启动后到Grub界面,按住 E
      • 光标移动到 Linux 开头,quiet 结尾的行末,在quiet后添加 init=/bin/bash(注意 init 前>面有空格)
      • 修改完后按住 Ctrl + X 进入单用户模式
      • 挂载文件,并修改root密码
        mount -o remount,rw /
        chroot /
        ## 假设密码是 Ab123456
        ## 建议执行两遍
        echo -n 'Ab123456' | passwd --stdin root
        sync
        
        - Ctrl + D 两次 退出(或 Ctrl + Alt + Delete),系统重启后就可以用新该 的密码登录了

By anYun 2023.04.18


  • SSH 远程root账户一直报 access denied
    • 最新版的RockyLinux安装时支持设置 root 远程,如果没有勾选系统默认是不允许root远程的
    • 修改 /etc/ssh/sshd_config ,将 PermitRootLogin without-password 替换为 PermitRootLogin yes
    • 重启 ssh 服务:systemctl restart sshd 或老版本 service sshd restart

By anYun 2023.04.21


  • 查看Linux内核以及发行版本
    • CentOS/Redhat 系列
      cat /etc/redhat-release
      或
      cat /proc/version
      或
      cat /etc/os-release
      或
      uname -a
      或
      hostnamectl
      
    • Debian/ubuntu 系列
      cat /etc/os-release
      或
      cat /etc/proc/version
      或
      cat /etc/issue
      或
      lsb_release -a
      或
      uname -a
      或
      hostnamectl
      

By anYun 2023.05.08


  • SSH 服务启动报错Can't open PID file /var/run/sshd.pid (yet?) after start: No such file or directory
    • 情况分析
      • 这种情况一般是修改了 sshd_config 文件导致
      • 也有极个别情况是 /var/run 下这个目录权限问题,但太少了
      • sshd 服务端口修改了,被selinux拦截导致
    • 解决方法
      • 检查 sshd_config 文件
      • 修改 /var/run/ 的权限:chmod -Rf 755 /var/run/
      • 检查 selinux 配置
        semanage port -l | grep ssh
        
        ## 增加你修改后的端口,比如 68784
        semanage port -a -t ssh_port_t -p tcp 68784
        

By anYun 2023.06.01


  • who 发现同一个用户多个连接进程
    • 确认多个进程是否有效 who_list
    • 杀死无用进程:pkill -kill -t pts/0
    • pkill 之前一定要确认是否有效
    • 这种情况一般是网络连接异常导致的进程残留

By anYun 2023.06.14


  • Linux 下找不到网络接口文件
    • CentOS8及以下:/etc/sysconfig/network-scripts
      • 生效网络配置:systemctl restart network
    • CentOS9 以上
      • 网络接口文件:/etc/NetworkManager/system-connections
      • 生效网络配置
        ## 重新载入所有网络配置文件(并未生效)
        nmcli c reload
        ## 重新载入指定网络配置文件(并未生效)
        nmcli c reload  enp3s0
        
        ## 立即生效配置文件
        nmcli c up enp3s0
        

By anYun 2023.06.16

  • SSH 端口转发
    • 场景描述
      • 主机A 可以访问 主机B,反之不能
      • 客户机C 可以访问 主机B,但不能访问 主机A
      • 业务在 主机A 上,客户机C 需要访问 主机A 业务
      • 主机信息:主机A 172.16.1.10主机B 172.16.24.23客户机C 172.16.88.7
    • 一条命令的事儿
      ## 8066 主机B代理端口
      ## localhost:80  主机A端口
      ## root@172.16.24.33 -p 6786 主机B ssh信息
      
      ## 在主机A执行,然后输入密码,当然也可以用免密方式
      ssh -NfR 8066:localhost:80 root@172.16.24.33 -p 6786
      
    • 这样客户机C访问 172.16.24.33:8066 就可以访问到 主机A的80端口上的业务了
    • 在主机A checking 端口转发是否正常
      lsof -i:80 | grep ssh
      ssh     1309591 root    5u  IPv4 2704761      0t0  TCP localhost:51726->localhost:http (ESTABLISHED)
      
      pstree -p | grep -w 'ssh'
      |-ssh(509044)
      
    • 可以做计划任务进行定期巡检,比如 1 分钟、5 分钟等

By anYun 2023.08.02


  • Linux 主机之间 SSH免密
    • 假设主机A和主机B
    • 在主机A上生成 ssh key
      ssh-keygen  ## 一路回车走到底,注意看key文件存放位置
      
    • 将key文件id_rsa.pub拷贝到主机B
      ssh-copy-id -i id_rsa.pub -p 8857 root@主机B
      ## 执行后根据提示操作,并输入主机B的SSH密码
      
    • 在主机A上SSH主机B就再也不用输入密码了
      ssh root@主机B -p 8857
      

By anYun 2023.08.03


  • Linux date 显示不是24小时制
    • 检查时区
      timedatectl | grep 'Time zone'
      # Time zone: Asia/Shanghai (CST, +0800)
      
    • 检查系统、硬件时钟
      date -R
      # Fri, 11 Aug 2023 13:56:37 +0800
      
      hwclock -r
      # 2023-08-11 13:56:51.686885+08:00
      
    • 修改 locale.conf 配置
      vim /etc/locale.conf
      
      ## 增加如下一行,如果已有 LC_TIME 行,则将值改为 en_GB.UTF-8 即可
      LC_TIME="en_GB.UTF-8"
      
    • 重启系统 reboot

By anYun 2023.08.11


  • CentOS 配置阿里yum源
    • 备份原有的 yum源
      cp -r /etc/yum.repos.d/ /etc/yum.repos.d.back
      
    • 下载阿里 yum源
      ## Centos-7.repo 是版本,你也可以写成 Centos-8.repo
      curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
      
    • 清缓存
      yum clean all
      
    • 生成缓存
      yum makecache
      

By anYun 2023.09.07


  • Bash 脚本数字逻辑比较出错
    • 两数字比较,引用变量不能使用""引起来
    • 数字比较时,两边类型必须是数字,数字和字符串不能直接比较

By anYun 2023.09.19


  • curl 返回中文内容时中文乱码
    • 添加 Header :curl -H "charset=UTF-8" 'xxx.com/xxx.txt'
    • 直接转换: curl -s 'xxx.com/xxx.txt' | iconv -f gbk -t utf-8

By anYun 2023.10.18


  • Rockylinux 修改yum源为国内源
    • 备份原有的源文件
    • 替换国内源地址
      ## 阿里云
      sed -e 's|^mirrorlist=|#mirrorlist=|g' -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' -i.bak /etc/yum.repos.d/rocky-*.repo
      
      ## 上海交大
      sed -e 's|^mirrorlist=|#mirrorlist=|g' -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.sjtug.sjtu.edu.cn/rocky|g' -i.bak /etc/yum.repos.d/rocky-*.repo
      
    • 生成缓存
      dnf makecache
      

By anYun 2023.11.07

  • Rockylinux 安装 fping 工具
    ## 安装epel源
    dnf install -y epel*
    
    dnf install -y fping
    
  • Linux 计算命令运行时间
    ## 在命令前面加 time 命令即可
    ## 如计算 ping -c 4 180.76.76.76 的执行时间
    time ping -c 4 180.76.76.76
    

By anYun 2023.11.18


  • Linux 配置NAT转发

    • 假定:主机有网卡 enp2s0 和 网卡 enp3s0
    • 网络:enp2s0 接通外网路由器,enp3s0 连接内部私网
    ## 开启IP转发
    ## 修改 /etc/sysctl.conf 如下,如果没有就直接添加
    net.ipv4.ip_forward = 1
    
    ## 生效配置文件
    sysctl -p
    
    ## enp3s0 中网段 172.16.1.0/24 的请求转发到 enp2s0 中以便上外网
    iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -o enp2s0 -j MASQUERADE
    
    ## 保存配置
    iptables-save
    

By anYun 2023.12.02


  • 修改Linux网卡名称
    • 方式一:修改文件方式
    • 方式二:nmcli 修改
      ## 查看设备网卡设备信息
      nmcli con show 或 nmcli c s
      # NAME                     UUID                                  TYPE      DEVICE
      # Wired connection 1           e1c56527-f1e1-4d09-a936-55d030390d5d  ethernet  enp2s0
      
      ## 将 'Wired connection 1' 修改为 enp2s0,名字中有特殊字符需要进行转义
      nmcli con modify Wired\ connection\ 1 connection.id enp2s0
      

By anYun 2023.12.02


  • Linux系统下 ping 带时间戳
    • 默认Linux ping 命令是不带时间戳的(如下)
      [root@localhost ~]# ping deyun.fun
          PING deyun.fun (36.159.123.145) 56(84) bytes of data.
          64 bytes from 36.159.123.145 (36.159.123.145): icmp_seq=1 ttl=50 time=60.7 ms
      64 bytes from 36.159.123.145 (36.159.123.145): icmp_seq=2 ttl=50 time=344 ms
      64 bytes from 36.159.123.145 (36.159.123.145): icmp_seq=3 ttl=50 time=226 ms
      64 bytes from 36.159.123.145 (36.159.123.145): icmp_seq=4 ttl=50 time=102 ms
      64 bytes from 36.159.123.145 (36.159.123.145): icmp_seq=5 ttl=50 time=75.7 ms
      --- deyun.fun ping statistics ---
      5 packets transmitted, 5 received, 0% packet loss, time 4313ms
      rtt min/avg/max/mdev = 60.745/161.925/344.181/108.330 ms
      
    • 使用管道符,添加时间戳
      | xargs -I {} bash -c 'echo $(date "+%F %T") "{}"'
      
    • 示例
      [root@localhost ~]# ping iquan.fun | xargs -I {} bash -c 'echo $(date "+%F %T") "{}"'
      2024-03-01 20:03:20 PING iquan.fun (101.42.177.113) 56(84) bytes of data.
      2024-03-01 20:03:20 64 bytes from 101.42.177.113 (101.42.177.113): icmp_seq=1 ttl=45 time=191 ms
      2024-03-01 20:03:21 64 bytes from 101.42.177.113 (101.42.177.113): icmp_seq=2 ttl=45 time=255 ms
      2024-03-01 20:03:21 64 bytes from 101.42.177.113 (101.42.177.113): icmp_seq=3 ttl=45 time=159 ms
      2024-03-01 20:03:22 64 bytes from 101.42.177.113 (101.42.177.113): icmp_seq=4 ttl=45 time=159 ms
      

By anYun 2024.03.01


  • screen 工具安装
    • Debian/Ubuntu 系列
      apt-get install -y screen
      
    • Redhat/Rockylinux 系列
      ## 8系列以前
      yum install -y screen
      
      ## 8系列以后
      dnf install -y epel-release
      dnf install -y screen
      

By anYun 2024.03.15


  • 判断指定目录是否为空
    F_DIR='/var/tmp/test'
    if [ -n "$(ls -A ${F_DIR})" ];then
      ## 非空
      echo "\"${F_DIR}\" is not Empty." && return 1
    else
      ## 空
      echo "\"${F_DIR}\" is Empty" && return 0
    fi
    

By anYun 2024.04.11


  • 系统意外关机导致无法启动:Failed mount /sysroot

    • 定位问题:journalctl -xe
    • 方法一:

      • 重启服务器后,选择 CentOS Linux (0-RESCUE-xxxx)
      • 等待系统自动修复完成并重启
    • 方法二:

      • 系统默认启动后,执行如下命令

        ## 查看文件情况
        ls -lh /dev/dm*
        xfs_repair -v -L /dev/dm-0
        
        ## 或
        xfs_repail -v -L /dev/dm-1
        

      • 等待执行完成,并出现

        …… (省略前面信息)
        Formnt log to cycle xxx
        done
        

      • 重启系统reboot
    • 方法三:

      • 使用光盘启动(最好是同版本镜像)设备
      • 选择救援模式 Resue a CentOS system
      • 输入 3 进入shell界面(或 Alt + Tab
      • 执行如下命令
        ## 查看文件情况
        ls -lh /dev/dm*
        xfs_repair -v -L /dev/dm-0
        
        ## 或
        xfs_repail -v -L /dev/dm-1
        
      • 等待执行完成,并出现
        …… (省略前面信息)
        Formnt log to cycle xxx
        done
        
      • 重启系统reboot

By anYun 2024.04.13


  • sort 对IP进行排序
    • 命令格式:sort -t'.' -k1n,1 -k2n,2 -k3n,3 -k4n,4
    • 效果
      ## 源文件
      cat ip.list
      192.166.33.101
      192.166.33.11
      192.66.33.11
      192.66.3.11
      132.66.3.11
      
      ## 排序后
      cat ip.list | sort -t'.' -k1n,1 -k2n,2 -k3n,3 -k4n,4
      132.66.3.11
      192.66.3.11
      192.66.33.11
      192.166.33.11
      192.166.33.101
      

By anYun 2024.04.24


  • 没有 telnetnmapnc 情况下,如何进行端口测试tcp
    • linux 下存在一个特殊文件 /dev/tcp/host_name/PORT,允许通过该接口文件进行TCP网络通信
    • 分别测试 172.16.1.100 的 8083 端口
      ## check port 80
      if echo > /dev/tcp/172.16.1.100/80 > /dev/null 2>&1 ;then
        echo 172.16.1.100 port 80 is open
      else
        echo 172.16.1.100 port 80 is not open
      fi
      
      ## check port 83
      if echo > /dev/tcp/172.16.1.100/80 > /dev/null 2>&1 ;then
        echo 172.16.1.100 port 80 is open
      else
        echo 172.16.1.100 port 80 is not open
      fi
      

By anYun 2024.05.07


  • curl 调试一直返回 301 Moved Permanently
    • 原因:Web 站点存在重定向
    • 规避方法
      ## 简单粗暴,使用 -L 参数以便支持重定向
      curl -L 
      
      ## URL 末尾添加 /
      curl www.iquan.fun/
      
      ## URL填写完整
      curl https://iquan.fun/
      

By anYun 2024.05.08


  • date +%s 时间戳长度不够
    ## 默认 %s 是10位,需要补几位就几N
    date +%s%6N
    

By anYun 2024.05.15


  • curl 遇到302跳转以及用户密码验证401问题
    ## 302 问题
    curl -I 获取到 Location URL 信息
    
    ## 然后再用curl去验证,即可获取 200 状态
    curl --insecure --anyauth -u 账户:密码 -X GET 'Location URL' 
    

By anYun 2024.06.17


  • diff 比对两个文件差异
    ## 比对文件 file1 和 file2 的差异并格式化输出
    diff -y file1 file2
    

By anYun 2024.06.25


  • wc -l 统计行数比 cat -n 少一行
    ## wc -l 统计的行数 和 cat -n 对比少了一行
    ## 因为 wc 是统计换行 个数,当文件最后一行没有换行符时就会出现这种情况
    
    ## 解决方案,用cat -n 替换 wc -l
    ## 如获取最后一行行号
    cat -n file | tail -n 1 | awk '{print $1}'
    

By anYun 2024.06.25


  • rpm 安装报错 RSA/SHA256 Signature, key ID xxx: NOKEY
    • 安装软件A时报错如上,并且提示需要软件A,此时可以加上 --force --nodeps 参数即可跳过依赖检查而数你安装

By anYun 2024.07.30

-- grep 报错 binary file matches **.log - 这是因为文件被识别成二进制导致,加上 -a 参数即可

By anYun 2024.09.25


  • 字符串转Unicode
    • 需要for循环遍历字符串
    • 转义字符处理,如 \n\r\t
      function strs2unicode(){
        strs="${1}"
        str_unicode=''
        for (( i = 0 ; i < ${#strs} ; i++ ))
        do
          a="${strs:$i:1}"
          if [ "${a}" == '\' ];then
            i=$(( $i + 1 ))
            b="$a${strs:$i:1}"
            ## 如果不需要 \u 开头,请删除 \\u
            str_unicode+=$(printf '\\u%04x' "(printf \"${b}\")")
          else
            ## 如果不需要 \u 开头,请删除 \\u
            str_unicode+=$(printf '\\u%04x' "'${a}'")
          fi
        done
        ## 如果需要小写转换大写,请将输出语句改为 echo "${str_unicode}" | tr 'a-z' 'A-Z'
        echo "${str_unicode}"
      }
      

By anYun 2024.10.08


  1. 本文版权归IT小圈所有,受中华人民共和国相关法律保护 

  2. 任何组织和个人未经允许不得私自复制传播以及商业性分享