Який найкращий спосіб перевірити, чи встановлено гучність у сценарії Bash?


103

Який найкращий спосіб перевірити, чи встановлено гучність у сценарії Bash?

Що мені дуже хотілося б - це метод, який я можу використовувати так:

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

Я ось-ось збирався написати сценарій, щоб це зробити сам. Перша моя думка - отримати інформацію з / etc / mtab, але я ще не проглянув свої книги з башти, щоб зрозуміти, чи є більш прямий спосіб.
3вплив

@ 3dinfluence - так , я знаю це вже давно, але /etc/mtab, /proc/mountsпов'язані з /proc/self/mounts. (принаймні на Fedora 20 це)
Вільф

Подібні запитання є щодо помилок сервера , переповнення стека та обміну стеками Unix та Linux .
Саша

Відповіді:


113

Уникайте використання, /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.)


7
Не кажучи вже про те, що дзвінок на горіння може зависнути, якщо точка монтажу закріплена.
Чад Хунейкутт

8
Добре підходить для Linux, а не для freebsd або solaris.
chris

4
Це правда, Кріс. Хоча питання було позначене Linux.
Ден Карлі

3
Я думаю, це філософське питання - чи варто намагатися зробити речі портативними, якщо це можливо, чи слід просто припустити, що всі керовані Windows / linux у світі та діють відповідно?
chris

18
Власне, вам слід перевірити на '/ mnt / foo', тобто. з пробілом, або ви можете отримати помилковий позитив, якби ви встановили том, названий напр. 'дивляться'. Щойно я отримав цю проблему з двома точками кріплення: 'lmde' та 'lmde-home'.
березня 1111

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

або

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

4
Тільки для інформації: mountpointбереться в пакеті "initscripts" в Ubuntu / Debian.
синенький

