Czy istnieje polecenie sprawdzające, gdzie jest zamontowany dysk?

29

Czy istnieje proste polecenie, które pobiera węzeł urządzenia dysku jako dane wejściowe i mówi mi, gdzie (i czy) ten dysk jest podłączony? Czy można uzyskać punkt montowania sam, więc mogę przekazać go do innego polecenia?

Pracuję na systemie Debian Squeeze na żywo z minimalną instalacją (w razie potrzeby mogę zainstalować dodatkowe pakiety).

obrzydliwie
źródło

Odpowiedzi:

14

W systemie Linux informacje o punkcie montowania można uzyskać bezpośrednio z jądra /proc/mounts. mountProgram zapisuje informacje w podobny /etc/mtab. Ścieżki i opcje mogą być różne, ponieważ /etc/mtabreprezentuje to, co mountprzekazano do jądra, podczas gdy /proc/mountspokazuje dane widoczne w jądrze. /proc/mountsjest zawsze aktualny, /etc/mtabale może nie być, jeśli /etcbył tylko do odczytu w pewnym momencie, którego nie spodziewali się skrypty rozruchowe. Format jest podobny do /etc/fstab.

W obu plikach pierwsze pole oddzielone spacjami zawiera ścieżkę urządzenia, a drugie pole zawiera punkt podłączenia.

awk -v needle="$device_path" '$1==needle {print $2}' /proc/mounts

lub jeśli nie masz awk:

grep "^$device_path " /proc/mounts | cut -d ' ' -f 2

Istnieje wiele przypadków, w których możesz nie otrzymać tego, czego oczekujesz. Jeśli urządzenie zostało zamontowane inną ścieżką /devoznaczającą to samo urządzenie, nie zauważysz tego w ten sposób. W /proc/mountsoprawach bindowania nie można odróżnić od oryginału. Może być więcej niż jedno dopasowanie, jeśli punkt montowania ocienia inny (jest to niezwykłe).

W /proc/selflub /proc/$pidznajduje się mountsplik na proces , który naśladuje plik globalny. Informacje o podłączeniu mogą się różnić między procesami, na przykład z powodu chroot. Istnieje dodatkowy plik o nazwie, mountinfoktóry ma inny format i zawiera więcej informacji, w szczególności numery główne i podrzędne urządzenia. Z dokumentacji :

36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
(1)(2)(3)   (4)   (5)      (6)      (7)   (8) (9)   (10)         (11)

(1) mount ID:  unique identifier of the mount (may be reused after umount)
(2) parent ID:  ID of parent (or of self for the top of the mount tree)
(3) major:minor:  value of st_dev for files on filesystem
(4) root:  root of the mount within the filesystem
(5) mount point:  mount point relative to the process's root
(6) mount options:  per mount options
(7) optional fields:  zero or more fields of the form "tag[:value]"
(8) separator:  marks the end of the optional fields
(9) filesystem type:  name of filesystem of the form "type[.subtype]"
(10) mount source:  filesystem specific information or "none"
(11) super options:  per super block options

Jeśli więc szukasz urządzenia według numeru, możesz to zrobić w następujący sposób:

awk -v dev="$major:minor" '$3==dev {print $5}'
awk -v dev="$(stat -L -c %t:%T /dev/block/something)" '$3==dev {print $5}'
Gilles „SO- przestań być zły”
źródło
„Jeśli urządzenie zostało zamontowane inną ścieżką w / dev, która oznacza to samo urządzenie, nie zauważysz tego w ten sposób”. - Tak jest w rzeczywistości: mam udisksdowiązanie symboliczne (w / dev / disk / by-label / ...). Ale mogę rozwiązać do węzła urządzenia za pomocą readlink -f. Podoba mi się ten /proc/mountspomysł, myślę, że może być nieco bardziej niezawodny niż /etc/mtab.
detly
@detly Lub możesz użyć mountinfo. Zadzwoń, stataby uzyskać numery urządzeń (zobacz moją zaktualizowaną odpowiedź, zapomniałem wcześniej podać polecenie).
Gilles 'SO - przestań być zły'
Może być potrzebna -d " "opcja dla cuttego greppolecenia.
Craig McQueen,
26

W systemie Linux możesz teraz użyć findmntpolecenia z util-linux(od wersji 2.18):

$ findmnt -S /dev/VG_SC/home
TARGET SOURCE                 FSTYPE OPTIONS
/home  /dev/mapper/VG_SC-home ext4   rw,relatime,errors=remount-ro,data=ordered

Lub lsblk(również od util-linux, od 2.19):

$ lsblk /dev/VG_SC/home
NAME       MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
VG_SC-home 254:2    0  200G  0 lvm  /home

Ten jest także przydatny do znalezienia całego systemu plików zamontowanego na określonym urządzeniu (dysku lub partycji ...):

$ lsblk  /dev/sda2
NAME                    MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda2                      8:2    0  59.5G  0 part
├─linux-debian64 (dm-1) 252:1    0    15G  0 lvm
└─linux-mint (dm-2)     252:2    0    15G  0 lvm  /

Aby uzyskać tylko punkt montowania:

$ findmnt -nr -o target -S /dev/storage/home
/home
$ lsblk -o MOUNTPOINT -nr /dev/storage/home
/home

