findmnt 결과 목록에서 바인드 마운트를 제외하는 방법은 무엇입니까?

findmnt 결과 목록에서 바인드 마운트를 제외하는 방법은 무엇입니까?

Bash 스크립트에는 다음 줄이 있습니다.

TARGETS="$(findmnt -n -v -t btrfs -o TARGET --list)"
UUIDS="$(findmnt -n -v -t btrfs -o UUID --list)"

저는 일부 서버(Arch Linux 실행)에서 이 스크립트를 실행하고 있습니다. 그러나 NFS 서버에서는 실패합니다. 이 경우 findmnt는 다음을 반환합니다.다중 마운트 지점특정 UUID에 대해(NFS 서버의 바인드 마운트로 인해) ㅏ필요하다내 스크립트의 최종 결과는 목록을 얻는 것입니다.UUID당 하나의 마운트 지점.

여기서 정말 좋은 답을 찾았습니다("흥미로운" 마운트 지점만 표시/재미없는 유형 필터링) 거기에서 논의된 모든 제안을 시도했지만 주어진 UUID에 대해 여러 마운트 지점을 반환하는 findmnt를 제거할 수 없습니다. 문제가 바인드 마운트에 의해서만 발생하는 중복으로 범위가 좁혀졌음에도 불구하고 말입니다. (내가 놓친 게 무엇입니까?)

임시 해결 방법으로 표시하고 싶은 설치만 포함하는 제한된 탭 파일을 만든 다음 -Ffindmnt의 옵션을 사용했습니다. 내 사용자 정의 탭 파일은 모든 바인드 마운트가 제거된 fstab의 복사본입니다.

TARGETS="$(findmnt -n -v -t btrfs -o TARGET --list -F /etc/fstab.custom)"
UUIDS="$(findmnt -n -v -t btrfs -o UUID --list -F /etc/fstab.custom)"

분명히 이것은 /etc/fstab에 변경 사항이 적용되고 내 사용자 정의 탭 파일이 수동으로 업데이트되지 않으면 깨지기 쉬운 접근 방식입니다. (또한 사용자 정의 파일의 중복을 유발하는 일부 비번들 설치를 수동으로 제거해야 했기 때문에 현 단계에서는 확실히 신뢰할 수 있는 솔루션이 아닙니다.)

원하는 결과를 얻는 더 좋은 방법이 있습니까? 나는 이것을 상상할 수 있다가능한이 문제는 findmnt 필터를 사용하거나 findmnt에서 반환된 목록에 적용된 외부 필터를 사용하여 해결할 수 있습니다.

모든 바인드 마운트는 "/srv/nfs/"로 시작합니다. 이를 목록에서 필터링하는 것은 좋은 시작이 될 것입니다. 그러나 이는 다소 취약한 솔루션으로 생각되기도 합니다(언젠가 누군가가 NFS 바인드 마운트가 서버에서 구성되는 방식을 변경하기로 결정할 수 있기 때문입니다).

또한 저는 bash나 awk에 능숙하지 않으며 findmnt에서 반환된 결과를 후처리하는 적절한 방법을 모릅니다. 나는 그것에 대해 생각했다 :

findmnt -n -t btrfs -o UUID,TARGET --list | grep -v -E "/srv/nfs|.tapp|/var/log"

그러나 이것은 경로 이름을 변경하면 깨지기 때문에 사용자 정의 탭 파일만큼 취약한 것 같습니다.

findmnt -n -t btrfs -o UUID,TARGET --list다음은 내 시스템 중 하나가 반환하는 내용의 예입니다(마운트 지점이 단순화됨).

