Как я могу записать документ здесь в файл в Bash script?
Прочтите расширенный 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
<<<
, как они называются?
Вместо использования cat
и перенаправления ввода/вывода было бы полезно использовать tee
вместо этого:
tee newfile <<EOF
line 1
line 2
line 3
EOF
Это более краткий, плюс в отличие от оператора перенаправления его можно комбинировать с sudo
, если вам нужно писать в файлы с правами root.
> /dev/null
в конце первой строки, чтобы содержимое этого файла не отображалось на stdout при его создании.
tee
в первую очередь, я думаю.
Замечания:
Вопрос (как написать документ здесь (aka heredoc) в файл в сценарии bash?) Имеет (по крайней мере) 3 основных независимых измерения или подзапросы:
root
) есть файл? (Существуют другие измерения/подзапросы, которые я не считаю важными. Рассмотрите возможность редактирования этого ответа, чтобы добавить их!) Вот некоторые из наиболее важных комбинаций измерений перечисленного выше вопроса с различными разграничивающими идентификаторами - нет ничего священный об 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
--append
-a
== --append
; т.е. tee -a
-> tee
. Смотрите info tee
(я бы процитировал это здесь, но разметка комментариев слишком ограничена.
Чтобы построить на @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
Если для файла назначения требуются права 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
cat << END > afile
за которым следует heredoc, работает отлично.
В качестве примера вы можете использовать его:
Сначала (создание 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
Forth (с использованием переменных):
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
Мне нравится этот метод для получения четкости, удобочитаемости и представления в отступом:
<<-End_of_file >file
→ foo bar
End_of_file
Где →
- символ tab.