Không thể thụt lề di truyền để khớp với thụt lề của tổ


62

Nếu có "Vấn đề thế giới thứ nhất" cho kịch bản, thì đây sẽ là nó.

Tôi có đoạn mã sau trong tập lệnh tôi đang cập nhật:

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

Kịch bản gửi email mà không có vấn đề, nhưng lệnh mailx được lồng trong một câu lệnh if để tôi dường như bị bỏ lại với hai lựa chọn:

  1. Đặt EOItrên một dòng mới và phá vỡ các mẫu thụt đầu dòng hoặc
  2. Giữ với thụt lề nhưng sử dụng một cái gì đó như một câu lệnh echo để nhận mailx để hút email của tôi.

Tôi mở các lựa chọn thay thế cho heredoc, nhưng nếu có cách nào để khắc phục điều này thì đó là cú pháp ưa thích của tôi.

Câu trả lời:


113

Bạn có thể thay đổi toán tử here-doc thành <<-. Sau đó, bạn có thể thụt lề cả tài liệu ở đây và dấu phân cách bằng các tab:

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

Lưu ý rằng bạn phải sử dụng các tab , không phải khoảng trắng để thụt lề tài liệu ở đây. Điều này có nghĩa là ví dụ trên sẽ không được sao chép (Stack Exchange thay thế các tab bằng dấu cách). Không thể có bất kỳ trích dẫn nào xung quanh EOFdấu phân cách đầu tiên , mở rộng tham số khác, thay thế lệnh và mở rộng số học không có hiệu lực.


Thật tuyệt, nó đã khắc phục vấn đề thụt lề nhưng bây giờ nó không mở rộng biến tôi đang cố gắng đặt vào đó ( $dateLastChanged) nếu tôi thực hiện dấu ngoặc kép + trong ví dụ của bạn, nhưng nếu tôi lấy dấu gạch nối và trích dẫn và đặt EOI lên dòng mới nó bắt đầu mở rộng nó một lần nữa.
Bratchley

1
@JoelDavis: Chỉ cần xóa dấu ngoặc kép, giữ dấu gạch nối.
choroba

5
Bị buộc phải sử dụng các tab là rất khó chịu. Có một cách tốt xung quanh nó?
con-f-use

2
@ con-f-use: Bạn có thể thử một cái gì đó tương tự cat << EOF | sed 's/^ *//'.
choroba

4
Hoặc thậm chí tốt hơn : cat <<- EOF | awk 'NR==1 && match($0, /^ +/){n=RLENGTH} {print substr($0, n+1)}'. Điều này loại bỏ số lượng khoảng trắng trước trong dòng đầu tiên khỏi mỗi dòng trong tài liệu ở đây (nhờ anubhava ).
con-f-use

5

Nếu bạn không cần thay thế lệnh và mở rộng tham số trong tài liệu ở đây, bạn có thể tránh sử dụng các tab bằng cách thêm khoảng trắng hàng đầu vào dấu phân cách:

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

Mặc dù vậy, tôi không thể tìm ra cách sử dụng thủ thuật này và tiếp tục mở rộng tham số.


1
Đối với tôi, đây là câu trả lời duy nhất giải quyết vấn đề thụt lề mà không sử dụng khoảng trắng. shell-checksẽ tìm thấy bất kỳ thay đổi thụt lề nào không khớp với khoảng trắng trong chuỗi được trích dẫn. Sử dụng dấu ngoặc kép để mở rộng tham số?
Tom Hale

4

Thử đi:

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

Bạn không thể có các dòng thụt lề khác nhau trong trường hợp này là trường hợp này. (Điều này quan trọng nếu ví dụ nội dung là tập lệnh.)
ivan_pozdeev

2

Hmm ... Có vẻ như bạn có thể tận dụng tốt hơn --formatđối số ở đây để sử dụng --printfthay vào đó và chỉ cần vượt qua rất nhiều trên một đường ống. Ngoài ra, của bạn if...filà một lệnh ghép - nó có thể chuyển hướng mà tất cả các lệnh có chứa sẽ kế thừa, vì vậy có lẽ bạn không cần phải lồng tổ chức này.

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

Vâng bản sửa đổi trước đây của tôi nói rằng tôi không quan tâm đến sed/ awkphần. Một phần của bản sửa đổi của tôi ngày hôm nay là lấy nó ra vì nó không phải là nguyên nhân của câu hỏi. Dù bằng cách nào, đó là sáu trong số một nửa tá khác.
Bratchley

@Bratchley - chết tiệt. Câu cuối cùng đó sẽ làm tôi mất tập trung trong phần còn lại của ngày.
mikeerv

Ý bạn thế nào
Bratchley

1
@Bratchley - Trông giống như một câu đố.
mikeerv

Hà. Không chắc chắn bạn đến từ quốc gia nào nhưng đó là cụm từ phổ biến ở Hoa Kỳ. Chỉ có nghĩa là "Cách tiếp cận khác nhau cho cùng một kết thúc." Giải pháp của bạn không nhận được xung quanh heredoc mặc dù.
Bratchley

0

Phương pháp khác sẽ là 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"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.