Jak mogę napisać tutaj dokument do pliku w skrypcie Bash?
Jak mogę napisać tutaj dokument do pliku w skrypcie Bash?
Odpowiedzi:
Przeczytaj Advanced Guide Bash-Scripting Guide Rozdział 19. Tutaj Dokumenty .
Oto przykład, który zapisze zawartość do pliku w /tmp/yourfilehere
cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
This line is indented.
EOF
Zauważ, że końcowe „EOF” (The LimitString
) nie powinno zawierać żadnych białych znaków przed słowem, ponieważ oznacza to, że LimitString
nie zostaną one rozpoznane.
W skrypcie powłoki możesz użyć wcięcia, aby kod był czytelny, jednak może to mieć niepożądany efekt wcięcia tekstu w dokumencie tutaj. W takim przypadku użyj <<-
(po którym następuje myślnik), aby wyłączyć wiodące tabulatory ( zwróć uwagę, że aby to przetestować, musisz zastąpić wiodące białe znaki tabulatorem , ponieważ nie mogę tutaj wydrukować rzeczywistych znaków tabulatora).
#!/usr/bin/env bash
if true ; then
cat <<- EOF > /tmp/yourfilehere
The leading tab is ignored.
EOF
fi
Jeśli nie chcesz interpretować zmiennych w tekście, użyj pojedynczych cudzysłowów:
cat << 'EOF' > /tmp/yourfilehere
The variable $FOO will not be interpreted.
EOF
Aby potokować heredoc przez potok poleceń:
cat <<'EOF' | sed 's/a/b/'
foo
bar
baz
EOF
Wynik:
foo
bbr
bbz
... lub zapisać heredoc do pliku za pomocą sudo
:
cat <<'EOF' | sed 's/a/b/' | sudo tee /etc/config_file.conf
foo
bar
baz
EOF
<<<
oni się nazywają?
<<<
nazywają się „Here Strings”. Kod podobny tr a-z A-Z <<< 'one two three'
spowoduje łańcuch ONE TWO THREE
. Więcej informacji na en.wikipedia.org/wiki/Here_document#Here_strings
<<'EOF'
raczej <<EOF
.
Zamiast używania cat
przekierowania I / O przydatne może być użycie tee
:
tee newfile <<EOF
line 1
line 2
line 3
EOF
Jest bardziej zwięzły, a w przeciwieństwie do operatora przekierowania można go łączyć, sudo
jeśli chcesz pisać do plików z uprawnieniami administratora.
> /dev/null
na końcu pierwszego wiersza, aby zapobiec wyświetlaniu zawartości pliku tutaj na standardowe wyjście podczas jego tworzenia.
sudo
raczej ze względu na jego kompatybilność niż z powodu zwięzłości :-)
man tee
. Użyj -a
flagi, aby dołączyć zamiast zastąpić.
Uwaga:
Pytanie (jak napisać tutaj dokument (aka heredoc ) do pliku w skrypcie bash?) Ma (przynajmniej) 3 główne niezależne wymiary lub pytania:
root
) Jest właścicielem pliku?(Istnieją inne wymiary / podzapytania, które nie uważam za ważne. Rozważ edycję tej odpowiedzi, aby je dodać!) Oto niektóre z ważniejszych kombinacji wymiarów pytania wymienionych powyżej, z różnymi różnymi ograniczającymi identyfikatorami - nie ma nic Najświętsze EOF
, po prostu upewnij się, że ciąg, którego używasz jako identyfikatora, nie występuje w twoim heredoc:
Aby zastąpić istniejący plik (lub napisać do nowego pliku), który posiadasz, zastępując odwołania do zmiennych wewnątrz 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
Aby dodać istniejący plik (lub zapisać do nowego pliku), który posiadasz, zastępując odniesienia do zmiennych wewnątrz 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
Aby zastąpić istniejący plik (lub zapisać nowy plik), którego jesteś właścicielem, dosłowną zawartością 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
Aby dołączyć istniejący plik (lub zapisać do nowego pliku), który posiadasz, z dosłowną zawartością 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
Aby zastąpić istniejący plik (lub zapisać do nowego pliku) będącego własnością root, zastępując odniesienia do zmiennych wewnątrz 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
Aby dołączyć istniejący plik (lub zapisać do nowego pliku) będącego własnością user = foo, z dosłowną zawartością 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
-a
== --append
; tj. tee -a
-> tee
. Zobacz info tee
(zacytuję to tutaj, ale znaczniki komentarzy są zbyt ograniczone
sudo tee /path/to/your/file << 'Screw_you_Foo'
?
FOE
zamiast EOF
w dołączonym przykładzie?
Aby skorzystać z odpowiedzi @ Livven , oto kilka przydatnych kombinacji.
podstawianie zmiennych, zachowywanie wiodącej tabulacji, nadpisywanie pliku, echo na standardowe wyjście
tee /path/to/file <<EOF
${variable}
EOF
brak podstawiania zmiennych , zachowywanie wiodącej tabulacji, nadpisywanie pliku, echo na standardowe wyjście
tee /path/to/file <<'EOF'
${variable}
EOF
podstawianie zmiennych, usuwanie tabulacji wiodącej , nadpisywanie pliku, echo na standardowe wyjście
tee /path/to/file <<-EOF
${variable}
EOF
podstawianie zmiennych, zachowane tabulacje wiodące, dołączanie do pliku , echo na standardowe wyjście
tee -a /path/to/file <<EOF
${variable}
EOF
podstawianie zmiennych, zachowywanie wiodącej tabulacji, nadpisywanie pliku, brak echa na standardowe wyjście
tee /path/to/file <<EOF >/dev/null
${variable}
EOF
powyżej może być połączony z sudo
oraz
sudo -u USER tee /path/to/file <<EOF
${variable}
EOF
Jeśli do pliku docelowego wymagane są uprawnienia roota, użyj |sudo tee
zamiast >
:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF
Dla przyszłych osób, które mogą mieć ten problem, działał następujący format:
(cat <<- _EOF_
LogFile /var/log/clamd.log
LogTime yes
DatabaseDirectory /var/lib/clamav
LocalSocket /tmp/clamd.socket
TCPAddr 127.0.0.1
SelfCheck 1020
ScanPDF yes
_EOF_
) > /etc/clamd.conf
cat << END > afile
następnie heredoc działa doskonale.
cat
jak pokazano w zaakceptowanej odpowiedzi.
cat
działa w podpowłoce, a wszystkie dane wyjściowe podpowłoki są przekierowywane do pliku
Jako przykład możesz go użyć:
Po pierwsze (nawiązanie połączenia ssh):
while read pass port user ip files directs; do
sshpass -p$pass scp -o 'StrictHostKeyChecking no' -P $port $files $user@$ip:$directs
done <<____HERE
PASS PORT USER IP FILES DIRECTS
. . . . . .
. . . . . .
. . . . . .
PASS PORT USER IP FILES DIRECTS
____HERE
Po drugie (wykonywanie poleceń):
while read pass port user ip; do
sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1
COMMAND 1
.
.
.
COMMAND n
ENDSSH1
done <<____HERE
PASS PORT USER IP
. . . .
. . . .
. . . .
PASS PORT USER IP
____HERE
Po trzecie (wykonywanie poleceń):
Script=$'
#Your commands
'
while read pass port user ip; do
sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port $user@$ip "$Script"
done <<___HERE
PASS PORT USER IP
. . . .
. . . .
. . . .
PASS PORT USER IP
___HERE
Dalej (przy użyciu zmiennych):
while read pass port user ip fileoutput; do
sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port $user@$ip fileinput=$fileinput 'bash -s'<<ENDSSH1
#Your command > $fileinput
#Your command > $fileinput
ENDSSH1
done <<____HERE
PASS PORT USER IP FILE-OUTPUT
. . . . .
. . . . .
. . . . .
PASS PORT USER IP FILE-OUTPUT
____HERE