Script di shell: come posso scrivere contenuti su più file se il file non esiste?


9

Ho bisogno di creare il file /opt/nginx/conf.d/default.confcon questo contenuto tramite script di shell e creare il file se non esiste:

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

Come posso scrivere contenuti multilinea tramite uno script di shell?

Ho creato la directory

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

Ma non so come scrivere un file.


1
puoi usare> (per sovrascrivere il file) o >> (per aggiungere se esiste già). esempio: echo "ciao mondo"> file.txt
— Rob

è tutto il testo statico o dovrebbe essere sostituito da una parte di esso con un valore dinamico? (es. nome host, porta, directory principale, ecc.)
— Jeff Schaller

Ho appena modificato la tua domanda per chiarire, ma potrei aver frainteso quello che volevi. Vuoi aggiungere il contenuto del file , anche se esiste già , o si solo desidera creare il file se non esiste? Cosa dovrebbe succedere se il file esiste già?
— terdon

Risposte:


13

sommario: usare >>per aggiungere, usare [ -f file ]per testare.

provare

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 sintassi cat <<EOFsi chiama " qui documento ".
  • $server sarà sostituito dal suo valore o vuoto se non definito.
  • come sottolineato, è possibile utilizzare virgolette singole 'EOF'per evitare di sostituire var, se presente.
  • puoi anche avere più eco (questo potrebbe essere doloroso da mantenere se troppa eco)

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

anteponendo

non esiste un antefatto diretto in bash, né usa il file temporaneo

mv file file_tmp
cat new_content file_tmp > file
rm file_tmp

o modificalo

sed -i -e '1r new_file' -e 'wq' file

Come posso anteporre un contenuto multilinea a un file?
— user3142695

1
Un'altra saggia modifica da fare sarebbe quella di citare le stringhe di limite here-doc, in modo che qualsiasi parola contenente $(se presente) non sia trattata come variabile e quindi non si espanda
— Inian,

@ user3142695 Il modo più semplice sarebbe scrivere il documento qui in un file separato, quindi cati due file insieme e rinominare il risultato.
— Kusalananda

Se uno vuole fare molti messaggi separati echo, è ancora più efficiente avere un solo reindirizzamento, mettendoli in un blocco: { echo "foo"; echo "bar"; echo "baz"; } >file- in questo modo non riapriamo fileogni volta che vogliamo solo scrivere una sola riga, e chiudendolo quando quella linea è terminata.
— Charles Duffy,

Un altro buon uso del documento qui:cat << EOF | sudo tee /opt/nginx/conf.d/default.conf ...
— lp1051,

3

Se il file /opt/nginx/conf.d/default.conf non esiste, quindi stampare (f) la stringa statica nel file:

[ -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

1
Considererei printf '%s\n' "first line" "second line"forse un po 'più leggibile; in questo modo non è necessario leggere l'intera stringa per capire dove si trovano le fughe ..
— Charles Duffy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.