bash останавливает канал, если команда не удалась

Файл fifo— это просто тип файла, который при открытии как для чтения, так и для записи создает экземпляр канала, как это сделал бы системный вызов ()канала.

По крайней мере, в Linux данные, проходящие через этот канал, вообще не сохраняются в файловой системе (только в ядре в виде памяти ядра ). А атрибут size файла fifo не имеет значения и всегда равен 0.

В Linux вы можете изменить размер буфера канала (, независимо от того, был ли этот канал создан с помощью pipe()или путем открытия файла FIFO )с помощью F_SETPIPE_SZfcntl(), хотя для непривилегированных пользователей это связано по /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 в моей системе ).

-1
15.04.2020, 09:30
2 ответа

Поскольку выходной файл создается до запуска конвейера, предотвратить создание выходного файла невозможно.

Таким образом, единственный шанс, который у вас есть, — это снова удалить файл в случае сбоя конвейера.

Akshism(ловушку ERR), которая поддерживается в bash, можно использовать, если вы ищете решение сценария.

В этом случае настоятельно рекомендую использовать

set -o noclobber

Предотвратить затирание файла, если он уже существует.

Таким образом, рекомендуемый код будет выглядеть так:

set -o noclobber

trap 'rm -rf test.gz' ERR

some_cmd | gzip > test.gz
2
19.03.2021, 02:29
if ! will_fail | gzip >test.gz; then
        rm -f test.gz
fi

Это не препятствует созданию файла (перенаправление создаст файл до выполнения конвейера ), но удалит файл в случае сбоя конвейера (при условии, что pipefailустановлено, так как оно находится в примере ).

1
19.03.2021, 02:29

Теги

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