Получить UUID / файловой системы из скрипта

11

Как я могу получить UUID тома, который содержит /файловую систему? Лучшее, что я нашел на сегодняшний день, это blkid -o list. Но этот вывод читается человеком и его трудно разобрать. Может быть, есть лучший способ?

Мне это нужно для параметризации управления конфигурацией с помощью системных шаблонов.

ПРИМЕЧАНИЕ о blkidтом, кто может повторно использовать результаты моего вопроса в будущем: blkidкэширует результаты предыдущих прогонов на /etc/blkid.tab. Это означает, что при запуске blkidот имени пользователя без полномочий root данные не возвращаются. Кроме того, выполнение blkidот имени пользователя без полномочий root после запуска root вернет устаревшие (возможно, некорректные) данные.

Dmitriusan
источник
В моих собственных системах я назначаю понятные человеку уникальные метки для всех разделов. Затем я могу узнать о них почти все, используя их метки и /dev/disk/by-label... Это также работает для разделов, которые не смонтированы. Он имеет преимущество в том, что может писать сценарии, выполняющие такие вещи, как rsync, от root до root-bak, что гораздо менее подвержено ошибкам, чем использование 2 UUIDS, которые ничего не «значат».
Джо

Ответы:

25

Используйте findmnt:

$ findmnt /        
TARGET SOURCE       FSTYPE OPTIONS
/      /dev/md127p1 ext4   rw,relatime,stripe=256,data=ordered
$ findmnt / -o UUID
UUID
046a554b-d9f5-4b23-82e6-ffaeb98284aa
$ findmnt / -o UUID -n
046a554b-d9f5-4b23-82e6-ffaeb98284aa

У него также есть несколько опций для управления тем, как она ищет информацию и как она ее представляет (включая вывод JSON!). Это часть mountпакета, доступная для любой установки Ubuntu.

Мур
источник
Это прекрасно работает 16.04. Он не функционировал для меня 14.04. Мне пришлось использовать этот подход для получения желаемых результатов на достоверных.
Старейшина Гик
11

Другое решение:

lsblk -nr -o UUID,MOUNTPOINT | grep -Po '.*(?= /$)'
  • -n подавляет заголовок (не очень нужен, но безопаснее для разбора)
  • -r делает необработанный вывод (делает его более безопасным для анализа)
  • -o UUID,MOUNTPOINT включать только необходимую информацию
pLumo
источник
5

Вы можете использовать lsblkкоманду для вывода UUID, но вам нужно имя устройства раздела (например, / dev / sda2). Вы можете получить это с помощью dfкоманды и обрезки вывода. Используйте подстановку команд, чтобы присвоить имя устройству lsblk. Похоже, вам нужен sudo для доступа к UUID, хотя для нормального вывода lsblk это не требуется:

sudo lsblk -n -o UUID "$(df -P / | tail -n1 | cut -d' ' -f1)"
Arronical
источник
2
Это работает для меня без sudo16.04.
Элия ​​Каган
только если вы (или какой-либо скрипт) когда-либо запускали эту команду от имени пользователя root ранее. Кроме того , может быть Ouput несвежий (из кэша) в данном случае
Dmitriusan
@Dmitriusan Я запустил это в системе 14.04, в которой никогда не было lsblkили не blkidвыполнялся root, и она работала отлично. Знаете ли вы, почему возникла проблема с кэшированием этой команды, а не версии, опубликованной Rovo? Может ли необработанный вывод каким-либо образом обойти кеширование?
Arronical
Я думаю, что любая команда, которая обращается к UUID устройств, потребует root-доступа (включая версию, опубликованную Rovo). Относительно lsblk, вот связанный вопрос unix.stackexchange.com/questions/210889/… (см. Первый ответ)
Dmitriusan
Я согласен, что sudo необходим, но не могу найти ничего, что могло бы предположить, что lsblk полагается на кеширование. Даже если я запускаю blkidс правами root, при создании файла кэша при /dev/.blkid.tabиспользовании sudo lsblkне будет отображаться ничего из столбца UUID. Я не думаю, что есть риск устаревания продукции.
Arronical
4

Лучшее решение, которое мне удалось найти, это

blkid -o list | awk '/\/[[:space:]]+/{ print $0 }' | tr -s ' ' | cut -d ' ' -f 4

По ощущениям неоптимально, но работает.

Примечание: [[: space:]] означаетSpace

Dmitriusan
источник
Это работает для меня, но с sudo.
pa4080
4

Установите значение mountpointтекущей точки монтирования файловой системы:

dev="$(exec awk -v mountpoint='/' '($2 == mountpoint){ print $1; quit; }' /proc/mounts)" &&
sudo blkid -o export -- "$dev" | sed -ne 's/^UUID=//p'
Дэвид Фёрстер
источник
1

Вот что я использую:

sudo tune2fs -l $(df  / | tail -1 |awk '{print $1}') |grep UUID|awk '{ print $3 }'

tune2fs находится в пакете e2fsprogs, который я не могу вспомнить, установлен ли он по умолчанию.

sudo apt install e2fsprogs

если он не установлен.

Джон
источник
Я awk: not an option: -eотредактировал ваш ответ, чтобы сделать его функциональным. Если я перешагнул, пожалуйста, не стесняйтесь откатываться назад. Ура! :-)
Старейшина Гик
Странно, но мне кажется, что она работает с или без нее. -e задокументировано в справочной странице по awk. Я всегда использовал это в сценариях, и я был удивлен, что без него все работало нормально :) Я думаю - это старая привычка UNIX. Но я должен был быть последовательным в своем использовании и использовать -e в обоих местах или в любом месте, чтобы не запутать людей.
Джон
Ах, я получаю тот же результат, что и вы до 14.04, который использует gawk. Я получаю ошибку, указанную в 16.04, которая используется mawkвместо этого.
Старейшина Компьютерщик
Это одна из тех / etc / альтернативных вещей. / etc / alternatives / awk -> / usr / bin / gawk для меня 16.04. Mawk установлен, но не активен в / etc / alternatives. На моем 17.04 гноме это указывает на awk. На моей свежей установке 17.10 это mawk. После установки gawk ссылка указывает на gawk, удаление gawk возвращает его в mawk.
Джон
:-) Именно эти незначительные различия между предположительно похожими программами, вероятно, привели к утверждениям типа «Меньше значит больше»
старейшина Гик
1

Проверено на работу 14.04 и 16.04

Простой один вкладыш , который всегда должен производить UUID из корня /является

экспорт DRIVE = $ (mount | grep '/' | awk -F "on" '{print $ 1}'); blkid $ DRIVE | cut -d '"' -f2`

Здесь мы собираем выходные данные команды mount, чтобы сопоставить корневой символ с пробелами с обеих сторон, /чтобы избежать совпадения при /использовании в качестве символа расширения пути, передавая это через awkиспользование «on» в качестве разделителя полей, чтобы вывести только имя устройства и присвоение TH для переменной среды $ DRIVE, затем используя вывод blkid $DRIVEpiped через cut, используя в "качестве разделителя полей, и выбирая только второе поле, которое удаляет все остальное, оставляя только UUID.

Обратите внимание , что после команды grep в приведенной выше команде на самом деле указано « space/ space», а не «/», как кажется.

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

Было бы разумно убедиться, что вы не используете переменную окружения $ DRIVE для чего-либо еще, прежде чем пытаться использовать этот подход, и вы echo $DRIVEполучите пустую строку, если вы не используете переменную.

Старейшина Гик
источник