7 ответов:
прочитайте руководство Advanced Bash-ScriptingГлава 19. Вот Документы.
вот пример, который будет записывать содержимое в файл по адресу
/tmp/yourfileherecat << EOF > /tmp/yourfilehere These contents will be written to the file. This line is indented. EOFобратите внимание, что окончательный 'EOF' (
LimitString) не должно быть никаких пробелов перед словом, потому что это означает, чтоLimitStringне будет распознан.в сценарии оболочки вы можете использовать отступ, чтобы сделать код читаемым, однако это может иметь нежелательный эффект отступа текста в вашем документе здесь. В этом случае используйте
<<-(затем тире), чтобы отключить ведущие вкладки (Примечание что для проверки этого вам нужно будет замените начальный пробел символом табуляции, так как я не могу печатать фактические символы табуляции здесь.)#!/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.
Примечание:
- следующее конденсирует и организует другие ответы в этой теме, особенно отличную работу Стефан Ласевский и Serge Stroobandt
- Lasiewski и я рекомендую Ch 19 (Здесь документы) в Advanced Bash-Scripting Guide
вопрос (Как написать здесь документ (он же 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чтобы добавить существующий файл (или записать в новый файл), принадлежащий пользователю=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
когда требуются права суперпользователя
если для конечного файла требуются права суперпользователя, используйте
|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
Comments