Eu tenho uma função bash que usa um arquivo como parâmetro, verifica se o arquivo existe e, em seguida, grava qualquer coisa saindo do stdin no arquivo. A solução ingênua funciona bem para texto, mas estou tendo problemas com dados binários arbitrários.
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
. Isso funciona apenas como a primeira coisa que procura stdin no script do shell pai. Basicamente, todo o código de David pode ser reduzido a um único caractere, mas acho quecat -
é mais elegante e menos problemático, porque é compreendido à vista.cat
passo quatro ou cinco segundos juntos, apenas para irritar os fanáticos do UUOCcat
apenas para que as pessoas que insistem em usá-lo necessariamente tenham que fazer ginástica mental para ler o código. Os pipes nomeados também são bons alvos.Para ler um arquivo de texto literalmente, não use plain
read
, que processa a saída de duas maneiras:read
interpreta\
como um caractere de escape; useread -r
para desativar isso.read
divide-se em palavras nos caracteres$IFS
; definaIFS
como uma string vazia para desativar isso.O idioma usual para processar um arquivo de texto linha por linha é
Para obter uma explicação desse idioma, consulte Por que é
while IFS= read
usado com tanta frequência, em vez deIFS=; while read..
? .Para escrever uma string literalmente, não use simplesmente plain
echo
, que processa a string de duas maneiras:echo
processos de barra invertida escapam. (No bash, depende se axpg_echo
opção está definida.)-n
ou-e
(o conjunto exato depende do shell).Uma maneira portátil de imprimir uma string é literalmente
printf
. (Não há maneira melhor no bash, a menos que você saiba que sua entrada não parece uma opçãoecho
.) Use o primeiro formulário para imprimir a sequência exata e o segundo formulário se desejar adicionar uma nova linha.Isso é adequado apenas para o processamento de texto , porque:
Você não pode processar dados binários no shell, mas as versões modernas de utilitários na maioria das unidades podem lidar com dados arbitrários. Para passar toda a entrada para a saída, use
cat
. Entrar na tangenteecho -n ''
é uma maneira complicada e não portátil de não fazer nada;echo -n
seria tão bom (ou não, dependendo do shell) e:
é mais simples e totalmente portátil.ou, mais simples,
Em um script, você geralmente não precisa usar,
>|
poisnoclobber
está desativado por padrão.fonte
Isso fará exatamente o que você deseja:
Observe o uso de memória. Isso lê a entrada de maneira delimitada por nulo.
Se não houver bytes
\0
nulos na entrada, o bash precisará primeiro ler todo o conteúdo da entrada na memória e, em seguida, imprimi-lo.Em relação à sua etapa truncada:
muito mais simples e equivalente é:
fonte