¿Cómo puedo escribir un heredoc en un archivo en un script Bash?

Resuelto Joshua Enfield asked hace 14 años • 11 respuestas

¿Cómo puedo escribir un documento aquí en un archivo en un script Bash?

Joshua Enfield avatar Jun 02 '10 03:06 Joshua Enfield
Aceptado

Lea el Capítulo 19 de la Guía avanzada de secuencias de comandos Bash. 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 (The LimitString) no debe tener ningún espacio en blanco delante de la palabra, porque significa que LimitStringno será reconocido.

En un script de shell, es posible que desee utilizar sangría para que el código sea legible; sin embargo, esto puede tener el efecto no deseado de sangrar el texto dentro de su documento aquí. En este caso, use <<-(seguido de un guión) para deshabilitar las pestañas iniciales ( tenga en cuenta que para probar esto deberá 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

Producción:

foo
bbr
bbz

... o escribir el heredoc en un archivo usando sudo:

cat <<'EOF' |  sed 's/a/b/' | sudo tee /etc/config_file.conf
foo
bar
baz
EOF
Stefan Lasiewski avatar Jun 02 '2010 03:06 Stefan Lasiewski

En lugar de utilizar catuna redirección de E/S, podría resultar útil utilizar tee:

tee newfile <<EOF
line 1
line 2
line 3
EOF

Es más conciso y, a diferencia del operador de redireccionamiento, se puede combinar con él sudosi necesita escribir en archivos con permisos de root.

Livven avatar Jun 13 '2013 17:06 Livven

Nota:

  • Lo siguiente condensa y organiza otras respuestas en este hilo, especialmente el excelente trabajo de Stefan Lasiewski y Serge Stroobandt.
  • Lasiewski y yo recomendamos el capítulo 19 (aquí documentos) de la Guía avanzada de secuencias de comandos Bash

La pregunta (¿cómo escribir un documento aquí (también conocido como heredoc ) en un archivo en un script bash?) tiene (al menos) 3 dimensiones o subpreguntas independientes principales:

  1. ¿Quiere sobrescribir un archivo existente, agregarlo a un archivo existente o escribir en un archivo nuevo?
  2. ¿Su usuario u otro usuario (por ejemplo, root) es propietario del archivo?
  3. ¿Quiere escribir el contenido de su heredoc literalmente o que bash interprete las referencias de variables dentro de su heredoc?

(Hay otras dimensiones/subpreguntas que no considero importantes. ¡Considere editar esta respuesta para agregarlas!) Estas son algunas de las combinaciones más importantes de las dimensiones de la pregunta enumeradas anteriormente, con varios identificadores delimitadores diferentes: no hay nada sagrado acerca de EOF, solo asegúrese de que la cadena que usa como identificador delimitador no aparezca dentro de su documento heredoc:

  1. Para sobrescribir un archivo existente (o escribir en un archivo nuevo) de su propiedad, sustituyendo 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
    
  2. Para agregar un archivo existente (o escribir en un archivo nuevo) de su propiedad, sustituyendo 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
    
  3. Para sobrescribir un archivo existente (o escribir en un archivo nuevo) de su propiedad, 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
    
  4. Para agregar un archivo existente (o escribir en un archivo nuevo) de su propiedad, 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
    
  5. Para sobrescribir un archivo existente (o escribir en un archivo nuevo) propiedad de root, sustituyendo 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
    
  6. Para agregar un archivo existente (o escribir en un archivo nuevo) propiedad de usuario=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
    
TomRoche avatar Sep 18 '2014 03:09 TomRoche

Para aprovechar la respuesta de @Livven , aquí hay algunas combinaciones útiles.

  1. sustitución de variables, retención de la pestaña inicial, sobrescritura del archivo, eco en la salida estándar

    tee /path/to/file <<EOF
    ${variable}
    EOF
    
  2. sin sustitución de variables , se conserva la pestaña inicial, se sobrescribe el archivo y se hace eco en la salida estándar

    tee /path/to/file <<'EOF'
    ${variable}
    EOF
    
  3. sustitución de variables, pestaña inicial eliminada , sobrescritura de archivos, eco a la salida estándar

    tee /path/to/file <<-EOF
        ${variable}
    EOF
    
  4. sustitución de variables, pestaña inicial retenida, agregar al archivo , eco a la salida estándar

    tee -a /path/to/file <<EOF
    ${variable}
    EOF
    
  5. sustitución de variables, pestaña inicial retenida, sobrescritura del archivo, sin eco en la salida estándar

    tee /path/to/file <<EOF >/dev/null
    ${variable}
    EOF
    
  6. sudolo anterior también se puede combinar con

    sudo -u USER tee /path/to/file <<EOF
    ${variable}
    EOF
    
go2null avatar Aug 02 '2016 21:08 go2null

Cuando se requieren permisos de root

Cuando se requieren permisos de root para el archivo de destino, utilice |sudo teeen lugar de >:

cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF

cat << "EOF" |sudo tee /tmp/yourprotectedfilehere
The variable $FOO *will* be interpreted.
EOF
Serge Stroobandt avatar Feb 13 '2014 20:02 Serge Stroobandt