Como posso impedir que a substituição de comandos remova o NUL e a (s) nova (s) linha (s) inicial (ais)?

1

Uma resposta do Stackoverflow diz que a substituição de comandos remove o NUL  e traçando nova (s) linha (s), e fornece os seguintes comandos para evitar que isso aconteça,

FILE="$(mktemp)"
printf "a
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") 
\n" > "$FILE" S="$(uuencode -m "$FILE" /dev/stdout)" uudecode -o /dev/stdout <(printf "$S") | od -tx1 rm "$FILE"

cat "$FILE" não remove NUL ou novas linhas finais. Pode substituir

FILE="$(mktemp)"
printf "a
FILE="$(mktemp)"
printf "a
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") 
\n" > "$FILE" S="$(uuencode -m "$FILE" /dev/stdout)" uudecode -o /dev/stdout <(printf "$S") | od -tx1 rm "$FILE"
\n" > "$FILE" cat "$FILE" | od -tx1 rm "$FILE"

para que os comandos sugeridos possam ser simplificados para

FILE="$(mktemp)"
printf "a%pre%\n" > "$FILE"
cat "$FILE" | od -tx1
rm "$FILE"

?

    
por Ben 20.11.2018 / 21:30

1 resposta

3

O importante sobre a questão vinculada está no título: "Como ler um arquivo em uma variável no shell?" A resposta é que você não, não no Bash, já que o Bash não consegue lidar com os bytes NUL.

Isso pode ser contornado de alguma forma codificando o arquivo para que os NULs literais sejam representados de outra maneira. Isso poderia ser codificação Base64 (como uuencode -m ), ou codificação de URL, ou qualquer outra coisa. Isso é o que a resposta lá faz, ele codifica o arquivo usando uuencode para uma string "mais agradável" sem NULs, então armazena isso na variável S . (Um S=$(cat file) puro não funcionaria, ele tentaria armazenar o arquivo inalterado, com os bytes NUL e tudo mais.) A ação oposta de decodificar o arquivo também é mostrada.

Normalmente, não há muita necessidade para isso, e provavelmente se deve tentar evitar isso. É mais fácil processar os arquivos, mantendo-os como arquivos e processando-os com ferramentas externas, conforme necessário. Mas a questão era especificamente sobre como armazenar um arquivo (um arquivo arbitrário) em uma variável shell. Em teoria, pode haver algum uso para isso. Talvez.

Embora no seu caso, se você quiser apenas imprimir uma string fixa, então printf "a\NNN\n" > $filename ou similar funciona bem, já que qualquer byte pode ser representado com %code% escapes.

    
por 20.11.2018 / 22:27