Назад | Перейти на главную страницу

Как лучше всего проверить, смонтирован ли том в сценарии Bash?

Как лучше всего проверить, смонтирован ли том в сценарии Bash?

Что мне действительно нужно, так это метод, который я могу использовать вот так:

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

Избегать использования /etc/mtab потому что это может быть непоследовательным.

Избегайте трубопроводов mount потому что это не должно быть так сложно.

Просто:

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

(Пробел после /mnt/foo избегать совпадения, например /mnt/foo-bar.)

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

или

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

findmnt -rno SOURCE,TARGET "$1" позволяет избежать всех проблем в других ответах. Он чисто выполняет свою работу с помощью всего одной команды.


У других подходов есть следующие недостатки:

  • grep -q и grep -s являются лишним ненужным шагом и поддерживаются не везде.
  • /proc/\* не везде поддерживается.
  • mountinfo основан на / proc / ..
  • cut -f3 -d' ' путает пробелы в именах путей
  • Парсинг монтироватьпустое пространство проблематично. На странице руководства теперь говорится:

.. режим листинга поддерживается только для обратной совместимости.

Для более надежного и настраиваемого вывода используйте найти(8), особенно в ваших скриптах.


Функции Bash:

#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

Примеры использования:

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

Такой сценарий никогда не будет переносимым. Грязный секрет в unix заключается в том, что только ядро ​​знает, какие файловые системы и где находятся, и, за исключением таких вещей, как / proc (не переносимый), оно никогда не даст вам прямого ответа.

Обычно я использую df, чтобы узнать, что такое точка монтирования подкаталога и в какой файловой системе он находится.

Например (требуется оболочка posix, такая как ash / AT&T ksh / bash / и т. Д.)

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

Вроде как сообщает вам полезную информацию.

Ниже приводится то, что я использую в одном из моих заданий cron по резервному копированию rsync. он проверяет, смонтирован ли / backup, и пытается смонтировать его, если это не так (это может привести к сбою, потому что диск находится в отсеке для горячей замены и может даже не присутствовать в системе)

ПРИМЕЧАНИЕ: следующее работает только в Linux, потому что он greps / proc / mounts - более переносимая версия будет запускать 'mount | grep / backup ', как в ответе Мэтью ..

  if ! grep -q /backup /proc/mounts ; then
    if ! mount /backup ; then
      echo "failed"
      exit 1
    fi
  fi
  echo "suceeded."
  # do stuff here

Как насчет сравнения номеров устройств? Я просто пытался думать о самом эзотерический путь..

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

В моей логике есть изъян ...

Как функция:

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

Сообщения об ошибках эха, вероятно, избыточны, потому что stat также будет отображать ошибку.

Поскольку для монтирования вам в любом случае нужен каталог, который монтируется, моя стратегия всегда заключалась в том, чтобы создать фиктивный файл со странным именем файла, которое никогда не будет использоваться, и просто проверить его существование. Если файл был там, значит, на этом месте ничего не монтировалось ...

Я не думаю, что это работает для подключения сетевых дисков или чего-то подобного. Использовал для флешек.

Мне нравятся ответы, в которых используется /proc/mounts, но мне не нравится делать простой grep. Это может дать вам ложные срабатывания. Что ты действительно хочу знать, "есть ли в какой-либо из строк именно эту строку для поля номер 2". Итак, задайте этот вопрос. (в этом случае я проверяю /opt)

awk -v status=1 '$2 == "/opt" {status=0} END {exit status}' /proc/mounts

# and you can use it in and if like so:

if awk -v status=1 '$2 == "/opt" {status=0} END {exit status}' /proc/mounts; then
  echo "yes"
else
  echo "no"
fi

Извините за то, что поднял этот вопрос, но я думаю, что это очень полезно:

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

Это получает 2-й столбец / proc / mounts (2-й столбец = точки монтирования).

Затем он собирает вывод. Обратите внимание на ^ и $, это не позволяет / backup соответствовать / mnt / backup или / backup-old и т. Д.

Ни один из них не соответствует варианту использования, когда данный каталог является подкаталогом в другой точке монтирования. Например, у вас может быть / thing, который является монтированием NFS для host: / real_thing. Использование grep для этой цели в / proc / mounts / etc / mtab или 'mount' не будет работать, потому что вы будете искать точку монтирования, которой не существует. Например, / thing / thingy не является точкой монтирования, но / thing монтируется на хосте: / real_thing. Лучший ответ, за который проголосовали здесь, на самом деле НЕ «лучший способ определить, смонтирован ли каталог / volumne». Я бы проголосовал за использование 'df -P' (-P стандартный режим POSIX) в качестве более чистой стратегии:

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

Результатом работы будет:

Mounted via: host:/real_thing

Если вы хотите знать, какова настоящая точка монтирования, не проблема:

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

Результатом этой команды будет:

Mounted on: /thing

Все это очень полезно, если вы пытаетесь создать своего рода chroot, который отражает точки монтирования вне chroot, внутри chroot, через произвольный каталог или список файлов.

Зависит от того, что вы знаете о проверяемом объеме.

В конкретном случае, который я недавно исследовал, когда я хотел выяснить, смонтирован ли конкретный флэш-накопитель, проще всего проверить наличие / dev / disks / by-label /. Если устройство подключено, сценарии udev проверяют, существует ли ссылка (и что она удаляется при отключении устройства).

(Это НЕ очень переносимый ответ; он работает во многих современных дистрибутивах Linux, и вопрос был помечен для Linux, и это совершенно другой подход, чем все, что было упомянуто до сих пор, поэтому он расширяет возможности.)

Должно быть что-то более сложное, чем это?

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

Хотя это вопрос Linux, почему бы не сделать его переносимым, если это легко сделать?

Справочная страница grep говорит:

Переносимые сценарии оболочки должны избегать использования -q и -s и должны перенаправлять стандартный вывод и вывод ошибок на /dev/null вместо.

Поэтому я предлагаю следующее решение:

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

Это?:

volume="/media/storage"
if mount|grep $volume; then
echo "mounted"
else
echo "not mounted"
if

Из: Форум Ubuntu

Может быть, grep / etc / mtab для вашей точки монтирования?

Создайте файл под вашей точкой монтирования, например check_mount а затем просто проверьте, существует ли он?

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

Мне пришлось сделать это в Chef для идемпотентности, так как при запуске chef-client запуск завершался ошибкой из-за того, что том уже был смонтирован. В то время, когда я пишу это, шеф-повар mount у ресурса есть какая-то ошибка, которая не работает с атрибутами так, как мне нужно, поэтому я смонтировал том, используя execute ресурс вместо этого. Вот как я это сделал:

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

В случае какой-либо путаницы в моем файле атрибутов у меня есть следующее:

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

В if not node['docker-server']['mountpoint'] == "none" является частью case оператор, где, если точка монтирования на сервере не указана, точка монтирования по умолчанию none.