Como posso escrever um documento aqui em um arquivo no script Bash?
Como posso escrever um documento aqui em um arquivo no script Bash?
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
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 LimitString
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.)
#!/usr/bin/env bash
if 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
<<<
, como eles são chamados?
<<<
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
<<'EOF'
, em vez de <<EOF
.
Em vez de usar cat
o 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 sudo
se você precisar gravar em arquivos com permissões de root.
> /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:
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
-a
== --append
; ou seja, tee -a
-> tee
. Veja info tee
(eu citá-lo aqui, mas comentário marcação é muito limitada.
sudo tee /path/to/your/file << 'Screw_you_Foo'
?
FOE
vez de EOF
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
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 sudo
também
sudo -u USER tee /path/to/file <<EOF
${variable}
EOF
Quando permissões de raiz são necessárias para o arquivo de destino, use em |sudo tee
vez de >
:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF
Para futuras pessoas que possam ter esse problema, o seguinte formato funcionou:
(cat <<- _EOF_
LogFile /var/log/clamd.log
LogTime yes
DatabaseDirectory /var/lib/clamav
LocalSocket /tmp/clamd.socket
TCPAddr 127.0.0.1
SelfCheck 1020
ScanPDF yes
_EOF_
) > /etc/clamd.conf
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 arquivo
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