Как лучше всего проверить, смонтирован ли том в сценарии 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
.