Файл fifo
— это просто тип файла, который при открытии как для чтения, так и для записи создает экземпляр канала, как это сделал бы системный вызов ()канала.
По крайней мере, в Linux данные, проходящие через этот канал, вообще не сохраняются в файловой системе (только в ядре в виде памяти ядра ). А атрибут size файла fifo не имеет значения и всегда равен 0.
В Linux вы можете изменить размер буфера канала (, независимо от того, был ли этот канал создан с помощью pipe()
или путем открытия файла FIFO )с помощью F_SETPIPE_SZ
fcntl()
, хотя для непривилегированных пользователей это связано по /proc/sys/fs/pipe-max-size
. Любой писатель или читатель канала может выдать это fcntl()
, хотя писателю имеет больше смысла делать это. В случае именованного канала вам нужно будет сделать это для каждого канала, созданного через файл fifo.
$ mkfifo fifo
$ exec 3<> fifo # instantiate the pipe
$ seq 20000 > fifo
^C # seq hangs because it's trying to write more than 64KiB
$ exec 3<&- 3<> fifo # close the first pipe and instantiate a new one
$ (perl -MFcntl -e 'fcntl(STDOUT, 1031, 1048576)'; seq 20000) > fifo
$ # went through this time
Выше я использовал perl
для выдачи fcntl()
, жестко закодировав значениеF_SETPIPE_SZ
(1031 в моей системе ).
Поскольку выходной файл создается до запуска конвейера, предотвратить создание выходного файла невозможно.
Таким образом, единственный шанс, который у вас есть, — это снова удалить файл в случае сбоя конвейера.
Akshism
(ловушку ERR
), которая поддерживается в bash
, можно использовать, если вы ищете решение сценария.
В этом случае настоятельно рекомендую использовать
set -o noclobber
Предотвратить затирание файла, если он уже существует.
Таким образом, рекомендуемый код будет выглядеть так:
set -o noclobber
trap 'rm -rf test.gz' ERR
some_cmd | gzip > test.gz
if ! will_fail | gzip >test.gz; then
rm -f test.gz
fi
Это не препятствует созданию файла (перенаправление создаст файл до выполнения конвейера ), но удалит файл в случае сбоя конвейера (при условии, что pipefail
установлено, так как оно находится в примере ).