Bash komut dosyasında bir birimin monte edilip edilmediğini kontrol etmenin en iyi yolu nedir?


103

Bash komut dosyasında bir birimin monte edilip edilmediğini kontrol etmenin en iyi yolu nedir?

Gerçekten sevdiğim şey şu şekilde kullanabileceğim bir yöntem:

if <something is mounted at /mnt/foo> 
then
   <Do some stuff>
else
   <Do some different stuff>
fi

Bunu kendim yapmak için bir senaryo yazmak üzereydim. İlk düşüncem / etc / mtab 'dan bilgi almak. Ama daha doğrudan bir yol olup olmadığını görmek için henüz bash kitaplarımın üzerinden geçmedim.
3dinfluence

@ 3dinfluence - evet bunu uzun zaman önce biliyorum ama /etc/mtab, /proc/mountsbağlantılıdır /proc/self/mounts. (Fedora 20'deki atleast)
Wilf

Yanıtlar:


113

/etc/mtabTutarsız olabileceğinden, kullanmaktan kaçının .

Borulardan kaçının mountçünkü o kadar da karmaşık olması gerekmez.

basitçe:

if grep -qs '/mnt/foo ' /proc/mounts; then
    echo "It's mounted."
else
    echo "It's not mounted."
fi

(Bundan sonra gelen boşluk /mnt/fooeşleşmekten kaçınmak içindir /mnt/foo-bar.


7
Bahsedilmez, bağlama noktası sıkıştırılmışsa, bir montaj çağrısı askıda kalabilir.
Chad Huneycutt

8
Linux için iyi, freebsd veya solaris için değil.
chris

4
Bu doğru Chris. Her ne kadar soru Linux olarak etiketlendi.
Dan Carley

3
Sanırım bu felsefi bir soru - mümkünse her şeyi taşınabilir hale getirmeye çalışmalı mıyız yoksa tüm dünyadaki pencereleri / linux'u açıp buna göre davrandığını mı varsaymalıyız?
chris

18
Aslında, '/ mnt / foo' için test etmelisiniz, yani. Örneğin, bir boşlukla veya yanlış bir pozitif elde edersiniz, örneğin; 'kedi köpek'. Bu konuyu iki bağlantı noktasıyla aldım, 'lmde' ve 'lmde-home'.
marlar

58
if mountpoint -q /mnt/foo 
then
   echo "mounted"
else
   echo "not mounted"
fi

veya

mountpoint -q /mnt/foo && echo "mounted" || echo "not mounted"

4
Sadece bilgi için: mountpointUbuntu / Debian'daki "initscripts" paketinden geliyor.
blueyed

1
Benim için işe yaramadı - :-(
Wilf

Bu, Vagrant'ımın beklediği çağrı.
dhill

Asıl sorun mountpoint, aslında bir montaj noktası monte edilip edilmediğini, ancak bir cihazın monte edilip edilmediğini kontrol etmesidir. Bir seçenekle birlikte bir cihaz iletilirse -x, size ana cihaz / küçük cihaz numarasını gösterir, ancak monte edilmişse değil.
vegatripy

@blueyed Debian Buster paketi tarafından sağlandıutil-linux
elboulangero

18

findmnt -rno SOURCE,TARGET "$1"diğer cevaplardaki tüm problemleri önler. Tek bir komutla işi temiz bir şekilde yapıyor.


Diğer yaklaşımlar bu olumsuzluklara sahiptir:

  • grep -qve grep -sgereksiz bir adımdır ve her yerde desteklenmez.
  • /proc/\* her yerde desteklenmiyor.
  • mountinfo dayanmaktadır / proc / ..
  • cut -f3 -d' ' yol adlarındaki boşlukları siler
  • Ayrıştırma bağlama 'ın beyaz boşluk problemlidir. Adam sayfası şimdi diyor ki:

.. listeleme modu sadece geriye dönük uyumluluk için korunur.

Daha sağlam ve özelleştirilebilir çıktılar için , özellikle komut dosyalarınızda findmnt (8) kullanın .


Bash fonksiyonları:

#These functions return exit codes: 0 = found, 1 = not found

isMounted    () { findmnt -rno SOURCE,TARGET "$1" >/dev/null;} #path or device
isDevMounted () { findmnt -rno SOURCE        "$1" >/dev/null;} #device only
isPathMounted() { findmnt -rno        TARGET "$1" >/dev/null;} #path   only

#where: -r = --raw, -n = --noheadings, -o = --output

Kullanım örnekleri:

if isPathMounted "/mnt/foo bar";      #Spaces in path names are ok.
   then echo "path is mounted"
   else echo "path is not mounted"
fi

if isDevMounted "/dev/sdb4"; 
   then echo "device is mounted"
   else echo "device is not mounted"
fi

#Universal:
if isMounted "/mnt/foo bar"; 
   then echo "device is mounted"
   else echo "device is not mounted"
fi

if isMounted "/dev/sdb4";
   then echo "device is mounted"
   else echo "device is not mounted"
fi

1
Zaten Linux'a özgü için bu gerçekten en iyi yaklaşım. findmnt(8)Komutanlığı gördüm ama asla onunla oynamadım. Açıkçası eğer bir Linux kutusunda (ya da komutun mevcut olduğu yerde) bu tür şeyleri yapan (ya da yenilerini yapan) bazı komutlarımı güncellemiş olsaydım, yaptığım şey buydu.
Pryftan

1
Encfs için, findmntparametre ile birlikte verilmesi gerektiğini unutmayın --source encfs, aksi takdirde her zaman ana dizine geri düştüğü için her zaman monte edilecek dizini göz önünde bulundurur.
Burkart

Bu aynı zamanda daha iyi grepbir bağlama yolu garip ise, yanlış pozitif olsun, çünkü çözelti: Ben monte eğer örneğin /dev/mmcblk0p1üzerine ~/mnt/dev/sda1, ben bir şey yanlış olabilir /dev/sda1komutuyla monte edilir mount | grep '/dev/sda1'. Kullanarak yanlış bir pozitif alamıyorum findmnt. İyi cevap!
Cody Piersall

7

Böyle bir senaryo asla taşınabilir olmayacak. Unix'teki kirli bir sır, yalnızca çekirdeğin hangi dosya sistemlerinin nerede olduğunu bilmesi ve / proc (taşınabilir değil) gibi şeylerin size asla net bir cevap vermemesidir.

Genellikle bir alt dizinin bağlama noktasının ne olduğunu ve hangi dosya sisteminde olduğunu bulmak için df'yi kullanırım.

Örneğin (kül / AT&T ksh / bash / etc gibi posix kabuğu gerektirir)

case $(df  $mount)
in
  $(df  /)) echo $mount is not mounted ;;
  *) echo $mount has a non-root filesystem mounted on it ;;
esac

Kinda size faydalı bilgiler söyler.


1
Soru Linux etiketli, bu yüzden belki de taşınabilir olmak zorunda değil
Rory

6

Aşağıdaki, benim rsync yedek cron işlerimden birinde kullandığım şey. / yedeğin takılı olup olmadığını kontrol eder ve takılı değilse takmaya çalışır (sürücü çalışırken değiştirilebilir bir bölmede olduğundan ve hatta sistemde bulunmayabileceğinden, başarısız olabilir)

NOT: Aşağıdaki sadece linux üzerinde çalışır, çünkü greps / proc / mounts - daha taşınabilir bir sürüm çalıştırılabilir 'mount | grep / backup ', Matthew’ın cevabında olduğu gibi ..

  Eğer ! grep -q / backup / proc / mounts; sonra
    Eğer ! mount / backup; sonra
      yankı "başarısız"
      çıkış 1
    fi
  fi
  yankı "başardı."
  # burada bir şeyler yap

2
Alternatif olarak iyi bir sağlık kontrolü olarak değerlendirildi.
Dan Carley

Muhtemelen bu yöntem Matthew Bloch'un cevabıyla aynı problemlerle karşılaşmaktadır.
mwfearnley

evet, "Eliptical view" (Bahsi geçen "Eliptical view" tarafından belirtilen dosya adı alanı dışında). Alt-dizge konusu önemli bir şey değil, eğer bir şekilde iddiaları alıntılamanın yapabileceğiniz bir şey olduğunu unutmazsanız. mesela grep -q ' /backup ' /proc/mountsya mount | grep -q ' /backup '. Senin grep desteklemiyorsa Ya / dev / null yönlendirmek -q(ki olduğu bugünlerde grep için POSIX spec olarak).
Cas

2

Takmak için, yine de orada bir dizine sahip olmanız gerekir, bunun üzerine eklenir, stratejim her zaman asla kullanılmayacak garip bir dosya adına sahip sahte bir dosya oluşturmaktı ve sadece varlığını kontrol etmekti. Eğer dosya orada olsaydı, o zaman hiçbir şey o noktaya monte edilmemişti ...

Bunun ağ sürücülerini veya bunun gibi şeyleri monte etmek için işe yaradığını sanmıyorum. Flash sürücüler için kullandım.


2

Cihaz numaralarını karşılaştırmaya ne dersiniz? Sadece en ezoterik yolu düşünmeye çalışıyordum ..

#!/bin/bash
if [[ $(stat -c "%d" /mnt) -ne $(stat -c "%d" /mnt/foo) ]]; then
    echo "Somethin mounted there I reckon"
fi

Mantığımda bununla ilgili bir kusur var.

İşlev olarak:

#!/usr/bin/bash
function somethingMounted {
        mountpoint="$1"
        if ! device1=$(stat -c "%d" $mountpoint); then
                echo "Error on stat of mount point, maybe file doesn't exist?" 1>&2
                return 1
        fi
        if ! device2=$(stat -c "%d" $mountpoint/..); then
                echo "Error on stat one level up from mount point, maybe file doesn't exist?" 1>&2
                return 1
        fi

        if [[ $device1 -ne $device2 ]]; then
                #echo "Somethin mounted there I reckon"
                return 0
        else
                #echo "Nothin mounted it seems"
                return 1
        fi
}

if somethingMounted /tmp; then
        echo "Yup"
fi

Yankı hata mesajları muhtemelen gereksizdir, çünkü stat de hatayı gösterir.


Aslında, muhtemelen :-( düşünce gibi dosya değil roman olarak ... orada olduğundan emin olmak için ilk her arama için stat çıkış durumunu kontrol etmesi gerekir
Kyle Brandt

1

Bunların hiçbiri, verilen bir dizinin başka bir bağlama noktası içindeki bir alt dizin olduğu kullanım koşullarını karşılamıyor. Örneğin, barındırmak için bir NFS bağlayıcısı olan / şey olabilir: / real_thing. Grep'i / proc / mounts / etc / mtab veya 'mount' komutunda kullanmak işe yaramayacak çünkü varolmayan bir montaj noktası arayacaksınız. Örneğin, / thing / thingy bir bağlama noktası değildir, ancak / thing ana bilgisayara monte edilmiştir: / real_thing. Burada oylanan en iyi cevap aslında "bir dizinin / volümün monte edilip edilmediğini belirlemenin en iyi yolu" DEĞİLDİR. Daha temiz bir strateji olarak 'df -P' (-P POSIX standartlar modu) kullanarak lehte oy kullanırdım:

dev=`df -P /thing/thingy | awk 'BEGIN {e=1} $NF ~ /^\/.+/ { e=0 ; print $1 ; exit } END { exit e }'` && {
    echo "Mounted via: $dev"
} || {
    echo "Not mounted"
}

Bunu çalıştırmanın sonucu şöyle olacaktır:

Mounted via: host:/real_thing

Gerçek bağlama noktasının ne olduğunu bilmek istiyorsanız, sorun değil:

mp=`df -P /thing/thingy | awk 'BEGIN {e=1} $NF ~ /^\/.+/ { e=0 ; print $NF ; exit } END { exit e }'` && {
    echo "Mounted on: $mp"
} || {
    echo "Not mounted"
}

Bu komutun çıktısı:

Mounted on: /thing

Bazı rasgele dizin veya dosya listesi aracılığıyla chroot içindeki montaj noktalarını chroot dışındaki montaj noktalarını yansıtan bir chroot türü oluşturmaya çalışıyorsanız, bu çok yararlıdır.


1

Bunu gündeme getirdiğim için üzgünüm ama bunun oldukça yararlı olduğunu düşünüyorum:

if awk '{print $2}' /proc/mounts | grep -qs "^/backup$"; then
    echo "It's mounted."
else
    echo "It's not mounted."
fi

Bu, / proc / mount'ların 2. sütununu alır (2nd column = mount noktaları).

Sonra çıktıyı siler. ^ Ve $ 'a dikkat edin, bu / yedeklemenin / mnt / backup veya / backup-old vs. ile eşleşmesini önler.


0

belki mola noktası için grep / etc / mtab?


1
mtab güncelliğini yitirebilir veya mount -n kullandığınızda olduğu gibi mount tarafından güncelleştirilmez, çünkü / salt okunurdur.
chris

Aynı fikirdeyim, ancak bakmaya başlayacak ilk yer gibiydi.
Ophidian


0

Bu bir Linux sorusu olmasına rağmen, kolayca yapıldığında neden taşınabilir hale getirmiyorsunuz?

grepDiyor ki manuel sayfa :

Taşınabilir kabuk komut dosyaları hem -q hem de -s'den kaçınmalı ve /dev/nullbunun yerine standart ve hata çıktısını yönlendirmelidir .

Bu yüzden aşağıdaki çözümü öneriyorum:

if grep /mnt/foo /proc/mounts > /dev/null 2>&1; then
        echo "Mounted"
else
        echo "NOT mounted"
fi

3
Pek çok UNIX sistemi / proc dosya sistemini sağlamaz
Dmitri Chubarov

@DmitriChubarov Gerçekten. Taşınabilirlik kavramını ironik kılan nedir? Ve belki de daha yeni bir güncellemedir -qve -sPOSIX tarafından belirtilmiştir, bu yüzden yine de herhangi bir taşınabilirlik sorunu olmamalıdır (şimdi daha önce olmasaydı - ne zaman ne gibi değişiklikler olduğunu takip etmedim).
Pryftan

0

Bundan daha karmaşık olması gerekiyor mu?

mount \
    | cut -f 3 -d ' ' \
    | grep -q /mnt/foo \
  && echo "mounted" || echo "not mounted"

1
grep -q /mnt/fooayrıca montaj noktaları /mnt/foodile eşleşecek ve /not/mnt/foo... Peki ya grep -qx /mnt/foo?
rakslice

@rakslice: Bu işe yaramaz. -xgrep eşleşmesini yalnızca tüm çizgi eşleşirse eşleştirir.
mivk

1
cut -f 3 -d ' 'mount yolu dosya adında bir boşluk olduğunda tökezler.
Eliptik manzara

0

Kontrol ettiğiniz birim hakkında bildiklerinize bağlı olarak değişir.

Belirli bir flash sürücünün monte edilip edilmediğini bulmakla ilgilendiğim son zamanlarda araştırdığım belirli bir durumda, / dev / disks / by-label / öğesinin mevcudiyetini kontrol etmek en kolay olanıdır. Eğer cihaz prize takılı ise udev scriptleri bağlantının mevcut olduğundan emin olun (ve cihaz fişi çekildiğinde çıkartılmış).

(Bu oldukça taşınabilir bir cevap DEĞİLDİR; pek çok modern Linux dağıtımında çalışır ve soru Linux için etiketlendi ve şu ana kadar bahsedilen her şeyden tamamen farklı bir yaklaşım, bu yüzden olanakları genişletiyor.)


0

Mountpoint'inizin altındaki gibi bir dosya oluşturun check_mountve varsa test edin.

if [[ -f /something/check_mount ]]; then
   echo "Mounted
   RC=$?
else
   Echo "Not mounted"
   RC=0
fi
exit $RC

-1

Chef-client'in çalışacağı zaman, run zaten monte edilmiş birim nedeniyle başarısız olacağı için bunu Chef in boşuna yapmak zorunda kaldım. Bunu yazdığımda, Chef mountkaynağının ihtiyacım olan özelliklerle çalışmayan bir tür böcek vardı, bu yüzden executekaynağı kullanarak birimi birleştirdim . İşte nasıl yaptım:

if not node['docker-server']['mountpoint'] == "none"
  execute "set up mount" do
    user "root"
    command "mount -t ext4 #{node['docker-server']['mountpoint']} #{node['docker-server']['data-dir']}"
    not_if "grep -qs #{node['docker-server']['data-dir']} /proc/mounts"
  end
end

Herhangi bir karışıklık durumunda, özellikler dosyamda aşağıdakiler var:

default['docker-server']['mountpoint'] = "/dev/vdc"
default['docker-server']['data-dir'] = "/data"

if not node['docker-server']['mountpoint'] == "none"Bir bir parçası olan casesunucu üzerinde bağlama noktası için, bağlama noktası belirtilmezse varsayılan değilse deyimi none.


... ve bunun asıl soru ile ne ilgisi var?!?
Massimo

Aşçı tarifi yorumumun asıl soruya olan ilişkisi, insanların giderek otomasyona doğru hareket ettikleridir. Bu nedenle, eğer birisi bu işi bir Şef tarifinde nasıl yapacağını merak ederek buraya gelirse, bir cevapları olacaktır. Hayatta iki seçenek vardır: 1) Çabuk minimum yapın ve bazı insanları mutlu edin, ve 2) Ekstra mil gidin. Bu nedenle, gönderimi aşağıya işaretlemek yerine, ne olduğunu kabul edin: kabul edilen cevabı destekleyen ek bilgiler.
KLaw

Soru, bash scriptleri ile ilgiliydi, cevabınız Chef scriptleri ile ilgili. Birisi için faydalı olabileceği halde, soru ile hiçbir ilgisi yoktur.
Massimo

@KLaw 'Bu nedenle, gönderimi aşağıya işaretlemek yerine, ne olduğunu kabul edin: kabul edilen cevabı destekleyen ek bilgiler.' Aynı fikirdeyim ve genellikle aşağı oy kullanmayacağım (ya da burada da bulunmadım) ama bu tür bir şeyle ilgili bir sorun yaşarsanız, belki de diğer noktalarınıza ek olarak eklemelisiniz? Diğer yorumları saklayabilir. Ama otomasyon gelince, bash scriptlerinin izin verdiği tam olarak bu yüzden amacınızı göremiyorum. Tabii içimde programcı o komut yukarıda düşünen iğrenç ama bu bir dil sorunu her şeyden çok ... var
Pryftan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.