Question Quel est le meilleur moyen de vérifier si un volume est monté dans un script Bash?


Quel est le meilleur moyen de vérifier si un volume est monté dans un script Bash?

Ce que j'aimerais vraiment, c'est une méthode que je peux utiliser comme ceci:

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

90
2017-08-05 20:16


origine


J'étais sur le point d'écrire un script pour le faire moi-même. Ma première pensée est d’obtenir des informations de / etc / mtab. Mais je n’ai pas encore feuilleté mes livres de bash pour voir s’il existe un moyen plus direct. - 3dinfluence
@ 3dinfluence - oui, je le sais depuis longtemps, mais /etc/mtab, /proc/mounts sont liés à /proc/self/mounts. (au moins sur Fedora 20 il est) - Wilf


Réponses:


Évitez d'utiliser /etc/mtab parce que cela peut être incohérent.

Éviter les tuyaux mount parce que ça n'a pas besoin d'être si compliqué.

Simplement:

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

(L'espace après la /mnt/foo est d'éviter d'apparier par exemple /mnt/foo-bar.)


103
2017-08-05 20:27



Sans oublier, un appel à monter peut être suspendu si le point de montage est bloqué. - Chad Huneycutt
Bon pour Linux, pas pour FreeBSD ou Solaris. - chris
C'est vrai, chris. Bien que la question a été étiquetée linux. - Dan Carley
J'imagine que c'est une question philosophique - devrions-nous essayer de rendre les choses portables si possible ou devrions-nous simplement supposer que tout le monde tourne sous Windows / Linux et agir en conséquence? - chris
En fait, vous devriez tester '/ mnt / foo', c'est-à-dire. avec un espace ou vous pourriez obtenir un faux positif si vous aviez monté un volume nommé par exemple. "fooks". Je viens d'avoir ce problème avec deux points de montage, "lmde" et "lmde-home". - marlar


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

ou

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

53
2018-01-04 08:33



Juste pour informations: mountpoint provient du paquet "initscripts" dans Ubuntu / Debian. - blueyed
N'a pas fonctionné pour moi - :-( - Wilf
C'est l'appel auquel mon vagabond se cramponne. - dhill
Le problème avec mountpoint en fait, il vérifie si un point de montage est monté, mais pas si un périphérique est monté. Si un appareil est passé avec le -x En option, il vous indique le numéro de périphérique majeur / mineur, mais pas s'il est monté. - vegatripy


Un script comme celui-ci ne sera jamais portable. Un sale secret sous Unix est que seul le noyau sait quels systèmes de fichiers se trouvent où et, à part des choses comme / proc (non portable), il ne vous donnera jamais de réponse directe.

J'utilise généralement df pour découvrir le point de montage d'un sous-répertoire et son système de fichiers.

Par exemple (nécessite un shell posix comme cendres / AT & T ksh / bash / etc)

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

Kinda vous dit des informations utiles.


6
2017-08-05 20:32



La question est étiquetée linux, alors peut-être que ça ne doit pas être portable - Rory


Voici ce que j'utilise dans l'un de mes travaux cron de sauvegarde rsync. il vérifie si / backup est monté et essaie de le monter s'il ne l'est pas (cela peut échouer car le lecteur se trouve dans une baie remplaçable à chaud et peut même ne pas être présent dans le système)

NOTE: Ce qui suit ne marche que sur linux, car il contient greps / proc / mounts - une version plus portable exécutera 'mount | grep / backup ', comme dans la réponse de Matthew ..

  si ! grep -q / backup / proc / mounts; puis
    si ! monter / sauvegarder; puis
      echo "échoué"
      sortie 1
    Fi
  Fi
  echo "réussi"
  # faire des choses ici

6
2017-08-05 20:39



Upvoté comme une alternative bonne vérification de la santé mentale. - Dan Carley
Vraisemblablement, cette méthode se heurte aux mêmes problèmes que la réponse de Matthew Bloch. - mwfearnley
Oui, à l'exception du problème d'espace dans le nom de fichier mentionné par "Eliptical view" (ceci insère toute la ligne, pas seulement un champ extrait). Le problème des sous-chaînes n’est pas un problème, à moins d’oublier que citer des arguments est une chose que vous pouvez faire. par exemple. grep -q ' /backup ' /proc/mounts ou mount | grep -q ' /backup '. Ou redirigez vers / dev / null si votre grep ne supporte pas -q (lequel est dans la spécification POSIX pour grep ces jours-ci). - cas


findmnt -rno SOURCE,TARGET "$1" évite tous les problèmes dans les autres réponses. Il fait proprement le travail avec une seule commande.


D'autres approches ont ces inconvénients:

  • L'analyse monterL'espace blanc de est problématique. Sa page de manuel dit maintenant:

Le mode liste est maintenu pour la compatibilité ascendante uniquement.

Pour une utilisation plus robuste et personnalisable des sorties trouver(8), en particulier dans vos scripts.


  • grep -q et grep -s sont une étape supplémentaire inutile et ne sont pas pris en charge partout.
  • /proc/\* n'est pas supporté partout.
  • mountinfo est basé sur / proc / ..
  • cut -f3 -d' ' gâche les espaces dans les noms de chemins

Les fonctions:

#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

Exemples d'utilisation:

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

5
2018-03-15 16:42



Pour Linux en tout cas, c’est la meilleure approche. J'ai vu le findmnt(8) commande mais je n'ai jamais vraiment joué avec. Franchement, si je mettais à jour certains de mes scripts qui font ce type de choses (ou en créons de nouveaux) sur une machine Linux (ou lorsque la commande est disponible), c’est ce que je ferais. - Pryftan


Comme pour monter, vous devez de toute façon avoir un répertoire dessus, ma stratégie a toujours été de créer un faux fichier avec un nom de fichier étrange qui ne serait jamais utilisé et de vérifier son existence. Si le fichier était là, rien n'était monté à cet endroit ...

Je ne pense pas que cela fonctionne pour monter des lecteurs réseau ou des choses comme ça. Je l'ai utilisé pour les lecteurs flash.


2
2017-08-05 20:36





Que diriez-vous de comparer les numéros d'appareils? J'essayais juste de penser au plus ésotérique façon..

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

Il y a un défaut dans ma logique avec ça ...

En tant que fonction:

#!/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

Les messages d'erreur echo sont probablement redondants, car stat affichera également une erreur.


2
2017-08-05 20:57



En fait, il faudrait probablement vérifier l’état de sortie de stat d’abord pour chaque appel afin de s’assurer que le fichier est là ... pas aussi nouveau que je le pensais :-( - Kyle Brandt♦


Aucune de celles-ci ne convient au cas d'utilisation où un répertoire donné est un sous-répertoire dans un autre point de montage. Par exemple, vous pourriez avoir / thing qui est un montage NFS à héberger: / real_thing. Utiliser grep à cette fin sur / proc / mounts / etc / mtab ou 'mount' ne fonctionnera pas, car vous rechercherez un point de montage qui n'existe pas. Par exemple, / thing / thingy n'est pas un point de montage, mais / thing est monté sur l'hôte: / real_thing. La meilleure réponse votée ici n’est en réalité PAS "la meilleure façon de déterminer si un répertoire / volume est monté". Je voterais en faveur de l’utilisation de 'df -P' (mode standard -P POSIX) comme stratégie plus propre:

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"
}

Le résultat de l’exécution sera:

Mounted via: host:/real_thing

Si vous voulez savoir quel est le véritable point de montage, pas de problème:

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"
}

Le résultat de cette commande sera:

Mounted on: /thing

Ceci est très utile si vous essayez de créer une sorte de chroot qui reflète les points de montage en dehors du chroot, au sein du chroot, via un répertoire ou une liste de fichiers arbitraire.


1
2017-10-24 13:59