Script de Shell: ¿Cómo puedo escribir contenido de varias líneas en el archivo si el archivo no existe?

9

Necesito crear el archivo /opt/nginx/conf.d/default.confcon este contenido a través de script de shell y crear el archivo si no existe:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    root /usr/share/nginx/html;
}

¿Cómo escribo contenido multilínea a través de un script de shell?

Creé el directorio

sudo mkdir -p /opt/nginx/conf.d

Pero no sé cómo escribir un archivo.

usuario3142695
fuente
1
puede usar> (para sobrescribir el archivo) o >> (para agregar si ya existe). ejemplo: echo "hello world"> file.txt
Rob el
¿Es todo el texto estático, o debería sustituirse alguna parte con un valor dinámico? (por ejemplo, nombre de host, puerto, directorio raíz, etc.)
Jeff Schaller
Acabo de editar su pregunta para aclarar, pero es posible que haya entendido mal lo que quería. ¿Desea agregar el contenido al archivo incluso si ya existe , o solo desea crear el archivo si no existe? ¿Qué debería pasar si el archivo ya existe?
terdon

Respuestas:

13

resumen: use >>para agregar, use [ -f file ]para probar.

tratar

if [ ! -f myfile ]
then
   cat <<EOF > myfile
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name $server ;
    root /usr/share/nginx/html;
}
EOF
fi
  • la sintaxis cat <<EOFse llama " documento aquí ".
  • $server será reemplazado por su valor, o vacío si no está definido.
  • como se señaló, puede usar comillas simples 'EOF'para evitar reemplazar var, si corresponde.
  • También puede tener eco múltiple (esto podría ser doloroso de mantener si hay demasiado eco)

    echo "## foo.conf" > foo.conf
    echo param1=hello >> foo.conf
    echo param2=world >> foo.conf
    

pre-pendiente

no hay un antecedente directo en bash, ya sea use un archivo temporal

mv file file_tmp
cat new_content file_tmp > file
rm file_tmp

o editarlo

sed -i -e '1r new_file' -e 'wq' file
Archemar
fuente
¿Cómo anteponer algún contenido multilínea a un archivo?
user3142695
1
Otro cambio sabia que hacer sería citar las cuerdas límite aquí-doc, de manera que cualquier palabra que contiene $(si está presente) no son tratados como variables y por tanto no siendo ampliado
Inian
@ user3142695 Lo más fácil sería escribir el documento aquí en un archivo separado y luego catlos dos archivos juntos y cambiar el nombre del resultado.
Kusalananda
Si uno quiere hacer muchos correos separados echo, es aún más eficiente tener solo una redirección, colocándolos en un bloque: de { echo "foo"; echo "bar"; echo "baz"; } >fileesa manera, no volveremos a abrir filecada vez que solo queremos escribir una sola línea en él, y cerrándolo cuando termine esa línea.
Charles Duffy el
Otro buen uso de este documento:cat << EOF | sudo tee /opt/nginx/conf.d/default.conf ...
lp1051
3

Si el archivo /opt/nginx/conf.d/default.conf no existe, imprima (f) la cadena estática en el archivo:

[ -f /opt/nginx/conf.d/default.conf ] || printf 'server {\n    listen 80 default_server;\n    listen [::]:80 default_server;\n    server_name _;\n    root /usr/share/nginx/html;\n}\n' > /opt/nginx/conf.d/default.conf
Jeff Schaller
fuente
1
Consideraría printf '%s\n' "first line" "second line"quizás un poco más legible; de esa manera no es necesario leer toda la secuencia para descubrir dónde están las escapadas ...
Charles Duffy,