Не может сделать отступ heredoc, чтобы соответствовать отступу вложенности


62

Если есть «Проблемы Первого Мира» для сценариев, это было бы так.

У меня есть следующий код в скрипте, который я обновляю:

if [ $diffLines -eq 1 ]; then
        dateLastChanged=$(stat --format '%y' /.bbdata | awk '{print $1" "$2}' | sed 's/\.[0-9]*//g')

        mailx -r "Systems and Operations <sysadmin@[redacted].edu>" -s "Warning Stale BB Data" jadavis6@[redacted].edu <<EOI
        Last Change: $dateLastChanged

        This is an automated warning of stale data for the UNC-G Blackboard Snapshot process.
EOI

else
        echo "$diffLines have changed"
fi

Сценарий отправляет электронную почту без проблем, но команда mailx вложена в оператор if, поэтому у меня остается два варианта:

  1. Поставьте EOIновую строку и разбейте шаблоны отступов или
  2. Держите с отступом, но используйте что-то вроде выражения echo, чтобы mailx высосал мою электронную почту.

Я открыт для альтернатив heredoc, но если есть способ обойти это, это мой предпочтительный синтаксис.

Ответы:


113

Вы можете изменить оператор here-doc на <<-. После этого вы можете сделать отступ как для документа here, так и для разделителя :

#! /bin/bash
cat <<-EOF
    indented
    EOF
echo Done

Обратите внимание, что вы должны использовать табуляции , а не пробелы для отступа здесь. Это означает, что приведенный выше пример не будет скопирован (Stack Exchange заменяет вкладки пробелами). Вокруг первого EOFразделителя не должно быть кавычек , иначе расширение параметров, подстановка команд и арифметическое расширение не действуют.


Круто, это решает проблему с отступом, но теперь она не расширяет переменную, которую я пытаюсь вставить туда ( $dateLastChanged), если я сделаю в вашем примере вещь с кавычками +, но если я беру дефис и кавычки и помещаю EOI в Новая линия начинает расширяться снова.
Братчли

1
@JoelDavis: просто удалите кавычки, оставьте дефис.
Чороба

5
Быть вынужденным использовать вкладки очень раздражает. Есть ли хороший способ обойти это?
con-f-use

2
@ con-f-use: вы можете попробовать что-то вроде cat << EOF | sed 's/^ *//'и так далее.
Чороба

4
Или еще лучше cat <<- EOF | awk 'NR==1 && match($0, /^ +/){n=RLENGTH} {print substr($0, n+1)}'. Это удаляет количество предшествующих пробелов в первой строке из каждой строки в документе здесь (благодаря anubhava ).
con-f-use

5

Если вам не требуется подстановка команд и расширение параметров внутри вашего документа here, вы можете избежать использования табуляции, добавив начальные пробелы в разделитель:

$     cat << '    EOF'
>         indented
>     EOF
        indented
$     cat << '    EOF' | sed -r 's/^ {8}//'
>         unindented
>     EOF
unindented

Однако я не мог найти способ использовать этот трюк и сохранить расширение параметров.


1
Для меня это единственный ответ, который решает проблему отступа без использования пробелов. shell-checkнайдет любые отступы, которые не соответствуют пробелам в строке в кавычках. Использовать двойные кавычки для расширения параметров?
Том Хейл,

4

Попробуй это:

sed 's/^ *//' >> ~/Desktop/text.txt << EOF
    Load time-out reached and nothing to resume.
    $(date +%T) - Transmission-daemon exiting.
EOF

В этом случае у вас не может быть строк с разными отступами в heredoc. (Это имеет значение, если, например, содержимое является скриптом.)
ivan_pozdeev

2

Хмм ... Похоже, вы могли бы лучше использовать --formatаргумент здесь, чтобы использовать --printfвместо этого и просто передать партии через канал. Кроме того, ваша if...fiсоставная команда - она ​​может перенаправить все наследуемые команды, поэтому, возможно, вам вообще не понадобится вкладывать heredoc.

if      [ "$diffLines" = 1 ]
then    stat --printf "Last Change: %.19y\n\n$(cat)\n" /.bbdata |
        mailx   -r  "Systems and Operations <sysadmin@[redacted].edu>" \
                -s  "Warning Stale BB Data" 'jadavis6@[redacted].edu'
else    echo    "$diffLines have changed"
fi      <<\STALE
This is an automated warning of stale data for the UNC-G Blackboard Snapshot process.
STALE

Да, моя предыдущая редакция сказала, что я не возражаю против sed/ awkчасти. Часть моего пересмотра сегодня состояла в том, чтобы вынуть это, так как это не было уместно к вопросу В любом случае это шесть из полдюжины других.
Братчли

@ Братчли - блин. Это последнее предложение отвлечет меня до конца дня.
mikeserv

Что ты имеешь в виду?
Братчли

1
@ Братчли - похоже на загадку.
mikeserv

Ха. Не знаю, из какой вы страны, но в Штатах это обычная фраза. Просто означает «Другой подход к одному и тому же концу». Ваше решение все же обходит heredoc.
Братчли

0

Другой метод был бы здесь:

    mail_content="Last Change: $dateLastChanged

    This is an automated warning of stale data for the UNC-G Blackboard Snapshot process."
    mailx -r "Systems and Operations <sysadmin@[redacted].edu>" -s "Warning Stale BB Data" jadavis6@[redacted].edu <<<"$mail_content"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.