Я думаю, вы путаете синтаксис оболочки для конвейеров и базовое системное программирование 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 )stdout
на запись fd с помощьюdup2(pipefd[1], 1)
execve("/usr/bin/foo",...)
fork()
вернул не -0 дочерний PID )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 для файлов, которые вы создали с именем, а затем удалили.)
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
был бы, вероятно, лучше (и гораздо более переносимым ).
df | grep "^$(readlink -f /dev/disk/by-uuid/$UUID) " |sed 's/^[^%]*% \+//'
Это также работает, когда связаны -монтирования в подкаталогах монтирования, что может запутать некоторые другие потенциальные решения.
(Редактировать:)
Разрешить пробелы в точке монтирования.
(Редактировать2:)
Точка монтирования также может содержать «%».