¿Cómo puedo escribir un heredoc a un archivo en el script Bash?
¿Cómo puedo escribir un documento here en un archivo en el script Bash?
7 answers
Lea la Guía Avanzada de Scripts de Bash Capítulo 19. Aquí Documentos.
Aquí hay un ejemplo que escribirá el contenido en un archivo en /tmp/yourfilehere
cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
This line is indented.
EOF
Tenga en cuenta que el 'EOF' final (El LimitString
) no debe tener ningún espacio en blanco delante de la palabra, porque significa que el LimitString
no será reconocido.
En un script de shell, es posible que desee usar sangría para hacer que el código sea legible, sin embargo, esto puede tener el efecto no deseado de sangría del texto dentro su documento aquí. En este caso, use <<-
(seguido de un guion) para deshabilitar las pestañas iniciales ( Tenga en cuenta que para probar esto necesitará reemplazar el espacio en blanco inicial con un carácter de tabulación, ya que no puedo imprimir caracteres de tabulación reales aquí.)
#!/usr/bin/env bash
if true ; then
cat <<- EOF > /tmp/yourfilehere
The leading tab is ignored.
EOF
fi
Si no desea interpretar variables en el texto, utilice comillas simples:
cat << 'EOF' > /tmp/yourfilehere
The variable $FOO will not be interpreted.
EOF
Para canalizar el heredoc a través de una canalización de comandos:
cat <<'EOF' | sed 's/a/b/'
foo
bar
baz
EOF
Salida:
foo
bbr
bbz
... o para escribir el el heredoc a un archivo usando sudo
:
cat <<'EOF' | sed 's/a/b/' | sudo tee /etc/config_file.conf
foo
bar
baz
EOF
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-27 09:44:37
En lugar de usar cat
y la redirección de E/S, podría ser útil usar tee
en su lugar:
tee newfile <<EOF
line 1
line 2
line 3
EOF
Es más conciso, además, a diferencia del operador de redirección, se puede combinar con sudo
si necesita escribir en archivos con permisos de root.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-13 17:35:13
Nota:
- lo siguiente condensa y organiza otras respuestas en este hilo, esp el excelente trabajo de Stefan Lasiewski y Serge Stroobandt
- Lasiewski y yo recomendamos Ch 19 (Aquí Documentos) en la Guía Avanzada de Bash-Scripting
La pregunta (¿cómo escribir un documento here (aka heredoc) en un archivo en un script bash?) tiene (al menos) 3 dimensiones independientes principales o preguntas:
- ¿Desea sobrescribir un archivo existente, anexarlo a un archivo existente o escribir en un archivo nuevo?
- ¿Su usuario u otro usuario (por ejemplo,
root
) posee el archivo? - ¿Desea escribir el contenido de su heredoc literalmente, o hacer que bash interprete las referencias de variables dentro de su heredoc?
(Hay otras dimensiones/subcuestiones que no considero importantes. ¡Considera editar esta respuesta para añadirlas! Aquí están algunos de los combinaciones más importantes de las dimensiones de la pregunta mencionada anteriormente, con varios identificadores delimitadores diferentes {no hay nada sagrado en EOF
, solo asegúrese de que la cadena que usa como su identificador delimitador no ocurra dentro de su heredoc:
-
Para sobrescribir un archivo existente (o escribir en un archivo nuevo) que usted posee, sustituyendo las referencias de variables dentro del 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 un archivo existente (o escribir a un nuevo archivo) que usted posee, sustituyendo las referencias de variables dentro del 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 sobrescribir un archivo existente (o escribir en un archivo nuevo) que usted posee, con el contenido literal del 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 un archivo existente (o escribir en un nuevo archivo) que usted posee, con el contenido literal del 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 sobrescribir un archivo existente (o escribir en un nuevo archivo) propiedad de root, sustituyendo las referencias de variables dentro del 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 anexar un archivo existente (o escribir en un nuevo archivo) propiedad de user = foo, con el contenido literal del 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:25
Para construir sobre la respuesta de @Livven, aquí hay algunas combinaciones útiles.
-
Sustitución de variables, pestaña inicial retenida, sobrescribir archivo, echo a stdout
tee /path/to/file <<EOF ${variable} EOF
-
Sin sustitución de variables , se conserva la pestaña inicial, sobrescribe el archivo, hace eco a la salida estándar
tee /path/to/file <<'EOF' ${variable} EOF
-
Sustitución de variables, pestaña inicial eliminada , sobrescribir archivo, echo a salida estándar
tee /path/to/file <<-EOF ${variable} EOF
-
Sustitución de variables, pestaña inicial retained, append to file , echo to stdout
tee -a /path/to/file <<EOF ${variable} EOF
-
Sustitución de variables, tabulación inicial retenida, sobrescribir archivo, sin eco a salida estándar
tee /path/to/file <<EOF >/dev/null ${variable} EOF
-
Lo anterior se puede combinar con
sudo
tambiénsudo -u USER tee /path/to/file <<EOF ${variable} EOF
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36
Cuando se requieren permisos de root
Cuando se requieren permisos de root para el archivo de destino, use |sudo tee
en lugar de >
:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-21 13:55:57
Para las futuras personas que puedan tener este problema, el siguiente formato funcionó:
(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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-03 14:58:43
Como ejemplo podría usarlo:
Primero (hacer una conexión 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 (ejecutar 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
Tercero (ejecutar 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
Forth (usando variables):
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-16 10:27:52