Como posso definir uma variável de ambiente que contenha caracteres de nova linha?

4

Estou tentando definir uma chave RSA como uma variável de ambiente que, como arquivo de texto, contém caracteres de nova linha.

Sempre que eu tentar ler o arquivo e passá-lo para uma variável de ambiente, ele será interrompido apenas no caractere de nova linha na primeira linha. Como posso evitar isso?

    
por notfreshprince 08.06.2017 / 14:54

3 respostas

5

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 printf %s $var , certamente não echo $var que adicionaria 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 .

Com rc , você pode usar a forma ''(separator){...} de substituição de comando com uma lista de separadores vazia:

var = ''(){cat file}
    
por 08.06.2017 / 15:36
0

Se você usa zsh , basta atribuir o conteúdo de um arquivo como este:

p="'cat file_to_be_read'"
    
por 08.06.2017 / 15:15
0

Em shells tradicionais bourne que não suportam os esquemas de manipulação de parâmetros, podemos fazer o seguinte:

NL='
'
var='cat file'
while case 'printf '%s\n' "$var" | wc -l' in "'wc -l < file'" ) break ;; esac
do var=$var$NL; done

Em que primeiro começamos com o conteúdo do arquivo chamado arquivo. Agora, se houver novas linhas finais, somente o loop while entrará em ação. As novas linhas não finais não causarão nenhum problema, já que elas não serão afetadas pela substituição de comandos.

Em cada iteração do loop while, uma nova linha é atrelada à variável e, como isso não envolve o comando sub, também conhecido como ... , não ocorre perda de novas linhas.

    
por 08.06.2017 / 19:41