sed: /etc/fstab의 항목 교체

sed: /etc/fstab의 항목 교체

저는 우리 시스템 중 일부를 강화하고 있습니다. 강화 프로세스의 일환으로 특정 파티션의 기능을 제한하기 위해 /etc/fstab의 일부 항목을 업데이트해야 했습니다.

그렇긴 하지만, sed 인라인 대체를 사용하여 행을 업데이트할 수 있기를 바랍니다. 다음은 /etc/fstab의 현재 조각입니다:

# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root /                       ext4    defaults        1 1
/dev/mapper/vg1-lv_home /home                   ext4    defaults        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0

sed 명령을 실행한 후 파일이 다음과 같기를 원합니다.

# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root /                       ext4    defaults        1 1
/dev/mapper/vg1-lv_home /home                   ext4    defaults,nodev        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0

기본적으로 ext[2-4]의 모든 줄(루트 파티션 아님)에 "nodev"를 추가해야 합니다.

내가 구성한 sed 명령은 거의 이 작업을 수행했지만 어떤 이유로든 "/" 파티션과 일치하지 않는 정규식을 얻을 수 없으므로 항상 해당 줄도 업데이트됩니다.

sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab

vg1-lv_root가 아닌 공백으로 둘러싸인 "/"를 닫고 싶습니다. 다음은 작동하지만 이 솔루션은 투박하기 때문에 마음에 들지 않습니다.

sed '/^[^#].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab | sed '/^[^#].*root.*ext[2-4]/s/defaults,nodev/defaults/' > /etc/fstab

답변1

awk추가 논리를 사용하여 문자열을 추가하고 column최종 출력 파일의 형식을 다시 지정할 수 있습니다. /etc//tmp/폴더 에 대한 쓰기 권한이 있다고 가정

tempfile=$(mktemp /tmp/tmpfile.XXXXXXXX)

/tmp/awk이렇게 하면 출력을 기록 하고 원본 파일로 다시 리디렉션 할 수 있는 경로에 임시 파일이 생성됩니다.

awk '$3 ~ "ext[2-4]"{ $4=$4",nodev" }1 ' /etc/fstab | column -t > "$tempfile" && mv -- "$tempfile" /etc/fstab

해당 column -t부분은 단지 중복되며 출력 파일을 정리되지 않고 부피가 커지게 만드는 대신 더 읽기 쉽게 만드는 데 필요합니다.

답변2

더 간단한 방법은 다음과 같습니다 sed.

$ sed -E 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab 
# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root /                       ext4    defaults        1 1
/dev/mapper/vg1-lv_home /home                   ext4    defaults,nodev        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0

비결은 공백 뒤에 a /와 하나 이상의 공백이 아닌 문자( \s/\S+) 가 오는 경우를 찾은 ext[2-4]다음 앞에 공백( \s+ext[2-4]), 추가 공백 및 가 있는 경우를 찾는 것입니다 defaults. 이는 귀하가 관심 있는 사례와만 일치해야 합니다. 따라서 일치하는 항목이 있으면 전체 일치 항목을 자체 플러스 nodev: 로 바꾸세요 \1,nodev.

다만 휴대성이 얼마나 좋은지는 잘 모르겠습니다. -E많은 구현에서는 확장 정규식을 지원 sed하지만 POSIX는 아닙니다. 보다 이식성 있는 접근 방식을 위해 Perl에서 동일한 아이디어를 시도해 볼 수 있습니다.

$ perl -pe 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab 
# /etc/fstab
# Created by anaconda on Wed Feb 21 09:37:23 2018
/dev/mapper/vg1-lv_root /                       ext4    defaults        1 1
/dev/mapper/vg1-lv_home /home                   ext4    defaults,nodev        1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0

두 경우 모두 파일을 제자리에서 편집하려면 다음을 사용하십시오 -i.

perl -i -pe 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab 
sed -E 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab 

또는 BSD 또는 OSX의 경우 sed:

sed -i '' -E 's|(\s/\S+\s+ext[2-4]\s+defaults)|\1,nodev|' fstab 

위의 내용에서는 이 defaults옵션이 유일한 옵션이거나 적어도 마지막 옵션이라고 가정합니다. 그런 게 있었다면 실패했을 거예요 nodev,defaults.

답변3

물론 질문을 게시한 지 10분 후에 마침내 다음 명령을 사용하여 내가 원하는 작업을 수행할 수 있었습니다.

sed -r '/^[^#].*[ \t]+\/[^[:space:]].*ext[2-4]/s/defaults/defaults,nodev/g' /etc/fstab

누구든지 더 명확하거나 간단한 답변을 갖고 있다면 듣고 싶습니다. 감사해요!

답변4

제외된 경기는 유지 관리가 어렵습니다. 원하는 파티션만 일치시키는 것이 더 안전합니다. 그리고 한 줄만 일치하는 경우에는 뒤에 "g"가 필요하지 않습니다.

sed -r 's#(/home\s.*defaults)\s#\1,nodev #' /etc/fstab 

관련 정보