터미널에서 이메일을 보내려면 스크립트가 필요합니다. 여기와 다른 온라인 사이트에서 본 내용을 기반으로 다음과 같이 형식을 지정했습니다.
/var/mail -s "$SUBJECT" "$EMAIL" << EOF
Here's a line of my message!
And here's another line!
Last line of the message here!
EOF
그러나 이것을 실행하면 다음 경고가 표시됩니다.
myfile.sh: line x: warning: here-document at line y delimited by end-of-file (wanted 'EOF')
myfile.sh: line x+1: syntax error: unexpected end of file
… 여기서 줄 x는 프로그램에서 마지막으로 작성된 코드 줄이고 줄 y는 그 /var/mail
안에 있는 줄입니다 . 나는 대체 해봤 EOF
다른 것들과 ( ENDOFMESSAGE
, FINISH
, 등)하지만 아무 소용. 내가 온라인에서 찾은 거의 모든 것이 이런 식으로 이루어졌고 나는 bash에서 정말 처음이라서 스스로 알아내는 데 어려움을 겪고 있습니다. 누구든지 도움을 줄 수 있습니까?
답변
EOF
토큰은 행의 시작 부분에 있어야합니다, 당신은 함께가는 코드 블록과 함께 그것을 들여 수 없습니다.
쓰면 <<-EOF
들여 쓰기를 할 수 있지만 Tab공백이 아닌 문자 로 들여 쓰기를해야 합니다. 따라서 코드 블록으로도 끝나지 않을 수도 있습니다.
또한 라인 의 토큰 뒤에 공백이 없는지 확인하십시오 EOF
.
답변
here-doc를 시작하거나 끝나는 줄에는 인쇄 할 수 없거나 공백 문자 (예 : 캐리지 리턴)가있을 수 있습니다. 이는 두 번째 “EOF”가 첫 번째 “EOF”와 일치하지 않고 here-doc를 끝내지 않음을 의미합니다. 그래야합니다. 이것은 매우 일반적인 오류이며 텍스트 편집기만으로는 감지하기 어렵습니다. 예를 들어 다음과 cat
같이 인쇄 할 수없는 문자를 표시 할 수 있습니다 .
cat -A myfile.sh
cat -A
솔루션 의 출력을 확인 하면 문제가되는 문자를 제거하십시오.
답변
다음 전에 선행 공백을 제거하십시오 EOF
.
/var/mail -s "$SUBJECT" "$EMAIL" <<-EOF
ident <tab>
대신 <spaces>
사용하고 <<-EOF를 사용하면 잘 작동합니다.
는 "-"
제거 <tabs>
하지 <spaces>
만, 적어도이 작품을.
답변
이렇게하면이 오류가 발생할 수도 있습니다.
while read line; do
echo $line
done << somefile
이 경우 << somefile
읽어야 하기 때문 < somefile
입니다.
답변
heredoc 을 사용 하지 않고 들여 쓰기 된 여러 줄 을 처리 할 수있는 유연한 방법이 있습니다.
echo 'Hello!'
sed -e 's:^\s*::' < <(echo '
Some indented text here.
Some indented text here.
')
if [[ true ]]; then
sed -e 's:^\s\{4,4\}::' < <(echo '
Some indented text here.
Some extra indented text here.
Some indented text here.
')
fi
이 솔루션에 대한 몇 가지 참고 사항 :
- 내용에 간단한 따옴표가있을 것으로 예상되는 경우에는이를 사용하여 이스케이프
\
하거나 문자열 구분 기호를 큰 따옴표로 바꾸십시오. 후자의 경우 유사한 구성$(command)
이 해석 될 수 있도록주의하십시오 . 문자열에 간단한 따옴표와 큰 따옴표가 모두 포함되어 있으면 적어도 종류를 이스케이프해야합니다. - 주어진 예는 후행 빈 줄을 인쇄합니다.이 줄을 제거하는 방법은 여러 가지가 있습니다. 여기에는 제안을 깔끔하게 유지하기 위해 포함되지 않았습니다.
- 유연성은 물론 몇 가지 sed REGEXP를 알고있는 경우 선행 공간이 유지되거나 이동하는 정도를 제어 할 수있는 용이성에서 비롯됩니다.
답변
내가 가지고 싶을 때 문서화 문자열을 내 bash는 기능, 나는의 제안과 유사한 솔루션을 사용 user12205 A의 중복 이 질문을.
다음과 같은 솔루션에 대해 USAGE를 정의하는 방법을 참조하십시오.
- 선택한 IDE에서 나를 위해 자동 포맷 (숭고함)
- 여러 줄
- 들여 쓰기로 공백이나 탭을 사용할 수 있습니다.
- 주석 내의 들여 쓰기를 유지합니다.
function foo {
# Docstring
read -r -d '' USAGE <<' END'
# This method prints foo to the terminal.
#
# Enter `foo -h` to see the docstring.
# It has indentations and multiple lines.
#
# Change the delimiter if you need hashtag for some reason.
# This can include $$ and = and eval, but won't be evaluated
END
if [ "$1" = "-h" ]
then
echo "$USAGE" | cut -d "#" -f 2 | cut -c 2-
return
fi
echo "foo"
}
따라서 결과 foo -h
:
This method prints foo to the terminal.
Enter `foo -h` to see the docstring.
It has indentations and multiple lines.
Change the delimiter if you need hashtag for some reason.
This can include $$ and = and eval, but won't be evaluated
설명
cut -d "#" -f 2
: #
구분 된 줄 의 두 번째 부분을 검색합니다 . (구분 기호로 “#”을 사용하고 첫 번째 열이 비어있는 csv를 생각해보십시오.)
cut -c 2-
: 결과 문자열의 두 번째에서 끝 문자 검색
또한 빈 문자열이되기 때문에 오류없이 첫 번째 인수가없는 if [ "$1" = "-h" ]
것처럼 평가됩니다 False
.
답변
Barmar와 Joni가 언급 한 다른 답변과 함께 <<-EOF
.