Как я могу написать heredoc в файл в скрипте Bash?



Как я могу написать здесь документ в файл в скрипте Bash?

657   7  

7 ответов:

прочитайте руководство Advanced Bash-ScriptingГлава 19. Вот Документы.

вот пример, который будет записывать содержимое в файл по адресу /tmp/yourfilehere

cat << 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.

Примечание:

вопрос (Как написать здесь документ (он же heredoc) к файлу в скрипте bash?) (по минимум) 3 основных независимых измерения или подзапроса:

  1. вы хотите перезаписать существующий файл, добавить к существующему файлу или записать в новый файл?
  2. делает ли ваш пользователь или другой пользователь (например,root) собственного файла?
  3. вы хотите написать содержимое вашего heredoc буквально, или чтобы bash интерпретировал ссылки на переменные внутри вашего heredoc?

(есть и другие измерения / подзапросы, которые я не рассматриваю важный. Рассмотрите возможность редактирования этого ответа, чтобы добавить их!) Вот некоторые из наиболее важных комбинаций измерений вопроса, перечисленных выше, с различными различными идентификаторами разграничения-нет ничего святого в EOF, просто убедитесь, что строка, которую вы используете в качестве идентификатора-разделителя, делает не происходят внутри вашего heredoc:

  1. для перезаписи существующего файла (или записи в новый файл), которым вы владеете, подставляя ссылки на переменные внутри 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
    
  2. чтобы добавить существующий файл (или записать в новый файл), который у вас есть, подставляя ссылки на переменные внутри 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
    
  3. чтобы перезаписать существующий файл (или записать в новый файл), который у вас есть, с литеральным содержимым 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
    
  4. чтобы добавить существующий файл (или записать в новый файл), который у вас есть, с литеральным содержимым 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
    
  5. чтобы перезаписать существующий файл (или записать в новый файл), принадлежащий 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
    
  6. чтобы добавить существующий файл (или записать в новый файл), принадлежащий пользователю=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 это ответ, вот некоторые полезные комбинации.

  1. переменная подстановка, ведущая вкладка сохраняется, перезаписать файл, эхо в stdout

    tee /path/to/file <<EOF
    ${variable}
    EOF
    
  2. нет замены переменной, ведущая вкладка сохраняется, перезаписать файл, эхо в stdout

    tee /path/to/file <<'EOF'
    ${variable}
    EOF
    
  3. переменной подстановки, вкладка ведущих удалены перезаписать файл, Эхо стандартный вывод

    tee /path/to/file <<-EOF
        ${variable}
    EOF
    
  4. переменная подстановка, ведущая вкладка сохраняется,добавить файл, эхо в stdout

    tee -a /path/to/file <<EOF
    ${variable}
    EOF
    
  5. переменная подстановка, ведущая вкладка сохраняется, перезаписать файл,нет эхо в stdout

    tee /path/to/file <<EOF >/dev/null
    ${variable}
    EOF
    
  6. вышеуказанное можно совместить с 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

    Ничего не найдено.