Skrypt powłoki: Jak zapisać zawartość wielowierszową do pliku, jeśli plik nie istnieje?

9

Muszę utworzyć plik /opt/nginx/conf.d/default.confz tą zawartością za pomocą skryptu powłoki i utworzyć plik, jeśli nie istnieje:

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

Jak pisać treści wielowierszowe za pomocą skryptu powłoki?

Stworzyłem katalog

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

Ale nie wiem jak napisać plik.

użytkownik3142695
źródło
1
możesz użyć> (aby zastąpić plik) lub >> (aby dołączyć, jeśli już istnieje). przykład: echo „hello world”> plik.txt
Rob
czy to cały tekst statyczny, czy też jakakolwiek jego część powinna być zastąpiona wartością dynamiczną? (np. nazwa hosta, port, katalog główny itp.)
Jeff Schaller
Właśnie zredagowałem twoje pytanie, aby wyjaśnić, ale mogłem nie rozumieć, czego chciałeś. Chcesz dodać zawartość do pliku, nawet jeśli już istnieje , czy też tylko chce utworzyć plik, jeśli nie istnieje? Co powinno się stać, jeśli plik już istnieje?
terdon

Odpowiedzi:

13

Podsumowanie: użyj >>do dołączenia, użyj [ -f file ]do przetestowania.

próbować

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
  • składnia cat <<EOFnazywa się „ dokumentem tutaj ”.
  • $server zostanie zastąpiony jego wartością lub pusty, jeśli nie zostanie zdefiniowany.
  • jak wskazano, możesz użyć pojedynczego cudzysłowu, 'EOF'aby uniknąć zamiany var, jeśli istnieje.
  • możesz także mieć wiele ech (może to być bolesne w utrzymaniu, jeśli zbyt wiele ech)

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

przygotowując

w bash nie ma bezpośredniego dodania, albo użyj pliku tymczasowego

mv file file_tmp
cat new_content file_tmp > file
rm file_tmp

lub edytuj

sed -i -e '1r new_file' -e 'wq' file
Archemar
źródło
Jak dodać do pliku trochę treści wielowierszowej?
user3142695,
1
Inną mądrą zmianą byłoby zacytowanie ciągów limitów tutaj-doc, aby wszelkie słowa zawierające $(jeśli są obecne) nie były traktowane jako zmienne i dlatego nie były
interpretowane
@ user3142695 Najłatwiej byłoby napisać dokument tutaj do osobnego pliku, a następnie catdo dwóch plików razem i zmienić nazwę wyniku.
Kusalananda
Jeśli ktoś chce zrobić wiele osobnych echoplików, bardziej efektywne jest posiadanie tylko jednego przekierowania, umieszczając je w bloku: { echo "foo"; echo "bar"; echo "baz"; } >file- w ten sposób nie otwieramy się ponownie za filekażdym razem, gdy chcemy po prostu napisać do niego jedną linię, i zamykając go, gdy ta linia jest skończona.
Charles Duffy,
Kolejne dobre wykorzystanie tego dokumentu:cat << EOF | sudo tee /opt/nginx/conf.d/default.conf ...
lp1051
3

Jeśli plik /opt/nginx/conf.d/default.conf nie istnieje, wydrukuj (f) ciąg statyczny do pliku:

[ -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
źródło
1
Uważam, że printf '%s\n' "first line" "second line"może być nieco bardziej czytelny; w ten sposób nie trzeba czytać całego ciągu znaków, aby dowiedzieć się, gdzie są ucieczki ...
Charles Duffy,