코드 블록의 들여쓰기와 일치하도록 heredoc를 들여쓸 수 없습니다.

코드 블록의 들여쓰기와 일치하도록 heredoc를 들여쓸 수 없습니다.

스크립팅에 "제1세계 문제"가 있었다면 바로 이것이었습니다.

업데이트 중인 스크립트에 다음 코드가 있습니다.

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에 대한 대안을 열려 있지만, 이 문제를 해결할 수 있는 방법이 있다면 이것이 내가 선호하는 구문입니다.

답변1

here-doc 연산자를 로 변경할 수 있습니다 <<-. 그런 다음 여기에서 문서를 들여쓰기할 수 있습니다.및 구분 기호탭 포함:

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

알아채다태그를 사용해야 합니다., 공백 대신 문서를 들여쓰고 구분합니다. 이는 위의 예가 재현되지 않음을 의미합니다(Stack Exchange는 탭을 공백으로 대체합니다). 첫 번째 구분 기호 주위에 따옴표를 추가하면 EOF매개변수 확장, 명령 대체 및 산술 확장이 적용되지 않습니다.

답변2

이 문서에서 명령 대체 및 매개변수 확장이 필요하지 않은 경우 구분 기호에 선행 공백을 추가하여 탭 사용을 피할 수 있습니다.

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

그러나 이 트릭을 사용하고 매개변수를 확장된 상태로 유지하는 방법을 찾을 수 없습니다.

답변3

이 시도:

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

답변4

이 답변은 GNU-Bash에만 해당됩니다.

비결은 <<<Bash가 제공하는 단일 단어 here-doc를 사용하여 여러 줄 항목으로 만드는 것입니다.

cat또한 UUoC도 방지합니다. 입력을 다음에 제공하는 프로세스가 필요하지 않습니다 sed.

$ sed '1d;s/^    //' <<<"
    {
       TERM=$TERM
    }
    bye"

출력에는 선행 공백 4개 들여쓰기가 제거되고 $TERM확장된 것으로 표시됩니다.

{
   TERM=xterm-256color
}
bye

1d의 명령은 sed인용된 텍스트가 여는 인용문 다음에 개행 문자로 시작하기 때문에 존재하는 첫 번째 빈 줄을 제거하는 것입니다.

물론 실제 스크립트에서는 다음과 같습니다.찌그러뜨리다에드——용서해주세요.을 돌보다seded - 루프 또는 조건문 내부에 들여쓰기될 명령에 중괄호를 정렬합니다 .

각 데이터 줄을 구분 기호로 시작하면 간단한 sed대체를 통해 가변적인 들여쓰기 양이 제거되어 블록이 들여쓰기 수준 사이에서 자유롭게 이동할 수 있습니다.

while command ; do
    if condition ; then
        variable=$(sed '1d;s/^.*|//' <<<"
                  |{
                  |   TERM=$TERM
                  |}
                  |bye
                  ")
    fi
done

마지막 아이디어 중 하나는 일종의 매크로 역할을 하는 변수에 들여쓰기 마법을 넣는 것입니다.

# put in some common definitions library section
indent='sed 1d;s/^.*|//'

# ...

while command ; do
    if condition ; then
        variable=$($indent <<<"
                  |{
                  |   TERM=$TERM
                  |}
                  |bye
                  ")
    fi
done

우리는 좋은 구식 함수를 작성하여 이를 개선할 수 있습니다:

# put in some common definitions library section
ind()
{
   sed '1d;s/^.*|//' <<<$1
}

# ...

while command ; do
    if condition ; then
        variable=$(ind "
                  |{
                  |   TERM=$TERM
                  |}
                  |bye
                  ")
    fi
done

그런 다음 완전히 추상화합니다 <<<.

관련 정보