Не можна відступити гередок відповідно до відступу гніздування


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. Будьте з відступом, але використовуйте щось на кшталт ехо-заяви, щоб отримати mailx, щоб висмоктати електронну пошту.

Я відкритий для альтернатив heredoc, але якщо є спосіб обійти це, це мій кращий синтаксис.

Відповіді:


113

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

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

Зауважте, що ви повинні використовувати вкладки , а не пробіли для відступу цього документа. Це означає, що наведений вище приклад не працюватиме скопійованим (Stack Exchange замінює вкладки пробілами). Навколо першого EOFроздільника не може бути жодних лапок , інакше розширення параметрів, підміна команд та арифметичне розширення не діють.


Класно, що виправляє проблему з відступом, але тепер це не розширення змінної, яку я намагаюся помістити туди ( $dateLastChanged), якщо я роблю гіпен + цитати у вашому прикладі, але якщо я беру дефіс і цитати і ставлю EOI на новий рядок, він знову починає розширювати його.
Братчлі

1
@JoelDavis: Просто видаліть цитати, збережіть дефіс.
choroba

5
Змусити використовувати вкладки дуже дратує. Чи є хороший шлях до цього?
con-f-use

2
@ con-f-use: Ви можете спробувати щось подібне cat << EOF | sed 's/^ *//'тощо.
choroba

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

5

Якщо вам не потрібна заміна команд та розширення параметрів всередині вашого тут-документа, ви можете уникнути використання вкладок, додавши провідні пробіли до роздільника:

$     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

Ви не можете мати різно відрізані лінії в гередоку. (Це має значення, якщо, наприклад, вміст є сценарієм.)
ivan_pozdeev

2

Хм ... Здається, ви могли б краще скористатися --formatаргументом тут, щоб використовувати --printfзамість цього і просто передати партію по трубі. Крім того, ваша if...fiє складною командою - вона може приймати переспрямування, яке успадковуватимуть всі команди, тому, можливо, вам взагалі не потрібно вкладати гередок.

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частини. Частина мого перегляду сьогодні полягала в тому, щоб зняти це, оскільки це не було проблемою. Так чи інакше, це шість з півдесятка іншого.
Братчлі

@Bratchley - чорт. Це останнє речення буде мене відволікати на решту дня.
mikeserv

Як ви маєте на увазі?
Братчлі

1
@Bratchley - схоже на загадку.
mikeserv

Ха. Не впевнений, з якої країни ви є, але це загальна фраза в Штатах. Просто означає "Різний підхід до одного і того ж кінця". Твоє рішення все-таки обійде гередок.
Братчлі

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.