Aqui está um exemplo que gravará o conteúdo em um arquivo em /tmp/yourfilehere
cat << EOF >/tmp/yourfilehere
These contents will be written to the file.This line is indented.
EOF
Observe que o 'EOF' final (The LimitString) não deve ter nenhum espaço em branco na frente da palavra, porque isso significa que LimitStringele não será reconhecido.
Em um script de shell, convém usar o recuo para tornar o código legível, no entanto, isso pode ter o efeito indesejável de recuar o texto no documento aqui. Nesse caso, use <<-(seguido de um traço) para desativar as guias iniciais ( observe que para testar isso, você precisará substituir o espaço em branco inicial por um caractere de tabulação , pois não consigo imprimir caracteres de tabulação reais aqui.)
#!/usr/bin/env bashif true ;then
cat <<- EOF >/tmp/yourfilehere
The leading tab is ignored.
EOF
fi
Se você não quiser interpretar variáveis no texto, use aspas simples:
cat <<'EOF'>/tmp/yourfilehere
The variable $FOO will not be interpreted.
EOF
Para canalizar o heredoc através de um pipeline de comando:
cat <<'EOF'| sed 's/a/b/'
foo
bar
baz
EOF
Resultado:
foo
bbr
bbz
... ou para escrever o heredoc em um arquivo usando sudo:
cat <<'EOF'| sed 's/a/b/'| sudo tee /etc/config_file.conf
foo
bar
baz
EOF
Você nem precisa do Bash, esse recurso também está presente nos shells Bourne / Korn / POSIX.
Janus Troelsen
5
e quanto <<<, como eles são chamados?
precisa
18
@PineappleUndertheSea <<<são chamados 'Here Strings'. Código como tr a-z A-Z <<< 'one two three'resultará na string ONE TWO THREE. Mais informações em en.wikipedia.org/wiki/Here_document#Here_strings
Stefan Lasiewski 10/09/13
8
O EOF final também não deve ter nenhum espaço em branco depois dele. Pelo menos no bash, isso resulta em sendo não reconhecido como delimitador
carpii
10
Uma vez que este heredoc particular, destina-se a ser conteúdo literal, em vez do que contêm substituições, ele deve ser <<'EOF', em vez de <<EOF.
Charles Duffy
152
Em vez de usar cato redirecionamento de E / S, pode ser útil usá-lo tee:
tee newfile <<EOF
line 1
line 2
line 3
EOF
É mais conciso, além do operador de redirecionamento, ele pode ser combinado sudose você precisar gravar em arquivos com permissões de root.
A pergunta (como escrever um documento aqui (aka heredoc ) em um arquivo em um script bash?) Tem (pelo menos) três principais dimensões ou subquestões independentes:
Deseja sobrescrever um arquivo existente, anexá-lo a um arquivo existente ou gravar em um novo arquivo?
Seu usuário ou outro usuário (por exemplo, root) possui o arquivo?
Deseja escrever o conteúdo do seu heredoc literalmente ou fazer com que o bash interprete referências de variáveis dentro do seu heredoc?
(Existem outras dimensões / subquestões que não considero importantes. Considere editar esta resposta para adicioná-las!) Aqui estão algumas das combinações mais importantes das dimensões da pergunta listada acima, com vários identificadores de delimitação diferentes - não há nada sagrado EOF, apenas certifique-se de que a string usada como seu identificador delimitante não ocorra dentro do seu heredoc:
Para substituir um arquivo existente (ou gravar em um novo arquivo) que você possui, substituindo as referências de variáveis dentro do heredoc:
cat << EOF >/path/to/your/file
This line will write to the file.
${THIS} will also write to the file, with the variable contents substituted.
EOF
Para anexar um arquivo existente (ou gravar em um novo arquivo) que você possui, substituindo referências de variáveis dentro do heredoc:
cat << FOE >>/path/to/your/file
This line will write to the file.
${THIS} will also write to the file, with the variable contents substituted.
FOE
Para substituir um arquivo existente (ou gravar em um novo arquivo) que você possui, com o conteúdo literal do heredoc:
cat <<'END_OF_FILE'>/path/to/your/file
This line will write to the file.
${THIS} will also write to the file, without the variable contents substituted.
END_OF_FILE
Para anexar um arquivo existente (ou gravar em um novo arquivo) que você possui, com o conteúdo literal do heredoc:
cat <<'eof'>>/path/to/your/file
This line will write to the file.
${THIS} will also write to the file, without the variable contents substituted.
eof
Para substituir um arquivo existente (ou gravar em um novo arquivo) pertencente à raiz, substituindo as referências de variáveis dentro do heredoc:
cat << until_it_ends | sudo tee /path/to/your/file
This line will write to the file.
${THIS} will also write to the file, with the variable contents substituted.
until_it_ends
Para acrescentar um arquivo existente (ou gravar em um novo arquivo) de propriedade de user = foo, com o conteúdo literal do heredoc:
cat <<'Screw_you_Foo'| sudo -u foo tee -a /path/to/your/file
This line will write to the file.
${THIS} will also write to the file, without the variable contents substituted.Screw_you_Foo
# 6 é o melhor. Mas como você substitui o conteúdo do arquivo existente pelo nº 6?
Aleksandr Makov
2
@Aleksandr Makov: como você substitui o conteúdo do arquivo existente com o # 6? Omita o -a== --append; ou seja, tee -a-> tee. Veja info tee(eu citá-lo aqui, mas comentário marcação é muito limitada.
TomRoche
1
Existe um benefício em # 6 usando gato e tubulação para tee em vez de sudo tee /path/to/your/file << 'Screw_you_Foo'?
precisa
Por que em FOEvez de EOFno exemplo anexado?
Becko
2
@ Becko: apenas para ilustrar que o rótulo é apenas um rótulo. Observe que eu usei um rótulo diferente em cada exemplo.
TomRoche
41
Para aproveitar a resposta de @ Livven , aqui estão algumas combinações úteis.
substituição de variável, guia principal retido, sobrescrever arquivo, eco para stdout
tee /path/to/file <<EOF
${variable}
EOF
nenhuma substituição de variável , guia principal retida, sobrescrever arquivo, eco para stdout
tee /path/to/file <<'EOF'
${variable}
EOF
substituição de variável, guia inicial removido , sobrescrever arquivo, eco para stdout
tee /path/to/file <<-EOF
${variable}
EOF
substituição de variável, guia principal retido, anexado ao arquivo , eco ao stdout
tee -a /path/to/file <<EOF
${variable}
EOF
substituição de variável, guia principal retido, sobrescrever arquivo, sem eco para stdout
tee /path/to/file <<EOF >/dev/null
${variable}
EOF
o acima pode ser combinado com sudotambém
sudo -u USER tee /path/to/file <<EOF
${variable}
EOF
Não precisa dos parênteses: cat << END > afileseguido pelo heredoc funciona perfeitamente bem.
Glenn Jackman
Obrigado, isso realmente resolveu outro problema que encontrei. Depois de alguns documentos aqui, houve alguns problemas. Eu acho que tinha a ver com os parênteses, como nos conselhos acima.
Joshua Enfield
2
Isso não vai funcionar. O redirecionamento de saída precisa estar no final da linha que começa com, catcomo mostrado na resposta aceita.
Pausado até novo aviso.
2
@DennisWilliamson Funciona, é para isso que servem os parênteses. Toda a catroda dentro de um subnível, e toda a saída do subshell é redirecionado para o arquivo
Izkata
2
@ Izkata: Se você olhar para o histórico de edições desta resposta, os parênteses foram removidos antes de eu fazer o meu comentário e adicionados novamente. o comentário de glenn jackman (e o meu) se aplica.
Pausado até novo aviso.
3
Como exemplo, você pode usá-lo:
Primeiro (fazendo a conexão ssh):
while read pass port user ip files directs;do
sshpass -p$pass scp -o 'StrictHostKeyChecking no'-P $port $files $user@$ip:$directs
done<<____HERE
PASS PORT USER IP FILES DIRECTS
..................
PASS PORT USER IP FILES DIRECTS
____HERE
Segundo (executando comandos):
while read pass port user ip;do
sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1
COMMAND 1...
COMMAND n
ENDSSH1
done<<____HERE
PASS PORT USER IP
............
PASS PORT USER IP
____HERE
Terceiro (executando comandos):
Script=$'
#Your commands
'while read pass port user ip;do
sshpass -p$pass ssh -o 'StrictHostKeyChecking no'-p $port $user@$ip "$Script"done<<___HERE
PASS PORT USER IP
............
PASS PORT USER IP
___HERE
Quarto (usando variáveis):
while read pass port user ip fileoutput;do
sshpass -p$pass ssh -o 'StrictHostKeyChecking no'-p $port $user@$ip fileinput=$fileinput 'bash -s'<<ENDSSH1
#Your command > $fileinput#Your command > $fileinput
ENDSSH1
done<<____HERE
PASS PORT USER IP FILE-OUTPUT
...............
PASS PORT USER IP FILE-OUTPUT
____HERE
Respostas:
Leia o Advanced Bash-Scripting Guide Capítulo 19. Aqui Documentos .
Aqui está um exemplo que gravará o conteúdo em um arquivo em
/tmp/yourfilehere
Observe que o 'EOF' final (The
LimitString
) não deve ter nenhum espaço em branco na frente da palavra, porque isso significa queLimitString
ele não será reconhecido.Em um script de shell, convém usar o recuo para tornar o código legível, no entanto, isso pode ter o efeito indesejável de recuar o texto no documento aqui. Nesse caso, use
<<-
(seguido de um traço) para desativar as guias iniciais ( observe que para testar isso, você precisará substituir o espaço em branco inicial por um caractere de tabulação , pois não consigo imprimir caracteres de tabulação reais aqui.)Se você não quiser interpretar variáveis no texto, use aspas simples:
Para canalizar o heredoc através de um pipeline de comando:
Resultado:
... ou para escrever o heredoc em um arquivo usando
sudo
:fonte
<<<
, como eles são chamados?<<<
são chamados 'Here Strings'. Código comotr a-z A-Z <<< 'one two three'
resultará na stringONE TWO THREE
. Mais informações em en.wikipedia.org/wiki/Here_document#Here_strings<<'EOF'
, em vez de<<EOF
.Em vez de usar
cat
o redirecionamento de E / S, pode ser útil usá-lotee
:É mais conciso, além do operador de redirecionamento, ele pode ser combinado
sudo
se você precisar gravar em arquivos com permissões de root.fonte
> /dev/null
no final da primeira linha para impedir que o conteúdo do arquivo aqui seja exibido em stdout quando ele é criado.sudo
, e não por causa de sua brevidade :-)man tee
. Use o-a
sinalizador para acrescentar em vez de substituir.Nota:
A pergunta (como escrever um documento aqui (aka heredoc ) em um arquivo em um script bash?) Tem (pelo menos) três principais dimensões ou subquestões independentes:
root
) possui o arquivo?(Existem outras dimensões / subquestões que não considero importantes. Considere editar esta resposta para adicioná-las!) Aqui estão algumas das combinações mais importantes das dimensões da pergunta listada acima, com vários identificadores de delimitação diferentes - não há nada sagrado
EOF
, apenas certifique-se de que a string usada como seu identificador delimitante não ocorra dentro do seu heredoc:Para substituir um arquivo existente (ou gravar em um novo arquivo) que você possui, substituindo as referências de variáveis dentro do heredoc:
Para anexar um arquivo existente (ou gravar em um novo arquivo) que você possui, substituindo referências de variáveis dentro do heredoc:
Para substituir um arquivo existente (ou gravar em um novo arquivo) que você possui, com o conteúdo literal do heredoc:
Para anexar um arquivo existente (ou gravar em um novo arquivo) que você possui, com o conteúdo literal do heredoc:
Para substituir um arquivo existente (ou gravar em um novo arquivo) pertencente à raiz, substituindo as referências de variáveis dentro do heredoc:
Para acrescentar um arquivo existente (ou gravar em um novo arquivo) de propriedade de user = foo, com o conteúdo literal do heredoc:
fonte
-a
==--append
; ou seja,tee -a
->tee
. Vejainfo tee
(eu citá-lo aqui, mas comentário marcação é muito limitada.sudo tee /path/to/your/file << 'Screw_you_Foo'
?FOE
vez deEOF
no exemplo anexado?Para aproveitar a resposta de @ Livven , aqui estão algumas combinações úteis.
substituição de variável, guia principal retido, sobrescrever arquivo, eco para stdout
nenhuma substituição de variável , guia principal retida, sobrescrever arquivo, eco para stdout
substituição de variável, guia inicial removido , sobrescrever arquivo, eco para stdout
substituição de variável, guia principal retido, anexado ao arquivo , eco ao stdout
substituição de variável, guia principal retido, sobrescrever arquivo, sem eco para stdout
o acima pode ser combinado com
sudo
tambémfonte
Quando permissões de raiz são necessárias
Quando permissões de raiz são necessárias para o arquivo de destino, use em
|sudo tee
vez de>
:fonte
Para futuras pessoas que possam ter esse problema, o seguinte formato funcionou:
fonte
cat << END > afile
seguido pelo heredoc funciona perfeitamente bem.cat
como mostrado na resposta aceita.cat
roda dentro de um subnível, e toda a saída do subshell é redirecionado para o arquivoComo exemplo, você pode usá-lo:
Primeiro (fazendo a conexão ssh):
Segundo (executando comandos):
Terceiro (executando comandos):
Quarto (usando variáveis):
fonte
Eu gosto deste método para concisão, legibilidade e apresentação em um script recuado:
Onde
→
está um tabpersonagem.fonte