Как я могу написать здесь документ в файл в сценарии Bash?
Как я могу написать здесь документ в файл в сценарии Bash?
Ответы:
Прочитайте Руководство по расширенному написанию сценариев Bash. Глава 19. Здесь документы .
Вот пример, который запишет содержимое в файл в /tmp/yourfilehere
cat << EOF > /tmp/yourfilehere
These contents will be written to the file.
This line is indented.
EOF
Обратите внимание, что в конечном EOF (The 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
<<<
, как они называются?
<<<
называются «Здесь строки». Код как tr a-z A-Z <<< 'one two three'
приведет к строке ONE TWO THREE
. Дополнительная информация на en.wikipedia.org/wiki/Here_document#Here_strings
<<'EOF'
а не <<EOF
.
Вместо использования cat
перенаправления ввода / вывода может быть полезно использовать tee
вместо этого:
tee newfile <<EOF
line 1
line 2
line 3
EOF
Это более кратко, плюс в отличие от оператора перенаправления его можно комбинировать, sudo
если вам нужно записывать в файлы с правами root.
> /dev/null
в конце первой строки, чтобы содержимое этого файла не отображалось на stdout при его создании.
sudo
, а не из-за его краткости :-)
man tee
. Используйте -a
флаг, чтобы добавить вместо перезаписи.
Замечания:
Вопрос (как написать здесь документ (он же 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
Чтобы добавить существующий файл (или записать в новый файл), принадлежащий 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
-a
== --append
; т.е. tee -a
-> tee
. Смотрите info tee
(я бы процитировал это здесь, но разметка комментариев слишком ограничена.
sudo tee /path/to/your/file << 'Screw_you_Foo'
?
FOE
вместо EOF
примера в приложении?
Чтобы построить ответ @ Livven , вот несколько полезных комбинаций.
подстановка переменных, ведущая вкладка сохранена, файл перезаписи, эхо в стандартный вывод
tee /path/to/file <<EOF
${variable}
EOF
без подстановки переменных , ведущие вкладки сохраняются, файл перезаписи, эхо в стандартный вывод
tee /path/to/file <<'EOF'
${variable}
EOF
подстановка переменных, удаление первой вкладки , перезапись файла, вывод на стандартный вывод
tee /path/to/file <<-EOF
${variable}
EOF
подстановка переменных, ведущая вкладка сохранена, добавление в файл , вывод на stdout
tee -a /path/to/file <<EOF
${variable}
EOF
подстановка переменных, ведущая вкладка сохранена, файл перезаписи, нет эха на стандартный вывод
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 отлично работает.
cat
как показано в принятом ответе.
cat
работает внутри подоболочки, и весь вывод подоболочки перенаправляется в файл
Как пример, вы можете использовать его:
Первый (создание 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