Câu trả lời:
Gắn kết ràng buộc không phải là một loại hệ thống tập tin, cũng không phải là một tham số của hệ thống tập tin gắn kết; chúng là các tham số của hoạt động gắn kết . Theo như tôi biết, các chuỗi lệnh sau đây dẫn đến các trạng thái hệ thống cơ bản giống hệt như liên quan đến kernel:
mount /dev/foo /mnt/one; mount --bind /mnt/one /mnt/two
mount /dev/foo /mnt/two; mount --bind /mnt/two /mnt/one
Vì vậy, cách duy nhất để nhớ những gì gắn kết được gắn kết gắn kết là nhật ký của mount
các lệnh còn lại /etc/mtab
. Một hoạt động gắn kết liên kết được chỉ định bởi tùy chọnbind
gắn kết (làm cho loại hệ thống tập tin bị bỏ qua). Nhưng không có tùy chọn để liệt kê chỉ các hệ thống tập tin được gắn với một bộ tùy chọn cụ thể. Do đó bạn cần phải tự lọc.mount
mount | grep -E '[,(]bind[,)]'
</etc/mtab awk '$4 ~ /(^|,)bind(,|$)/'
Lưu ý rằng /etc/mtab
chỉ hữu ích ở đây nếu đó là tệp văn bản được duy trì bởi mount
. Một số bản phân phối được thiết lập /etc/mtab
như một liên kết tượng trưng để /proc/mounts
thay thế; /proc/mounts
hầu hết tương đương với /etc/mtab
nhưng có một vài điểm khác biệt, một trong số đó là không theo dõi các liên kết gắn kết.
Một phần thông tin được giữ lại bởi kernel, nhưng không được hiển thị trong đó /proc/mounts
là khi điểm gắn kết chỉ hiển thị một phần của cây thư mục trên hệ thống tập tin được gắn kết. Trong thực tế, điều này chủ yếu xảy ra với các liên kết gắn kết:
mount --bind /mnt/one/sub /mnt/partial
Trong /proc/mounts
, các mục nhập cho /mnt/one
và /mnt/partial
có cùng một thiết bị, cùng loại hệ thống tệp và cùng tùy chọn. Thông tin /mnt/partial
chỉ hiển thị một phần của hệ thống tập tin gốc /sub
được hiển thị trong thông tin điểm gắn trên mỗi quy trình trong /proc/$pid/mountinfo
(cột 4). Các mục ở đó trông như thế này:
12 34 56:78 / /mnt/one rw,relatime - ext3 /dev/foo rw,errors=remount-ro,data=ordered
12 34 56:78 /sub /mnt/partial rw,relatime - ext3 /dev/foo rw,errors=remount-ro,data=ordered
mount --version
đang sử dụng bản ghi đó có bind
thông tin /etc/mtab
gì không? Tôi đang sử dụng phiên bản 2.20.1 và tôi đã xem các nguồn mới nhất và trong mọi trường hợp tôi không thấy thông tin ràng buộc được ghi lại ở bất cứ đâu cho phép bạn grep for bind
. Mặt khác, những gì tôi đề xuất trong câu trả lời của mình thực tế lại liệt kê các liên kết gắn kết được tạo ra --bind
cũng như sử dụng bind
tùy chọn .
</etc/mtab awk …
tuân thủ POSIX (Tôi quên liệu nó có được hỗ trợ trong Bourne không). Vui lòng kiểm tra sự thật của bạn. Tôi có thể xác nhận rằng /etc/mtab
có bind
tùy chọn cho một hệ thống tập tin được gắn kết với mount --bind /source /target
Debian ổn định (mount từ produc-linux-ng 2.17.2).
mount
và /etc/mtab
. Bạn đang sử dụng Debian ổn định có phiên bản cũ hơn của linux-linux-ng; Tôi đang sử dụng thử nghiệm Debian có phiên bản mới hơn dường như không còn /etc/mtab
hành vi tương tự , đó có thể là lý do tại sao @rozcietrzewiacz không thấy bind
trong /etc/mtab
bản phân phối của mình cũng sử dụng phiên bản mới hơn?
findmnt
như một câu trả lời. Nó chỉ hoạt động nếu thư mục đích không phải là một điểm gắn kết khác. Hãy thử ví dụsudo mount --bind / foo && findmnt | grep foo
Có lẽ điều này có thể làm được mẹo:
findmnt | grep "\["
Thí dụ:
$ mkdir /tmp/foo
$ sudo mount --bind /media/ /tmp/foo
$ findmnt | grep "\["
│ └─/tmp/foo /dev/sda2[/media] ext4 rw,relatime,data=ordered
/
bản thân nó được gắn kết, ví dụ, đầu ra không có a [...]
.
Hạt nhân không xử lý các liên kết gắn kết khác với các gắn kết thông thường sau khi thực tế. Chỉ khác nhau trong những gì xảy ra trong khi mount
chạy.
Khi bạn gắn kết một hệ thống tệp (ví dụ: với mount -t ext4 /dev/sda1 /mnt
), hạt nhân (được đơn giản hóa một chút) thực hiện ba bước:
-t
hoặc sử dụng loại -t auto
mount
đoán cho bạn và cung cấp loại đã đoán cho hạt nhân)nodev
ví dụ: là một tùy chọn trên mountpoint, không phải trên hệ thống tập tin. Bạn có thể có một mount liên kết với nodev
và không có)Nếu bạn thực hiện gắn kết liên kết (ví dụ: với mount --bind /a /b
), điều sau đây xảy ra:
(Tôi sẽ bỏ qua mount --move
, vì nó không liên quan đến câu hỏi.)
Điều này khá giống với cách các tệp được tạo trên Linux:
Nếu bạn tạo một liên kết cứng, điều sau đây sẽ xảy ra:
Như bạn có thể thấy, tệp được tạo và liên kết cứng không thể phân biệt được:
$ touch first
$ ln first second
$ ls -li
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/first
1184243 -rw-rw-r-- 2 cg909 cg909 0 Feb 20 23:56 /tmp/second
Nhưng , vì bạn có thể xác định tất cả các liên kết cứng với một tệp bằng cách so sánh các số inode, bạn có thể xác định tất cả các gắn kết với một hệ thống tệp bằng cách so sánh chính: số phụ gắn kết.
Bạn có thể làm điều này với findmnt -o TARGET,MAJ:MIN
hoặc bằng cách trực tiếp xem /proc/self/mountinfo
( xem tài liệu nhân Linux để biết thêm thông tin ).
Tập lệnh Python sau liệt kê tất cả các liên kết gắn kết. Nó giả định rằng điểm gắn kết cũ nhất có đường dẫn tương đối ngắn nhất đến thư mục gốc của hệ thống tệp được gắn kết là giá trị gốc.
#!/usr/bin/python3
import os.path, re
from collections import namedtuple
MountInfo = namedtuple('MountInfo', ['mountid', 'parentid', 'devid', 'root', 'mountpoint', 'mountoptions', 'extra', 'fstype', 'source', 'fsoptions'])
mounts = {}
def unescape(string):
return re.sub(r'\\([0-7]{3})', (lambda m: chr(int(m.group(1), 8))), string)
with open('/proc/self/mountinfo', 'r') as f:
for line in f:
# Parse line
mid, pid, devid, root, mp, mopt, *tail = line.rstrip().split(' ')
extra = []
for item in tail:
if item != '-':
extra.append(item)
else:
break
fstype, src, fsopt = tail[len(extra)+1:]
# Save mount info
mount = MountInfo(int(mid), int(pid), devid, unescape(root), unescape(mp), mopt, extra, fstype, unescape(src), fsopt)
mounts.setdefault(devid, []).append(mount)
for devid, mnts in mounts.items():
# Skip single mounts
if len(mnts) <= 1:
continue
# Sort list to get the first mount of the device's root dir (if still mounted)
mnts.sort(key=lambda x: x.root)
src, *binds = mnts
# Print bind mounts
for bindmount in binds:
if src.root == bindmount.root:
srcstring = src.mountpoint
else:
srcstring = src.mountpoint+':/'+os.path.relpath(bindmount.root, src.root)
print('{0} -> {1.mountpoint} ({1.mountoptions})'.format(srcstring, bindmount))
unset DONE1FSES
FSES=$(findmnt -vUPno SOURCE,FSROOT,TARGET,MAJ:MIN)
FSES=${FSES//MAJ:MIN/MAJ_MIN}
while read SEARCH1FS
do
unset DONE2FSES
eval "$SEARCH1FS"
SEARCH1SOURCE=$SOURCE
SEARCH1FSROOT=$FSROOT
SEARCH1TARGET=$TARGET
SEARCH1MAJMIN=$MAJ_MIN
FS1WASHANDLED=0
while read DONE1FS
do
if [[ $DONE1FS == $MAJ_MIN ]]
then
FS1WASHANDLED=1
break
fi
done < <(echo "$DONE1FSES")
if [[ ($SEARCH1FSROOT == /) && ($FS1WASHANDLED == 0) ]]
then
DONE1FSES+=$MAJ_MIN$'\n'
while read SEARCH2FS
do
eval "$SEARCH2FS"
SEARCH2SOURCE=$SOURCE
SEARCH2FSROOT=$FSROOT
SEARCH2TARGET=$TARGET
SEARCH2MAJMIN=$MAJ_MIN
FS2WASHANDLED=0
while read DONE2FS
do
if [[ $DONE2FS == $SEARCH2FS ]]
then
FS2WASHANDLED=1
break
fi
done < <(echo "$DONE2FSES")
if [[ ($SEARCH1MAJMIN == $SEARCH2MAJMIN) && ($SEARCH1TARGET != $SEARCH2TARGET ) && ($FS2WASHANDLED == 0 ) ]]
then
DONE2FSES+=$SEARCH2FS$'\n'
echo "$SEARCH1TARGET$SEARCH2FSROOT --> $SEARCH2TARGET"
fi
done < <(echo "$FSES")
fi
done < <(echo "$FSES")
Điều này tương tự như câu trả lời findmnt khác, nhưng tránh vấn đề định dạng.
Để hiển thị tất cả các mục con:
findmnt --kernel -n --list | grep '\['
Để hiển thị tất cả các phần phụ của hệ thống tập tin kiểu ext4:
findmnt --kernel -t ext4 -n --list | grep '\['
Để hiển thị tất cả các mount không bao gồm các phần phụ:
findmnt --kernel -n --list | grep -v '\['
Để hiển thị tất cả các hệ thống tập tin kiểu ext4 không bao gồm các phần phụ:
findmnt --kernel -t ext4 -n --list | grep -v '\['
"-N" xóa các tiêu đề và "--list" sẽ xóa các dòng của định dạng "cây".
Đã thử nghiệm trên Debian.
findmnt | fgrep [
như được giải thích ở đây .