AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 759994
Accepted
yael
yael
Asked: 2023-10-27 19:37:36 +0800 CST2023-10-27 19:37:36 +0800 CST 2023-10-27 19:37:36 +0800 CST

linux + 通过 bash 脚本从 fstab 文件中删除未使用/不正确的 UUID 编号

  • 772

/etc/fstab我们的目标是创建 bash 脚本,从文件中删除未使用/不必要的 UUID 编号,

简要背景- 在我们的实验室中,我们有超过 500 台 RHEL 服务器,我们希望修复配置fstab不正确的文件,fstab如未使用的 UUID 编号或注释行中未使用的 UUID 编号等

我们创建以下 bash 脚本作为示例。

#!/bin/bash


blkid_list_of_uuid=` blkid | awk -F'UUID=' '{print $2}' | awk '{print $1}' | sed s'/"/ /g' `
grep UUID /etc/fstab >/tmp/fstab

while read line_from_fstab
do
        echo "checking if ${line_from_fstab} is unused UUID"
        if [[ ! ${line_from_fstab} =~ $blkid_list_of_uuid ]]
        then
           #sed -i "/$line_from_fstab/d" /etc/fstab
           echo "delete unused line ${line_from_fstab} from fstab"
        fi
done < /tmp/fstab

我们捕获了变量blkid中的数字blkid_list_of_uuid。并将 fstab 中的 UUID 行过滤到/tmp/fstab文件中

if 语法的目标 -[[ ! ${line_from_fstab} =~ $blkid_list_of_uuid ]] 是通过 sed 删除(现在在注释中)其中/etc/fstab未使用的UUID 行

但正则表达式不起作用,脚本实际上删除了正在使用的 UUID

blkid 的示例

blkid
/dev/mapper/vg-VOL_root: UUID="49232c87-6c49-411d-b744-c6c847cfd8ec" TYPE="xfs"
/dev/sda2: UUID="Y5MbyB-C5NN-hcPA-wd9R-jmdI-02ML-W9qIiu" TYPE="LVM2_member"
/dev/sda1: UUID="0d5c6164-bb9b-43f4-aa9b-092069801a1b" TYPE="xfs"
/dev/mapper/vg-VOL_swap: UUID="81140364-4b8e-412c-b909-ef0432162a45" TYPE="swap"
/dev/mapper/vg-VOL_var: UUID="e1574eeb-5a78-4a52-b7e3-c53e2b8a4220" TYPE="xfs"
/dev/sdb: UUID="547977e2-a899-4a75-a31c-e362195c264c" TYPE="ext4"
/dev/mapper/vg-VOL_docker: UUID="2e1a2cbf-9920-4e54-8b6b-86d0482c5f7b" TYPE="xfs"
/dev/sdc: UUID="1a289232-0cfe-4df7-9ad5-6a6e2362a1c5" TYPE="ext4"
/dev/sdd: UUID="91493d1f-ffe9-4f5f-aa6d-586d2c99f029" TYPE="ext4"
/dev/sde: UUID="f11845e7-1dcb-4b81-a1d4-9a5fe7da6240" TYPE="ext4"
bash
  • 4 4 个回答
  • 266 Views

