/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
awk
2개와 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
.
맨페이지에서 대신 제안했기 때문에 lsblk
not 을 사용했으며 분명히 루트 권한이 필요하지 않았습니다 .blkid
blkid
lsblk
lsblk
blkid