473c1g34-23ec-41dd-671f-c71473ad7d36 /
473c1g34-23ec-41dd-671f-c71473ad7d36 /srv/nfs/foo/wunder
473c1g34-23ec-41dd-671f-c71473ad7d36 /srv/nfs/foo/tinder
473c1g34-23ec-41dd-671f-c71473ad7d36 /.tapp
473c1g34-23ec-41dd-671f-c71473ad7d36 /var/log
473c1g34-23ec-41dd-671f-c71473ad7d36 /var/log/.tapp
13f4361e-771e-44b3-7413-a613bf4e331b /bar
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user1/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user6/Desktop
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user3/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user4/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user5/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /srv/nfs/bar/user6/Documents
13f4361e-771e-44b3-7413-a613bf4e331b /bar/.tapp
3ac663cc-e7e4-4764-7a7a-1d3fa16b376b /foo/files
3ac663cc-e7e4-4764-7a7a-1d3fa16b376b /srv/nfs/foo/files
4c61646e-1a1d-4d67-7d47-1446e41d6341 /bar/baz
4c61646e-1a1d-4d67-7d47-1446e41d6341 /srv/nfs/bar/baz/goop/stuff
4c61646e-1a1d-4d67-7d47-1446e41d6341 /srv/nfs/bar/baz/goop/widgets
4c61646e-1a1d-4d67-7d47-1446e41d6341 /srv/nfs/bar/baz/pie
4c61646e-1a1d-4d67-7d47-1446e41d6341 /srv/nfs/bar/baz/goop/gadgets
4c61646e-1a1d-4d67-7d47-1446e41d6341 /bar/baz/.tapp

모든 nfs 바인드 마운트(/srv/nfs로 시작하는 마운트)와 /.tapp 및 /var/log를 포함하는 모든 마운트 지점을 필터링해야 합니다. findmnt 옵션을 사용하여 이를 수행할 수 있는 방법이 있습니까? 그렇지 않다면 bash에서 어떻게 해야 할까요?

고쳐 쓰다: 질문에 집중하기 위해 findmnt 결과 목록에서 바인드 마운트를 제외하는 방법이 있어서 기쁩니다. 답변을 제공하기 위해 /var/log에 의해 생성된 것과 같은 다른 중복 마운트 지점을 무시해도 됩니다.

업데이트 2: json 형식의 findmnt 출력 예시입니다. 보존하려는 출력에서 ​​바인드 마운트와 바인드 마운트(/foo/files)를 구별하는 방법을 찾지 못했습니다.

{"target": "/srv/nfs/bar/user1/Documents", "uuid": "13f4361e-771e-44b3-7413-a613bf4e331b"},
{"target": "/srv/nfs/home/user5/Desktop", "uuid": "13f4361e-771e-44b3-7413-a613bf4e331b"},
{"target": "/srv/nfs/home/user3/Documents", "uuid": "13f4361e-771e-44b3-7413-a613bf4e331b"},
{"target": "/srv/nfs/home/user4/Documents", "uuid": "13f4361e-771e-44b3-7413-a613bf4e331b"},
{"target": "/foo/files", "uuid": "3ac663cc-e7e4-4764-7a7a-1d3fa16b376b"},

답변1

~에서번들 마운트만 나열, 바인드 마운트는 마운트 후 원래 마운트와 구별이 안되는 것 같습니다. 부분 바인딩(마운트 지점의 하위 디렉터리에 어딘가에 마운트 바인딩이 있음)이 출력에 다르게 표시되는 반면 findmnt, 다른 곳에 마운트 바인딩이 있는 마운트 지점을 구별할 수 있는 방법은 없습니다.

그렇다면 다음과 같이 하세요.

sudo mount -o bind / /srv
sudo mount -o bind /media /mnt

/와 의 설치 정보는 구별할 수 없지만 와 /srv는 구별할 수 있을 것 같습니다 ./media/mnt

따라서 남은 것은 단순히 중복된 항목을 제거하는 것입니다 findmnt.

findmnt -n -t btrfs -o UUID,TARGET -r | awk '!a[$1]++'

-r대신 이 옵션을 사용하면 -l출력에서 ​​특수 문자를 이스케이프 처리하여 경로를 안전하게 처리할 수 있습니다.

$ findmnt -n -t ext4 -o UUID,TARGET -r
d4873b63-0956-42a7-9dcf-bd64e495a9ff /
..
d4873b63-0956-42a7-9dcf-bd64e495a9ff /srv/media
d4873b63-0956-42a7-9dcf-bd64e495a9ff /a\x20b
d4873b63-0956-42a7-9dcf-bd64e495a9ff /srv/a\x20b

여기서는 a b로 이스케이프됩니다 a\x20b. printf "%b"다음을 사용하여 bash에서 이스케이프 문자를 확장 할 수 있습니다 .

$ findmnt -n -t ext4 -o UUID,TARGET -r | bash -c 'while read -r uuid point; do printf "%b\n" "$point"; done'
/
...
/srv/media
/srv/a b
/a b
/srv/a b

관련 정보