Как я могу написать heredoc в файл в скрипте Bash?
Как я могу написать здесь документ в файл в сценарии Bash?
7 ответов
прочитайте руководство Advanced Bash-ScriptingГлава 19. Вот Документы.
вот пример, который будет записывать содержимое в файл по адресу /tmp/yourfilehere
cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
This line is indented.
EOF
обратите внимание, что окончательный 'EOF' (LimitString
) не должно иметь пробелов перед словом, потому что это означает, что LimitString
не будет распознан.
в сценарии оболочки вы можете использовать отступ, чтобы сделать код читаемым, однако это может иметь нежелательный эффект отступа текста в вашем документе here. В этом случае используйте <<-
(затем тире), чтобы отключить ведущие вкладки (Примечание что для проверки этого вам нужно будет замените начальные пробелы символом табуляции, так как я не могу печатать фактические символы табуляции здесь.)
#!/usr/bin/env bash
if true ; then
cat <<- EOF > /tmp/yourfilehere
The leading tab is ignored.
EOF
fi
если вы не хотите интерпретировать переменные в тексте, используйте одинарные кавычки:
cat << 'EOF' > /tmp/yourfilehere
The variable $FOO will not be interpreted.
EOF
передать heredoc через команду трубопровод:
cat <<'EOF' | sed 's/a/b/'
foo
bar
baz
EOF
выход:
foo
bbr
bbz
... или записать heredoc в файл с помощью sudo
:
cat <<'EOF' | sed 's/a/b/' | sudo tee /etc/config_file.conf
foo
bar
baz
EOF
вместо cat
и перенаправление ввода / вывода может быть полезно использовать tee
вместо:
tee newfile <<EOF
line 1
line 2
line 3
EOF
это более лаконично, плюс в отличие от оператора перенаправления он может быть объединен с sudo
Если вам нужно записать файлы с правами root.
Примечание:
- следующие конденсирует и организует другие ответы в этой теме, esp отличную работу Стефан Lasiewski и Серега Stroobandt
- Lasiewski и я рекомендую Ch 19 (Здесь документы) в руководстве Advanced Bash-Scripting
вопрос (Как написать здесь документ (он же помощи heredoc) к файлу в скрипте bash?) (по минимум) 3 основных независимых измерения или подзапросы:
- вы хотите перезаписать существующий файл, добавить к существующему файлу или записать в новый файл?
- делает ваш пользователь или другой пользователь (например,
root
) собственного файла? - вы хотите написать содержание вашего heredoc буквально, или иметь bash интерпретировать ссылки на переменные внутри вашего heredoc?
(есть другие измерения / подзапросы, которые я не считаю важный. Подумайте о редактировании этого ответа, чтобы добавить их!) Вот некоторые из наиболее важных комбинаций измерений вопроса, перечисленных выше, с различными различными идентификаторами разграничения-нет ничего святого о EOF
, просто убедитесь, что строка, которую вы используете в качестве идентификатора разделителя, делает не происходят внутри вашей heredoc:
-
для перезаписи существующего файла (или записи в новый файл), которым вы владеете, подставляя ссылки на переменные внутри помощи 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
-
чтобы добавить существующий файл( или записать в новый файл), которым вы владеете, подставляя ссылки на переменные внутри 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
-
чтобы перезаписать существующий файл (или записать в новый файл), который у вас есть, с буквальным содержимым 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
-
чтобы добавить существующий файл (или записать в новый файл), который у вас есть, с буквальным содержимым помощи 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
-
чтобы перезаписать существующий файл (или записать в новый файл), принадлежащий root, подставляя ссылки на переменные внутри 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
-
чтобы добавить существующий файл (или записать в новый файл), принадлежащий user=foo, с буквальным содержимым 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
построить на @Livven это ответ, вот некоторые полезные комбинации.
-
переменная подстановка, ведущая вкладка сохранена, перезаписать файл, эхо в stdout
tee /path/to/file <<EOF ${variable} EOF
-
нет замены переменной, ведущая вкладка сохранена, перезаписать файл, эхо в stdout
tee /path/to/file <<'EOF' ${variable} EOF
-
переменной подстановки, вкладка ведущих удалены перезаписать файл, Эхо стандартный вывод
tee /path/to/file <<-EOF ${variable} EOF
-
переменная подстановка, ведущая вкладка сохранена,добавить файл, эхо в stdout
tee -a /path/to/file <<EOF ${variable} EOF
-
подстановка переменных, ведущая вкладка сохранена, перезаписать файл,нет эхо в stdout
tee /path/to/file <<EOF >/dev/null ${variable} EOF
-
вышеуказанное можно совместить с
sudo
а такжеsudo -u USER tee /path/to/file <<EOF ${variable} EOF
когда требуются права root
если для файла назначения требуются права root, используйте |sudo tee
вместо >
:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF
для будущих людей, у которых может быть эта проблема, работал следующий формат:
(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
в качестве экземпляра можно использовать:
первый (подключение 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
второй(выполнение команд):
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
третий(выполнение команд):
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
вперед (используя переменные):
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