ไม่สามารถเยื้อง 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

คุณสามารถเปลี่ยนผู้ประกอบการที่นี่ doc <<-ให้ จากนั้นคุณสามารถเยื้องทั้ง here-doc และ delimiterด้วยแท็บ:

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

โปรดทราบว่าคุณต้องใช้แท็บไม่ใช่ที่ว่างเพื่อเยื้อง here-doc ซึ่งหมายความว่าตัวอย่างข้างต้นจะไม่ทำงาน (คัดลอก Exchange แทนที่แท็บที่มีช่องว่าง) ไม่สามารถมีเครื่องหมายคำพูดใด ๆ รอบEOFตัวคั่นแรกการขยายพารามิเตอร์อื่นการทดแทนคำสั่งและการขยายเลขคณิตจะไม่มีผล


เจ๋ง, นั่นแก้ปัญหาการเยื้อง แต่ตอนนี้มันไม่ได้ขยายตัวแปรที่ฉันพยายามใส่ ( $dateLastChanged) ถ้าฉันทำไฮเปอร์ + เครื่องหมายคำพูดในตัวอย่างของคุณ, แต่ถ้าฉันใส่เครื่องหมายยัติภังค์และอัญประกาศแล้วใส่ EOI บรรทัดใหม่มันเริ่มขยายอีกครั้ง
Bratchley

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จะพบการเปลี่ยนแปลงเยื้องใด ๆ ที่ไม่ตรงกับช่องว่างในสตริงที่ยกมา ใช้เครื่องหมายคำพูดคู่สำหรับการขยายพารามิเตอร์หรือไม่
Tom Hale

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ส่วน ส่วนหนึ่งของการแก้ไขของฉันในวันนี้คือเอามันออกไปเพราะมันไม่ได้ทำให้คำถาม ไม่ว่าจะเป็นหกครึ่งครึ่งจากอีกครึ่งหนึ่ง
Bratchley

@Bratchley - เหี้ย ประโยคสุดท้ายนั้นจะกวนใจฉันไปตลอดทั้งวัน
mikeserv

คุณหมายความว่าอย่างไร?
Bratchley

1
@ Bratchley - ดูเหมือนว่าเป็นปริศนา
mikeserv

ฮ้า ไม่แน่ใจว่าคุณมาจากประเทศไหน แต่เป็นวลีทั่วไปในสหรัฐอเมริกา หมายถึง "วิธีการที่แตกต่างไปในตอนท้ายเดียวกัน" วิธีการแก้ปัญหาของคุณจะได้รับรอบ heredoc ว่า
Bratchley

0

วิธีการอื่นจะเป็น herestrings:

    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"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.