О, но sponge
это не единственный вариант; Вам не нужно получать moreutils
, чтобы заставить это работать должным образом. Любой механизм будет работать, если он удовлетворяет следующим двум требованиям:
- Он принимает имя выходного файла в качестве параметра.
- Он создает выходной файл только после обработки всего ввода.
Вы видите, хорошо известная проблема, на которую ссылается OP, заключается в том, что оболочка создаст все файлы, необходимые для работы каналов, прежде чем даже начнет выполнять команды в конвейере, поэтому именно оболочка фактически усекает выходной файл (который, к сожалению, также является входным файлом) еще до того, как какая-либо из команд сможет начать выполнение.
Команда tee
не работает, даже если она удовлетворяет первому требованию, потому что она не удовлетворяет второму требованию: она всегда будет создавать выходной файл сразу после запуска, так что это по сути так же плохо, как создание канала прямо в выходной файл. (На самом деле это еще хуже, потому что его использование вводит недетерминированную случайную задержку перед усечением выходного файла, поэтому вы можете подумать, что он работает, хотя на самом деле это не так.)
Итак, все, что нам нужно для решения этой проблемы - это какая-то команда, которая буферизует все свои входные данные перед созданием какого-либо вывода, и которая способна принимать имя выходного файла в качестве параметра, так что нам не нужно передавать его вывод в выходной файл. Одна такая команда shuf
. Итак, следующее будет выполнять то же самое, что sponge
и:
shuf --output=file --random-source=/dev/zero
Эти --random-source=/dev/zero
приемы части shuf
в делать свое дело , не делая перестановку на всех, так что это будет буфер ввода , не изменяя его.