Как я могу записать документ здесь в файл в Bash script?
Как написать heredoc в файл в Bash script?
Ответ 1
Прочтите расширенный Bash -Scripting Guide Глава 19. Здесь Документы.
Вот пример, который будет записывать содержимое в файл в /tmp/yourfilehere
cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
This line is indented.
EOF
Обратите внимание, что окончательный "EOF" (The LimitString
) не должен иметь пробелов перед словом, потому что это означает, что LimitString
не будет распознан.
В оболочке script вы можете использовать отступы, чтобы сделать код читаемым, однако это может иметь нежелательный эффект отступов текста внутри вашего документа. В этом случае используйте <<-
(за которым следует тире), чтобы отключить основные вкладки (Примечание), чтобы проверить это, вам нужно заменить ведущие пробелы символом табуляции, так как я не могу напечатать фактические символы табов здесь.)
#!/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
Ответ 2
Вместо использования cat
и перенаправления ввода/вывода было бы полезно использовать tee
вместо этого:
tee newfile <<EOF
line 1
line 2
line 3
EOF
Это более краткий, плюс в отличие от оператора перенаправления его можно комбинировать с sudo
, если вам нужно писать в файлы с правами root.
Ответ 3
Замечания:
- следующее конденсируется и организует другие ответы в этой теме, особенно отличную работу Стефана Ласьевского и Сержа Струбандта
- Lasiewski и я рекомендуем Ch 19 (здесь документы) в Расширенном руководстве по созданию скриптов
Вопрос (как написать документ здесь (aka 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
Ответ 4
Чтобы построить на @Livven answer, вот несколько полезных комбинаций.
-
подстановка переменных, ведущая вкладка сохранена, перезаписывает файл, echo to stdout
tee /path/to/file <<EOF ${variable} EOF
-
нет подстановки переменных, ведущая вкладка сохраняется, перезаписывает файл, echo to stdout
tee /path/to/file <<'EOF' ${variable} EOF
-
подстановка переменных, удалена ведущая вкладка, перезаписать файл, echo to stdout
tee /path/to/file <<-EOF ${variable} EOF
-
подстановка переменных, верхняя вкладка сохранена, добавить в файл, echo to 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
Ответ 5
Если требуются права root
Если для файла назначения требуются права root, используйте |sudo tee
вместо >
:
cat << 'EOF' |sudo tee /tmp/yourprotectedfilehere
The variable $FOO will *not* be interpreted.
EOF
Ответ 6
Для будущих людей, которые могут иметь эту проблему, работал следующий формат:
(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
Ответ 7
В качестве примера вы можете использовать его:
Сначала (создание ssh-соединения):
while read pass port user ip files directs; do
sshpass -p$pass scp -o 'StrictHostKeyChecking no' -P $port $files [email protected]$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 [email protected]$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 [email protected]$ip "$Script"
done <<___HERE
PASS PORT USER IP
. . . .
. . . .
. . . .
PASS PORT USER IP
___HERE
Forth (с использованием переменных):
while read pass port user ip fileoutput; do
sshpass -p$pass ssh -o 'StrictHostKeyChecking no' -p $port [email protected]$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
Ответ 8
Мне нравится этот метод для получения четкости, удобочитаемости и представления в отступом:
<<-End_of_file >file
→ foo bar
End_of_file
Где →
- символ tab.