Eu quero ler um arquivo e salvá-lo em variável, mas preciso manter a variável e não apenas imprimir o arquivo. Como posso fazer isso? Eu escrevi este script mas é'não é bem o que eu precisava:
#!/bin/sh
while read LINE
do
echo $LINE
done <$1
echo 11111-----------
echo $LINE
No meu script, posso dar o nome do arquivo como parâmetro, então, se o arquivo contém "aaaa" por exemplo, ele imprimiria isto:
aaaa
11111-----
Mas isso só imprime o arquivo na tela, e eu quero salvá-lo em uma variável! Existe uma maneira fácil de fazer isto?
Em cross-platform, o menor denominador comum sh
que você utiliza:
#!/bin/sh
value=`cat config.txt`
echo "$value"
No bash
ou zsh
, ler um arquivo inteiro em uma variável sem invocar o cat
:
#!/bin/bash
value=$(<config.txt)
echo "$value"
Invocar cat
em bash
ou zsh
para slurp um arquivo seria considerado um Uso inútil de gato.
Note que não é necessário citar a substituição do comando para preservar as novas linhas.
Veja: Bash Hacker's Wiki - Substituição de comandos - Especialidades.
**Duas armadilhas importantes***
que foram ignoradas por outras respostas até agora:
**Retirada da nova linha de expansão do comando***
Isto é um problema para o:
value="$(cat config.txt)"
mas não para soluções baseadas em "leitura".
A expansão do comando remove as linhas novas:
S="$(printf "a\n")"
printf "$S" | od -tx1
Saídas:
0000000 61
0000001
Isto quebra o método ingénuo de leitura a partir de ficheiros:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
POSIX workaround: anexar um char extra ao comando de expansão e removê-lo mais tarde:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Saídas:
0000000 61 0a 0a
0000003
Quase que o POSIX funciona: Codificação ASCII. Veja abaixo.
**NUL remoção de caracteres***
Não há uma forma sã de armazenar caracteres NUL nas variáveis.
Isto afecta tanto a expansão como as soluções "lidas", e eu não'não conheço nenhuma boa solução de trabalho para isso.
Exemplo:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Saídas:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ha, o nosso NUL desapareceu!
Soluções:
Codificação ASCII. Veja abaixo.
utilize a extensão bash $""
literals:
S=$"a\0b"
printf "$S" | od -tx1
Só funciona para os literais, por isso não é útil para ler a partir de ficheiros.
**Trabalho para as armadilhas***
Armazene uma versão codificada uuencode base64 do arquivo na variável, e decodifique antes de cada uso:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Saída:
0000000 61 00 0a
0000003
uuencode e udecode são POSIX 7 mas não no Ubuntu 12.04 por padrão (pacote sharutils')... Eu não't vejo uma alternativa ao POSIX 7 para o processo bash
<()` extensão de substituição, exceto a escrita em outro arquivo...
Claro que isso é lento e inconveniente, então acho que a verdadeira resposta é: don't use Bash se o arquivo de entrada puder conter caracteres NUL.