1
Не працювало для мене - :-(
Вільф

Це заклик, на який зависає мій Вагрант.
dhill

Проблема mountpointполягає в тому, що він перевіряє, чи встановлено точку монтажу, але не, чи встановлено пристрій. Якщо пристрій передається з -xопцією, він повідомляє вам основний / другорядний номер пристрою, але не, якщо він встановлений.
vegatripy

@blueyed У Debian Buster це передбачено пакетомutil-linux
elboulangero

18

findmnt -rno SOURCE,TARGET "$1"уникає всіх проблем в інших відповідях. Він чисто виконує роботу лише однією командою.


В інших підходів є такі недоліки:

  • grep -qі grep -sє зайвим непотрібним кроком, і підтримується не скрізь.
  • /proc/\* не підтримується скрізь.
  • mountinfo заснований на / proc / ..
  • cut -f3 -d' ' псує пробіли у назвах шляхів
  • Синтаксичне кріплення білого простір «s проблематично. Зараз на сторінці чоловіка написано:

.. Режим лістингу підтримується лише для зворотної сумісності.

Для більш надійного та настроюваного виводу використовуйте findmnt (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

1
У будь-якому випадку для Linux це дійсно найкращий підхід. Я бачив findmnt(8)команду, але ніколи насправді з нею не грав. Відверто кажучи, якби я оновлював деякі мої сценарії, які роблять подібні речі (або роблять нові) на вікні Linux (або там, де є команда), це я б робив.
Прифтан

1
Зверніть увагу, що для encfs, findmntвін повинен постачатися з параметром --source encfs, інакше він завжди вважатиме каталог встановленим, оскільки він повертається до батьківського монтажу.
Буркарт

Це також краще , ніж grepрішення , тому що , якщо шлях монтування дивно, ви можете отримати помилкові спрацьовування: наприклад , якщо я встановлюю /dev/mmcblk0p1на ~/mnt/dev/sda1, я міг би неправильно річ , яка /dev/sda1кріпиться з допомогою команди mount | grep '/dev/sda1'. Я не можу отримати помилковий позитив, використовуючи findmnt. Хороша відповідь!
Коді Пірсол

7

Такий сценарій ніколи не буде портативним. Брудний секрет в Unix полягає в тому, що тільки ядро ​​знає, які файлові системи є, де, окрім речей, таких як / proc (не портативний), воно ніколи не дасть вам прямої відповіді.

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

Наприклад (потрібна оболонка посіксу, наприклад, зола / 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

Kinda розповідає вам корисну інформацію.


1
Питання позначено тегом Linux, тому, можливо, воно не повинно бути портативним
Rory

6

далі - те, що я використовую в одному з моїх робочих місць резервного копіювання rsync. він перевіряє, чи встановлено / резервне копіювання, і намагається встановити його, якщо його немає (він може вийти з ладу, оскільки накопичувач знаходиться у відсіку гарячої заміни і може навіть не бути в системі)

ПРИМІТКА. Наступне працює лише в Linux, оскільки він greps / proc / mounts - більш портативна версія запустить 'mount | grep / backup ', як у відповіді Метью.

  якщо! grep -q / резервне копіювання / proc / mounts; тоді
    якщо! кріплення / резервне копіювання; тоді
      відлуння "не вдалося"
      вихід 1
    фі
  фі
  відлуння "вдалося".
  # робити тут речі

2
Запропонований як хороша альтернатива перевірки санітарності.
Ден Карлі

Імовірно, цей метод стикається з тими ж проблемами, що і у відповіді Меттью Блоха.
mwfearnley

Так, за винятком проблеми з пробілом у файлі, згаданої "Еліптичним поданням" (це стосується всього рядка, а не лише вилученого поля). Проблема з підрядками не є великою справою, якщо ви якось не забудете, що цитувати аргументи - це те, що ви можете зробити. наприклад grep -q ' /backup ' /proc/mountsабо mount | grep -q ' /backup '. Або перенаправити на / dev / null, якщо ваш grep не підтримує -q(що є специфікацією POSIX для grep в ці дні).
cas

2

Оскільки для того, щоб встановити, у будь-якому випадку вам потрібно мати каталог, який зможе встановитись, моя стратегія завжди була створити помилковий файл із дивним іменем файлу, який ніколи не буде використовуватися, і просто перевірити його наявність. Якщо файл був там, то на цьому місці нічого не було встановлено ...

Я не думаю, що це працює для монтажу мережевих накопичувачів або подібних речей. Я використовував його для флеш-накопичувачів.


2

Як щодо порівняння номерів пристроїв? Я просто намагався придумати найбільш езотеричний спосіб ..

#!/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 також відображатиме помилку.


Насправді, мабуть, доведеться спочатку перевірити стан виходу stat для кожного дзвінка, щоб переконатися, що файл там є ... не такий новий, як я думав :-(
Кайл Брандт

1

Жоден із них не задовольняє випадок використання, коли даний каталог є підкаталогом в іншій точці монтажу. Наприклад, у вас може бути / річ, яка є кріпленням NFS для розміщення: / real_thing. Використання grep для цієї мети на / proc / mounts / etc / mtab або 'mount' не буде працювати, тому що ви будете шукати точку кріплення, яка не існує. Наприклад, / thing / thingy не є точкою кріплення, але / thing встановлено на хості: / real_thing. Найкраща відповідь, проголосована тут, насправді НЕ "найкращий спосіб визначити, чи встановлений каталог / об'єм". Я хотів би проголосувати, використовуючи 'df -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, через якийсь довільний каталог або список файлів.


1

Вибачте за те, що це підняло, але я думаю, що це досить корисно:

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-й стовпчик = точки монтажу).

Потім він схоплює вихід. Зверніть увагу на ^ і $, це запобігає відповідності / резервного копіювання / mnt / backup або / backup-old тощо.


0

grep / etc / mtab для точки монтажу, можливо?


1
mtab може застаріти або просто не буде оновлено програмою mount, наприклад, коли ви використовуєте mount -n, оскільки / лише для читання.
chris

Я згоден, але це здавалося першим місцем, щоб почати шукати.
Офідіан


0

Хоча це питання Linux, чому б не зробити його портативним, коли це легко зробити?

Сторінка керівництва grepговорить:

Сценарії портативної оболонки повинні уникати як -q, так і -s, а /dev/nullнатомість слід перенаправляти стандартні та помилки .

Тому я пропоную таке рішення:

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

3
Багато UNIX-систем не надають файлову систему / proc
Дмитро Чубаров,

@DmitriChubarov Дійсно. Що робить концепцію портативності іронічною, чи не так? А може бути , це більш недавнє оновлення , але -qі -sвказані POSIX , так що не повинно бути ніяких портативність проблема з ним в будь-якому випадку ( в даний час , якщо не раніше - я не відстежував , які зміни відбуваються , коли).
Прифтан

0

Чи потрібно це бути складнішим за це?

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

1
grep -q /mnt/fooвідповідатиме точкам кріплення /mnt/foodі /not/mnt/foo... Як щодо grep -qx /mnt/foo?
rakslice

@rakslice: це не працює. -xробить grep match лише у тому випадку, якщо вся лінія збігається.
mivk

1
cut -f 3 -d ' 'спотикається, коли на шляху монтажу є пробіл у імені файлу.
Еліптичний вигляд

0

Залежить від того, що ви знаєте про гучність, яку ви перевіряєте.

У конкретному випадку, який я нещодавно досліджував, де я був стурбований, щоб дізнатися, чи встановлена ​​певна флешка, що найлегше працює - це перевірка наявності / dev / disks / by-label /. Якщо пристрій підключено до мережі, сценарії udev переконайтеся, що посилання існує (і що воно видалено, коли пристрій відключено).

(Це НЕ дуже портативний варіант відповіді; він працює на багатьох сучасних дистрибутивах Linux, і це питання було позначене для Linux, і це зовсім інший підхід від будь-якого, що було сказано до цього, тому він розширює можливості.)


0

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

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

-1

Мені довелося це зробити в шеф-кухарі для безвідмовності, оскільки коли шеф-повара-клієнт запустився, запуск не вдасться із-за вже встановленого обсягу. У той час, коли я це пишу, у mountресурсу Chef є якась помилка, яка не працюватиме з атрибутами так, як мені потрібно, тому я встановив гучність, використовуючи 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.


... і що це стосується оригінального питання?!?
Массімо

Відношення коментаря мого рецепта до шефа до оригінального питання полягає в тому, що люди все більше рухаються до автоматизації. Тому, якщо хтось сюди прийде цікавитись, як зробити цю роботу за рецептом шеф-кухаря, у них буде відповідь. У житті є два варіанти: 1) Зробіть мінімум і зробіть когось щасливим, і 2) Пройдіть зайву милю. Тому замість позначення моєї публікації прийміть її такою, якою вона є: додаткова інформація, яка підтримує прийняту відповідь.
KLaw

Питання стосувалося баш сценаріїв, ваша відповідь - про сценарії шеф-кухарів. Хоча це може бути корисним комусь, воно все ще не має жодної актуальності щодо питання.
Массімо

@KLaw "Тому замість того, щоб позначати свою публікацію, прийміть її такою, якою вона є: додаткова інформація, яка підтримує прийняту відповідь." Я погоджуюсь, і я не один, хто зазвичай проголосував (і я тут теж не був), але якщо у вас є проблеми з таким видом речі, ви можете, можливо, додати її як доповнення до інших пунктів? Можна зберегти інші коментарі. Але що стосується автоматизації, це саме те, що дозволяють баш сценарії, тому я не бачу вашої суті. Звичайно, програміст в мені вважає, що сценарій вище - огидний, але це питання мови більше, ніж усе інше ...
Прифтан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.