Shell-Skript: Wie kann ich mehrzeiligen Inhalt in eine Datei schreiben, wenn die Datei nicht vorhanden ist?

9

Ich muss die Datei /opt/nginx/conf.d/default.confmit diesem Inhalt über ein Shell-Skript erstellen und die Datei erstellen, wenn sie nicht vorhanden ist:

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

Wie schreibe ich mehrzeilige Inhalte über ein Shell-Skript?

Ich habe das Verzeichnis erstellt

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

Aber ich weiß nicht, wie ich eine Datei schreiben soll.

user3142695
quelle
1
Sie können> (zum Überschreiben der Datei) oder >> (zum Anhängen, falls bereits vorhanden) verwenden. Beispiel: Echo "Hallo Welt"> file.txt
Rob
Ist das der gesamte statische Text oder sollte ein Teil davon durch einen dynamischen Wert ersetzt werden? (zB Hostname, Port, Stammverzeichnis usw.)
Jeff Schaller
Ich habe gerade Ihre Frage bearbeitet, um sie zu klären, aber ich habe möglicherweise falsch verstanden, was Sie wollten. Möchten Sie den Inhalt zur Datei hinzufügen, auch wenn er bereits vorhanden ist , oder möchten Sie die Datei nur erstellen, wenn sie nicht vorhanden ist? Was soll passieren, wenn die Datei bereits vorhanden ist?
Terdon

Antworten:

13

Zusammenfassung: >>Zum Anhängen verwenden, [ -f file ]zum Testen verwenden.

Versuchen

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
  • Die Syntax cat <<EOFwird als " Hier-Dokument " bezeichnet.
  • $server wird durch seinen Wert ersetzt oder leer, wenn nicht definiert.
  • Wie bereits erwähnt, können Sie einfache Anführungszeichen verwenden 'EOF', um zu vermeiden, dass var ersetzt wird, falls vorhanden.
  • Sie können auch mehrere Echos haben (dies kann schmerzhaft sein, wenn zu viele Echos beibehalten werden).

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

vorangestellt

In Bash gibt es kein direktes Voranstellen. Verwenden Sie auch keine temporäre Datei

mv file file_tmp
cat new_content file_tmp > file
rm file_tmp

oder bearbeiten Sie es

sed -i -e '1r new_file' -e 'wq' file
Archemar
quelle
Wie würde ich einer Datei mehrzeiligen Inhalt voranstellen?
user3142695
1
Eine weitere sinnvolle Änderung wäre, die hier-doc-Grenzwertzeichenfolgen zu zitieren, damit alle Wörter, die $(falls vorhanden) enthalten, nicht als Variablen behandelt werden und daher nicht erweitert werden
Inian
@ user3142695 Am einfachsten wäre es, das Here-Dokument in eine separate Datei und dann catdie beiden Dateien zusammen zu schreiben und das Ergebnis umzubenennen.
Kusalananda
Wenn man viele separate echos ausführen möchte , ist es immer noch effizienter, nur eine Umleitung zu haben, indem man sie in einen Block setzt: { echo "foo"; echo "bar"; echo "baz"; } >file- Auf diese Weise öffnen wir nicht filejedes Mal neu, wenn wir nur eine einzelne Zeile darauf schreiben möchten. und schließen, wenn diese Zeile fertig ist.
Charles Duffy
Eine weitere gute Verwendung dieses Dokuments:cat << EOF | sudo tee /opt/nginx/conf.d/default.conf ...
lp1051
3

Wenn die Datei /opt/nginx/conf.d/default.conf nicht vorhanden ist, drucken Sie (f) die statische Zeichenfolge in die Datei:

[ -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
quelle
1
Ich würde es für printf '%s\n' "first line" "second line"etwas lesbarer halten. Auf diese Weise muss man nicht die ganze Zeichenfolge durchlesen, um herauszufinden, wo die Fluchten sind.
Charles Duffy