Note que, exceto em zsh, as variáveis do shell não podem armazenar seqüências arbitrárias de bytes. Variáveis em todos os outros shells não podem conter o byte NUL. E com o yash
, eles não podem conter bytes que não formam caracteres válidos.
Para arquivos que não contêm bytes NUL, em shells semelhantes a POSIX, você pode fazer:
var=$(cat file; echo .); var=${var%.}
Adicionamos um .\n
e removemos o .
à direita para contornar o fato de que $(...)
remove todos os caracteres de nova linha.
O acima também funcionaria em zsh
para arquivos que contêm NULs, embora em zsh
você também possa usar a matriz associativa especial $mapfile
:
zmodload zsh/mapfile
var=$mapfile[file]
Em zsh ou bash, você também pode usar:
{ IFS= read -rd '' var || :; } < file
Que lê até o primeiro byte NUL. Ele retornará um status de saída diferente de zero, a menos que um byte NUL seja encontrado. Usamos o grupo de comando para poder, pelo menos, informar os erros ao abrir o arquivo, mas não poderemos detectar erros de leitura por meio do status de saída.
Lembre-se de citar essa variável quando passada para outros comandos. Newline está no valor padrão de $IFS
, então faria com que o conteúdo da variável fosse dividido quando deixado sem aspas em contextos de lista em shells semelhantes a POSIX que não fossem zsh (sem mencionar os outros problemas com outros caracteres de $IFS
ou curingas ).
Então:
printf %s "$var"
por exemplo (não , certamente não printf %s $var
que adicionaria echo $var
echo
além dos split + glob). / p>
Com shells não POSIX:
Bourne shell:
O shell da bourne não suportava a forma $(...)
nem o operador ${var%pattern}
, por isso pode ser bastante difícil de conseguir lá. Uma abordagem é usar eval
e citando:
eval "var=''printf \' | cat file - | awk -v RS=\' -v ORS= -v b='\\' '
NR > 1 {print RS b RS RS}; {print}; END {print RS}''"
Com (t)csh
, é ainda pior, veja lá .
Com rc
, você pode usar a forma ''(separator){...}
de substituição de comando com uma lista de separadores vazia:
var = ''(){cat file}