Powyższe findmntpowraca ze statusem wyjścia z awarii, jeśli urządzenie nie jest zamontowane, nie lsblk.

Więc:

if mountpoint=$(findmnt -nr -o target -S "$device"); then
  printf '"%s" is mounted on "%s"\n' "$device" "$mountpoint"
else
  printf '"%s" does not appear to be directly mounted\n' "$device"
fi
Stéphane Chazelas
źródło
Zawsze dobrze jest nauczyć się czegoś nowego
roaima
6

mountPolecenia bez argumentów spowoduje wyświetlenie wszystkich aktualnie zamontowanych systemów plików; możesz to zrobić grepdla dysku, który chcesz (lub grep /etc/mtab, który jest plik mountodczytuje informacje z):

$ grep /dev/sda /etc/mtab
/dev/sda3 /boot ext2 rw,noatime 0 0
Michał Mrożek
źródło
To jednak zawiera wiele obcych tekstów. Muszę być w stanie przekazać punkt montowania innym poleceniom. (Przepraszam, wyjaśniłem to w Q.)
detly
Ach, grep ${NODE} /etc/mtab | cut -d ' ' -f 2powinienem to zrobić.
detly
Chociaż grep ^"${NODE}[[:space:]]\+" /etc/mtab | cut -d ' ' -f 2"jest znacznie mniej kruchy ...
obrzydliwie
2

Tak. Możesz zobaczyć Pokazywanie tylko interesujących punktów montowania / Filtrowanie nieciekawych typów lub katalogów list, pod /którymi nie ma pod tym samym punktem montowania dla niektórych przykładowych zastosowań, ale poniżej znajduje się także krótki przegląd. Polecenie, o które pytasz, to findmnt (choć lsblkmoże również służyć) :

lsblk -f /dev/sda[12]

NAME FSTYPE LABEL UUID                                 MOUNTPOINT
sda1 vfat   ESP   F0B7-5DAE                            /esp
sda2 btrfs  sys   94749918-bde1-46e6-b77c-b66e0368ecdb /    

Teraz, jak widać, /dev/sda1jest zamontowany /esp. Zastanawiam się, czy jest również montowany gdzie indziej?

findmnt /dev/sda1

TARGET SOURCE                    FSTYPE OPTIONS
/esp   /dev/sda1                 vfat   rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro
/boot  /dev/sda1[/EFI/arch_root] vfat   rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro

Aha. Widzę. Podfolder jest również --bindmontowany na bootie. Dobrze...

sudo umount /boot /esp
findmnt /dev/sda1

Nic. Co do cholery?

echo "$?"

1

Ohhh ... Cóż, to miłe. Hmmm...

for d in 1 2
do    findmnt "/dev/sda$d" >/dev/null
      printf  "/dev/sda$d%.$((6>>!$?))s%s\n"\
              " isn't" " currently mounted."
done

/dev/sda1 isn't currently mounted.
/dev/sda2 is currently mounted.

Och, tak, to naprawdę miłe.

for d in /dev/sd*
do    findmnt -noSOURCE,TARGET "$d"
done

/dev/sda2[/arch_root] /

Teraz odłóżmy sda1 tam, gdzie należy i spróbujmy jeszcze raz ...

sudo mount -a
for d in /dev/sd*
do    findmnt -noSOURCE,TARGET "$d"
done

/dev/sda1                 /esp
/dev/sda1[/EFI/arch_root] /boot
/dev/sda2[/arch_root] /

Ale gdzie znalazłem to magiczne polecenie?

man mount | sed -e:n -e'/findmnt/!d;N;/\n$/q;bn'

Aby uzyskać bardziej niezawodne i konfigurowalne dane wyjściowe, użyj findmnt(8) , szczególnie w skryptach. Zauważ, że znaki kontrolne w nazwie punktu montowania są zastępowane przez ?.

mikeserv
źródło
1

Nie znam czystego i prostego sposobu na wykrycie, czy /devzamontowany jest węzeł urządzenia . Ale to właśnie mogę zaoferować. Obsługuje bezpośrednio montowane urządzenia ( /dev/sda1) i urządzenia montowane przez UUID ( /dev/disk/by-uuid/aa4e7b08-6547-4b5a-85ad-094e9e1af74f). Łamie się, jeśli nazwy urządzeń zawierają spacje.

deviceIsMounted()
{
    local DEVICE="$1"
    local MOUNT=$(
        (
            echo "$DEVICE"
            find /dev -type l -lname "*${DEVICE/*\/}" -exec readlink -f {} \; -print |
                xargs -n2 |
                awk -v device="$DEVICE" '$1 == device {print $2}'
        ) |
            xargs -n1 -i{} grep -F {} /proc/mounts
    )
    test -n "$MOUNT" && echo "$MOUNT"
}

deviceIsMounted /dev/sda1 && echo yes              # Mountpoint and status
deviceIsMounted /dev/md2 >/dev/null && echo yes    # Just status

Funkcja zapisuje pozycję od /proc/mountsdo stdout, jeśli zostanie znaleziona, a także ustawia status wyjścia na 0. W przeciwnym razie status wyjścia to 1.

roaima
źródło
-1

Po prostu uruchom poniższe polecenie:

df -h
Steve
źródło