У меня есть функция bash, которая принимает файл в качестве параметра, проверяет, существует ли файл, а затем записывает все, что выходит из stdin, в файл. Наивное решение прекрасно работает для текста, но у меня проблемы с произвольными двоичными данными.
echo -n '' >| "$file" #Truncate the file
while read lines
do # Is there a better way to do this? I would like one...
echo $lines >> "$file"
done
> $file
. Это работает только как первое, что ищет stdin в родительском сценарии оболочки. По сути, весь код Дэвида может быть сведен к одному символу, но я думаю, чтоcat -
он более элегантен и менее проблематичен, потому что он понятен с первого взгляда.cat
натягиваю четыре или пять секунд вместе, чтобы разозлить фанатиков UUOCcat
просто так, чтобы люди, которые настаивают на их использовании, обязательно должны были делать умственную гимнастику, чтобы прочитать код. Именованные каналы также являются хорошими целями.Для того, чтобы прочитать текстовый файл в буквальном смысле, не используйте обычный
read
, который обрабатывает выход двумя способами:read
интерпретирует\
как побег персонажа; используйте,read -r
чтобы отключить это.read
разбивается на слова по символам в$IFS
; установитеIFS
пустую строку, чтобы отключить это.Обычная идиома для обработки текстового файла построчно
Для объяснения этой идиомы см. Почему
while IFS= read
используется так часто, а неIFS=; while read..
? ,Чтобы записать строку буквально, не просто используйте plain
echo
, который обрабатывает строку двумя способами:echo
обратная косая черта. (На bash это зависит от того, установлена лиxpg_echo
опция.)-n
или-e
(точный набор зависит от оболочки).Портативный способ печати строки буквально с
printf
. (В bash нет лучшего способа, если только вы не знаете, что ваш ввод не выглядит как вариантecho
.) Используйте первую форму, чтобы напечатать точную строку, и вторую форму, если вы хотите добавить новую строку.Это подходит только для обработки текста , потому что:
Вы не можете обрабатывать двоичные данные в оболочке, но современные версии утилит в большинстве устройств могут справиться с произвольными данными. Чтобы передать весь ввод на выход, используйте
cat
. Переход по касательнойecho -n ''
- сложный и непереносимый способ ничего не делать;echo -n
будет таким же хорошим (или не зависящим от оболочки),:
более простым и полностью переносимым.или, проще,
В сценарии вам обычно не нужно использовать,
>|
такnoclobber
как по умолчанию он выключен.источник
Это будет делать именно то, что вы хотите:
Обратите внимание на использование памяти, хотя. Это читает входные данные в нулевой форме.
Если на входе нет
\0
нулевых байтов, bash сначала должен прочитать все содержимое ввода в память, а затем вывести его.Относительно вашего усеченного шага:
гораздо проще и эквивалентнее:
источник