Как я могу записать документ здесь в файл в 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.