Eu tenho essa sequência de várias linhas (aspas incluídas):
abc'asdf"
$(dont-execute-this)
foo"bar"''
Como atribuiria a uma variável usando um heredoc no Bash?
Eu preciso preservar novas linhas.
Eu não quero escapar dos caracteres da string, isso seria irritante ...
'EOF'
, com quebras de linha escapadas com o` in the content: if the second line has
comando cd`, volto: " .sh: linha X: cd: comando não encontrado "; mas se eu citar duas vezes"EOF"
; as variáveis bash${A}
não são preservadas como seqüências de caracteres (elas são expandidas); mas então, as quebras de linha são preservadas - e, não tenho problemas ao executar um comandocd
na segunda linha ( e 'EOF' e "EOF" parecem funcionar bem também comeval
, para executar um conjunto de comandos armazenados em uma variável de string ). Felicidades!"EOF"
variável double qouted , se chamado viaeval $VAR
, fará com que todo o restante do script seja comentado, pois aqui $ VAR será visto como uma única linha ; para poder usar os#
comentários do bash no script de múltiplas linhas, aspas duplas também variável noeval call:
eval "$ VAR" `.eval
esse método, mas não o localizei, pois fazia parte de algum pacote comeval
algumas variáveis definidas no arquivo de configuração. Mensagem de erro foi:/usr/lib/network/network: eval: line 153: syntax error: unexpected end of file
. Acabei de mudar para outra solução.Respostas:
Você pode evitar o uso inútil
cat
e lidar melhor com aspas incompatíveis com isso:Se você não citar a variável ao repeti-la, as novas linhas serão perdidas. A citação preserva-os:
Se você deseja usar o recuo para facilitar a leitura no código-fonte, use um traço após os valores menores. O recuo deve ser feito usando apenas guias (sem espaços).
Se, em vez disso, você deseja preservar as guias no conteúdo da variável resultante, é necessário remover a guia
IFS
. O marcador de terminal para o documento aqui (EOF
) não deve ser recuado.As guias podem ser inseridas na linha de comando pressionando Ctrl- V Tab. Se você estiver usando um editor, dependendo de qual, isso também poderá funcionar ou talvez seja necessário desativar o recurso que converte automaticamente as guias em espaços.
fonte
set -o errexit
(akaset -e
) em seu script e usar isso, ele encerrará seu script porqueread
retorna um código de retorno diferente de zero quando atinge o EOF.set -e
e sempre recomendo contra o seu uso. É melhor usar o tratamento adequado de erros.trap
é seu amigo. Outros amigos:else
e||
entre outros.cat
realmente vale a pena nesse caso? Atribuir um heredoc a uma variável comcat
é um idioma bem conhecido. De alguma forma, o usoread
ofusca as coisas, trazendo poucos benefícios.d
e a string vazia;bash
entra-rd''
em colapso para simplesmente-rd
antes deread
ver seus argumentos, entãoVAR
é tratado como o argumento para-d
.read
retornará com um código de saída diferente de zero. Isso torna esse método abaixo do ideal em um script com a verificação de erros ativada (por exemploset -e
).Use $ () para atribuir a saída de
cat
sua variável assim:Certifique-se de delimitar o início de END_HEREDOC com aspas simples.
Observe que o delimitador heredoc final
END_HEREDOC
deve estar sozinho na linha (portanto, o parêntese final fica na próxima linha).Obrigado
@ephemient
pela resposta.fonte
echo "$VAR"
em vez deecho $VAR
.ash
OpenWRT, onderead
não suporta-d
.essa é a variação do método Dennis, parece mais elegante nos scripts.
definição de função:
uso:
desfrutar
O ps criou uma versão de 'loop de leitura' para shells que não suportam
read -d
. deve trabalhar comset -eu
e backticks desemparelhados , mas não foi testado muito bem:fonte
read
loop na função, para evitar o-d ''
bashismo necessário para preservar novas linhas).set -e
conjunto, enquanto a resposta selecionada não. Parece ser por causa dehttp://unix.stackexchange.com/a/265151/20650
não funciona porque você está redirecionando o stdin para algo que não se importa, ou seja, a atribuição
funciona, mas há um tique lá dentro que pode impedi-lo de usar isso. Além disso, você deve realmente evitar o uso de backticks, é melhor usar a notação de substituição de comando
$(..)
.fonte
$(cat <<'END'
lugar. @ Neil: A última nova linha não fará parte da variável, mas o restante será preservado.echo "$A"
(ou seja, colocando $ A entre aspas duplas) e você vê as novas linhas!REM=<< 'REM' ... comment block goes here ... REM
. Ou de forma mais compacta: << 'REM' ...
. Onde "REM" pode ser algo como "NOTES" ou "SCRATCHPAD", etc.Isso não é verdade - você provavelmente está apenas sendo enganado pelo comportamento do eco:
echo $VAR # strips newlines
echo "$VAR" # preserves newlines
fonte
Ramificando a resposta de Neil , muitas vezes você não precisa de um var, pode usar uma função da mesma maneira que uma variável e é muito mais fácil ler do que as
read
soluções embutidas ou baseadas em.fonte
Uma matriz é uma variável, portanto, nesse caso, o mapfile funcionará
Então você pode imprimir assim
fonte
atribuir um valor heredoc a uma variável
usado como argumento de um comando
fonte
echo "$VAR"
Eu me vi tendo que ler uma string com NULL, então aqui está uma solução que lê tudo o que você joga nela. Embora se você realmente esteja lidando com NULL, precisará lidar com isso no nível hexadecimal.
$ cat> read.dd.sh
Prova:
Exemplo HEREDOC (com ^ J, ^ M, ^ I):
fonte
Graças à resposta de dimo414 , isso mostra como sua ótima solução funciona e mostra que você também pode ter aspas e variáveis no texto:
saída de exemplo
test.sh
fonte
fonte