4 个回答

  • Voted
  1. Best Answer
    terdon
    2023-10-27T22:04:38+08:002023-10-27T22:04:38+08:00

    它不起作用的原因是你试图匹配错误的东西。这是您的blkid变量包含的内容:

    $ printf '%s\n' "$blkid_list_of_uuid"
     49232c87-6c49-411d-b744-c6c847cfd8ec 
     Y5MbyB-C5NN-hcPA-wd9R-jmdI-02ML-W9qIiu 
     0d5c6164-bb9b-43f4-aa9b-092069801a1b 
     81140364-4b8e-412c-b909-ef0432162a45 
     e1574eeb-5a78-4a52-b7e3-c53e2b8a4220 
     547977e2-a899-4a75-a31c-e362195c264c 
     2e1a2cbf-9920-4e54-8b6b-86d0482c5f7b 
     1a289232-0cfe-4df7-9ad5-6a6e2362a1c5 
     91493d1f-ffe9-4f5f-aa6d-586d2c99f029 
     f11845e7-1dcb-4b81-a1d4-9a5fe7da6240 
    

    这意味着:

    if [[ ! ${line_from_fstab} =~ $blkid_list_of_uuid ]]
    

    变成这样:

    if [[ ! "UUID=0a3407de-014b-458b-b5c1-848e92a327a3 /     ext4   defaults  0      1" =~ " 49232c87-6c49-411d-b744-c6c847cfd8ec 
     Y5MbyB-C5NN-hcPA-wd9R-jmdI-02ML-W9qIiu 
     0d5c6164-bb9b-43f4-aa9b-092069801a1b 
     81140364-4b8e-412c-b909-ef0432162a45 
     e1574eeb-5a78-4a52-b7e3-c53e2b8a4220 
     547977e2-a899-4a75-a31c-e362195c264c 
     2e1a2cbf-9920-4e54-8b6b-86d0482c5f7b 
     1a289232-0cfe-4df7-9ad5-6a6e2362a1c5 
     91493d1f-ffe9-4f5f-aa6d-586d2c99f029 
     f11845e7-1dcb-4b81-a1d4-9a5fe7da6240 
    " ]]
    

    fstab当然,这永远不会是真的:您正在找到的 UUID 列表中搜索整行。你想做的就是寻找唯一UUID。

    不要这样做,使用其他答案中给出的方法之一,使用 shell 来做这种事情是一个坏主意,但为了完成,这里有一个主要基于 shell 的方法,使用我认为你的意思的逻辑使用(请注意,这需要 GNU grep):

    $ grep -oP '^UUID=\S+' /etc/fstab | sed 's/=/="/; s/$/"/' | 
      while read -r fstab; do 
        sudo blkid |   
          grep -q "$fstab" && 
            echo "GOOD: $fstab" || 
              echo "BAD: $fstab"; done
    BAD: UUID="e16a3de8-a58f-430f-b80f-3d87e9fb0b1d"
    BAD: UUID="ef6747e2-f802-4b18-9169-ae65f9933ef1"
    BAD: UUID="b00792c8-f7e0-4448-b98d-021eede31e6c"
    GOOD: UUID="32133dd7-9a48-4b9d-b2e0-6e383e95631d"
    GOOD: UUID="69ae5a79-9a15-489c-951d-1e0c2a16b7fc"
    GOOD: UUID="6E5E-90F0"
    GOOD: UUID="ff3c9de1-417c-4c4d-8150-a89d222ae60b"
    

    这些BAD:是我的文件中的 UUID ,但在我的系统/etc/fstab的输出中找不到。blkid

    • 3
  2. Ed Morton
    2023-10-27T21:03:10+08:002023-10-27T21:03:10+08:00

    没有示例输入和预期输出,这是一个未经测试的猜测,但我认为这就是你想要的,使用任何 awk:

    #!/usr/bin/env bash
    
    tmp=$(mktemp) || exit 1
    trap 'rm -f "$tmp"; exit' EXIT
    
    blkid |
    awk '
        NR == FNR {
            gsub(/"/,"",$2)
            blkids[$2]
            next
        }
        !/^UUID/ || ($1 in blkids)
    ' - /etc/fstab > "$tmp" &&
    mv -- "$tmp" /etc/fstab
    

    上面假设输出格式如https://linux.101hacks.com/unix/blkidblkid所示:

    /dev/sdb1: UUID="6e0acfe3-81ed-4f9f-8ab5-0d65ba1f0ef2" TYPE="ext2"
    /dev/sdc1: UUID="aa82d7bb-ab2b-4739-935f-fd8a5c9a6cb0" TYPE="ext2"
    /dev/sda1: UUID="187171ab-c9b8-43ec-b0bb-77c736ca22e0" TYPE="ext4" LABEL="/home"
    /dev/sda2: UUID="1a225baa-7027-4619-aaa5-900e24c1fdff" TYPE="swap"
    /dev/sdb3: UUID="2a294b33-eb61-40a3-b3fc-ad6eaf7f156f" TYPE="ext2"
    

    内容格式如https://wiki.archlinux.org/title/fstab/etc/fstab所示:

    # <device>                                <dir> <type> <options> <dump> <fsck>
    UUID=0a3407de-014b-458b-b5c1-848e92a327a3 /     ext4   defaults  0      1
    UUID=f9fe0b69-a280-415d-a03a-a32752370dee none  swap   defaults  0      0
    UUID=b411dc99-f0a0-4c87-9e05-184977be8539 /home ext4   defaults  0      2
    

    通过快速谷歌搜索发现。

    • 2
  3. Archemar
    2023-10-27T20:45:03+08:002023-10-27T20:45:03+08:00

    我不确定您是否可以使用 uuid 列表作为正则表达式。

    为了得到我用过的这个列表

    blkid | awk -F\" '{for(i=1;i<=NF;i++) if ($i ~ / UUID=/ ) { i++; print $i ; break ; }  }'
    

    在哪里

    • -F\"用作"分隔符
    • for(i=1;i<=NF;i++)走线
    • if ($i ~ / UUID=/ )如果找到 UUID=(space在 UUID 为强制之前)...
    • { i++ ; print $i ; break ; } }'.. 获取下一个字段(实际的 UUID)并打印它,退出循环。

    接下来我使用普通的grep

    if ! echo "${blkid_list_of_uuid}" | grep ${line_from_fstab}
    

    (可以用来grep -q减少垃圾)

    这导致

    blkid_list_of_uuid=$(blkid | awk -F\" '{for(i=1;i<=NF;i++) if ($i ~ / UUID=/ ) { i++ ; print $i ; break ; } }' )
    grep UUID /etc/fstab >/tmp/fstab
    while read line_from_fstab
    do
            echo "checking if ${line_from_fstab} is unused UUID"
            if ! echo "${blkid_list_of_uuid}" | grep ${line_from_fstab}
            then
               #sed -i "/$line_from_fstab/d" /etc/fstab
               echo "delete unused line ${line_from_fstab} from fstab"
            fi
    done < /tmp/fstab
    

    • 很少需要管道两个awk和一个sed

    • blkid_list_of_uuid 也可以存储在临时文件中,从而导致

       grep -q ${line_from_fstab} /tmp/blkid_list_of_uuid
      

      (不会工作,因为${line_from_fstab}不是 uuid)

    • 正如所指出的,从长远来看,在 500 个虚拟机中部署和运行 bash 脚本可能不是一个好主意,我会考虑 ansible。

    • 1
  4. JoL
    2023-10-28T06:32:43+08:002023-10-28T06:32:43+08:00

    terdon 回答了你做错了什么。我将仅提供一个更简单的方法的示例来完成您尝试的操作:

    lsblk -no uuid | grep . | grep -Ff- /etc/fstab 
    

    这应该按照您想要的方式输出 fstab,区别在于它不会像正则表达式或潜在sed命令那样对待 UUID。您可以将输出定向到/tmp/fstab然后将其移动到/etc/fstab。

    我使用了lsblknot ,blkid因为联机帮助页blkid建议lsblk改为,并且lsblk不需要 root 权限,而blkid显然需要 root 权限。

    • 0

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve