linux + bash 스크립트를 통해 fstab 파일에서 사용되지 않거나 잘못된 UUID 번호를 제거합니다.

linux + bash 스크립트를 통해 fstab 파일에서 사용되지 않거나 잘못된 UUID 번호를 제거합니다.

/etc/fstab우리의 목표는 파일에서 사용되지 않거나 불필요한 UUID 번호를 제거하는 bash 스크립트를 만드는 것입니다.

간단한 배경- 우리 연구실에는 500개 이상의 RHEL 서버가 있으며 사용되지 않은 UUID 번호 또는 주석 줄의 사용되지 않은 UUID 번호 등과 같이 fstab잘못된 구성이 있는 파일을 수정하려고 합니다.fstab

예제로 다음 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 구문의 목표는 sed를 통해 사용되지 않은 UUID 행을 [[ ! ${line_from_fstab} =~ $blkid_list_of_uuid ]] 제거하는 것입니다(현재 주석에서)./etc/fstab

하지만 정규식은 작동하지 않습니다. 스크립트는 실제로 사용 중인 UUID를 제거합니다.

블키드의 예

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"

답변1

작동하지 않는 이유는 잘못된 것을 일치시키려고 하기 때문입니다. 변수에 포함된 내용은 다음과 같습니다 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 목록에서 전체 행을 검색하고 있습니다. 당신이 원하는 것은 One 을 찾는 것뿐입니다 UUID.

이렇게하지 마십시오. 다른 답변에 제공된 방법 중 하나를 사용하여 쉘을 사용하여 이러한 작업을 처리하십시오.나쁜 생각이야, 그러나 완전성을 기하기 위해 여기에 사용하려는 논리를 사용하는 대부분의 쉘 기반 접근 방식이 있습니다(여기에는 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

답변2

예제 입력과 예상 출력이 없으면 이는 테스트되지 않은 추측이지만 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

위의 blkid출력 형식은 다음과 같다고 가정합니다.https://linux.101hacks.com/unix/blkid:

/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"

/etc/fstab내용 형식은 다음과 같습니다https://wiki.archlinux.org/title/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

구글 검색으로 빠르게 알아냈습니다.

답변3

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=가 발견된 경우( spaceUUID가 필수이기 전에)...
  • { 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

  • awk2개와 1개를 파이프로 연결하는 경우는 거의 없습니다.sed

  • blkid_list_of_uuid는 임시 파일에 저장될 수도 있습니다.

     grep -q ${line_from_fstab} /tmp/blkid_list_of_uuid
    

    (uuid가 아니기 때문에 작동하지 않습니다 ${line_from_fstab})

  • 지적한 바와 같이, 500개의 가상 머신에 bash 스크립트를 배포하고 실행하는 것은 아마도 장기적으로 좋은 생각이 아닐 것입니다. 저는 ansible을 고려하고 싶습니다.

답변4

terdon이 대답했습니다. 무엇을 잘못하고 있습니까? 수행하려는 작업을 수행하는 더 간단한 방법의 예를 제공하겠습니다.

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

이렇게 하면 fstab이 원하는 방식으로 출력됩니다. 차이점은 UUID를 정규식이나 잠재적인 sed명령처럼 처리하지 않는다는 것입니다. 출력을 로 보낸 /tmp/fstab다음 으로 이동할 수 있습니다 /etc/fstab.

맨페이지에서 대신 제안했기 때문에 lsblknot 을 사용했으며 분명히 루트 권한이 필요하지 않았습니다 .blkidblkidlsblklsblkblkid

관련 정보