Эффективный способ получить точку монтирования устройства по его UUID.

Я думаю, вы путаете синтаксис оболочки для конвейеров и базовое системное программирование Unix. Канал / FIFO — это тип файла, который не хранится на диске, а вместо этого передает данные от средства записи к считывателю через буфер в ядре.

Канал/FIFO работает одинаково независимо от того, соединились ли писатель и читатель с помощью системных вызовов, таких как open("/path/to/named_pipe", O_WRONLY);, или с помощьюpipe(2)для создания нового анонимного канала и возврата дескрипторов открытых файлов как для чтения, так и для записи..

fstat(2)в дескрипторе файла канала даст вам sb.st_mode & S_IFMT == S_IFIFOв любом случае.


Когда вы бежитеfoo | bar:

  • Оболочка разветвляется, как обычно, для любой не -встроенной команды
  • Затем выполняет pipe(2)системный вызов для получения двух файловых дескрипторов :ввода и вывода анонимного канала.
  • Затем снова разветвляется .
  • Ребенок (, где fork()вернул 0 )
    • закрывает считывающую сторону канала (, оставляя запись fd открытой)
    • и перенаправляет stdoutна запись fd с помощьюdup2(pipefd[1], 1)
    • тогда делаетexecve("/usr/bin/foo",...)
  • Родительский (, где fork()вернул не -0 дочерний PID )
    • закрывает сторону канала для записи (, оставляя открытым fd для чтения)
    • и перенаправляет stdinиз read fd с помощьюdup2(pipefd[0], 0)
    • затем делаетexecve("/usr/bin/bar",...)

Вы попадете в очень похожую ситуацию, если запустите foo > named_pipe & bar < named_pipe.

Именованный канал — это место встречи процессов для установления каналов друг с другом.


Ситуация аналогична анонимным временным файлам и файлам с именами. Вы можете open("/path/to/dir", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);создать временный файл без имени (O_TMPFILE), как если бы вы открыли "/path/to/dir/tmpfile"с помощью O_CREAT, а затем отсоединили его, оставив вам дескриптор файла для удаленного файла.

Используя linkat,вы даже можете связать этот анонимный файл с файловой системой, дав ему имя, если он был создан с помощью O_TMPFILE.(Однако вы не можете сделать это в Linux для файлов, которые вы создали с именем, а затем удалили.)

2
13.03.2020, 21:33
2 ответа
findmnt -noTARGET "/dev/disk/by-uuid/$UUID"

grep "$(stat -Lc '%#t %#T' "/dev/disk/by-uuid/$UUID" | xargs printf '%d:%d')" /proc/self/mountinfo

awk -v dev="$(stat -Lc '%#t %#T' "/dev/disk/by-uuid/$UUID" | xargs printf '%d:%d')" '$3~dev{print$5}' /proc/self/mountinfo

Для подгонки привязных -креплений:

awk -v dev="$(stat -Lc '%#t %#T' "/dev/disk/by-uuid/$UUID" | xargs printf '%d:%d')" '$3~dev&&$4=="/"{print$5}' /proc/self/mountinfo

Имейте в виду, что устройства можно устанавливать в нескольких местах.

Чудовищность $(stat... | xargs printf)заключается только в том, что stat(1)не может печатать старшие и младшие числа в десятичных . Просто разбор вывода ls -Hlбыл бы, вероятно, лучше (и гораздо более переносимым ).

1
28.04.2021, 23:20
df | grep "^$(readlink -f /dev/disk/by-uuid/$UUID) " |sed 's/^[^%]*% \+//'

Это также работает, когда связаны -монтирования в подкаталогах монтирования, что может запутать некоторые другие потенциальные решения.

(Редактировать:)
Разрешить пробелы в точке монтирования.

(Редактировать2:)
Точка монтирования также может содержать «%».

1
28.04.2021, 23:20

Теги

Похожие вопросы