Bash에서 여러 줄 문자열을 출력하는 방법은 무엇입니까?


250

다중 에코 호출을 사용하지 않고 Bash에서 다중 행 문자열을 출력하는 방법은 다음과 같습니다.

echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo 
echo "Report bugs to: "
echo "up home page: "

Bash 내장 만 사용 하여이 작업을 수행 할 수있는 휴대용 방법을 찾고 있습니다.


4
잘못된 호출에 대한 응답으로 사용 메시지를 출력하는 경우 일반적으로 다음 메시지를 사용하여 해당 메시지를 표준 출력 대신 표준 오류로 보냅니다.echo >&2 ...
Mark Reed

2
@MarkReed 사용법 메시지는 다음을 입력하여 출력됩니다 --help(표준 출력으로 이동해야 함).
helpermethod

다른 사람들을 위해, "여기 문서들"에 대한 더 많은 정보가 있습니다 : tldp.org/LDP/abs/html/here-docs.html
Jeffrey Martinez

printfGordon Davidson 의 기반 솔루션을 확인하십시오 . echo또는 cat접근 방식 의 그림자에 있지만 , 그것은 훨씬 덜 혼란스러운 것 같습니다. 분명히 'printf'문법은 약간의 학습 곡선을 나타내지 만 다른 단점 (? 호환성, 성능? ...)을 원합니다.
mjv

답변:


296

여기서는 종종 이러한 목적으로 문서가 사용됩니다.

cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to: 
up home page:
EOF

모든 Bash 버전을 포함하여 모든 Bourne 파생 쉘에서 지원됩니다.


4
응-하지만 cat내장되어 있지 않습니다.
Mark Reed

8
@MarkReed : 사실이지만 항상 사용 가능합니다 (특별한 상황에서는 제외).
추후 공지가있을 때까지 일시 중지되었습니다.

6
+1 Thx. 여러 read -d '' help <<- EOF ...줄 문자열을 변수로 읽은 다음 결과를 에코했습니다.
helpermethod 2016 년

3
HEREDOC을 변수에 저장할 수 있습니까?
chovy

177

또는 당신은 이것을 할 수 있습니다 :

echo "usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to: 
up home page: "

1
@OliverWeiler : Dash 및 Heirloom Bourne Shell 과 같은 Bourne 쉘에서도 작동 합니다.
추후 공지가있을 때까지 일시 중지되었습니다.

6
1) 문자열을 파일 왼쪽 끝까지 들여 쓰기하거나 2) 나머지 코드와 일치하도록 들여 쓰기를 유지해야하지만 함수 로이 기능을 필요로하는 경우 좋지 않습니다. 들여 쓰기
sg

43

이 페이지의 통찰력있는 답변에서 영감을 얻어 가장 단순하고 유연한 방법을 고려한 혼합 접근법을 만들었습니다. 어떻게 생각해?

먼저 변수에 사용법을 정의하여 다른 컨텍스트에서 재사용 할 수 있습니다. 형식은 제어 문자를 추가 할 필요없이 매우 단순하고 거의 WYSIWYG입니다. 이것은 나에게 합리적으로 휴대용 것 같습니다 (MacOS 및 Ubuntu에서 실행했습니다)

__usage="
Usage: $(basename $0) [OPTIONS]

Options:
  -l, --level <n>              Something something something level
  -n, --nnnnn <levels>         Something something something n
  -h, --help                   Something something something help
  -v, --version                Something something something version
"

그런 다음 간단히 사용할 수 있습니다

echo "$__usage"

또는 매개 변수를 구문 분석 할 때 하나의 라이너로 에코 할 수 있습니다.

levelN=${2:?"--level: n is required!""${__usage}"}

4
이것은 위의 대답이 수정되지 않은 스크립트에서 나를 위해 일했습니다.
David Welch

3
이것은 텍스트에서 찾기 어렵고 스크립트에서 문자열과 출력을 크게 다르게 확장하기 어려운 \ t 및 \ n과 같은 많은 문자를 포함하는 것보다 훨씬 더 깨끗합니다.
sg

1
어떤 이유로 그것은 나를 위해 같은 줄에 모든 것을 인쇄합니다 : /
Nicolas de Fontenay

2
@Nicolas : 큰 따옴표를 echo "$__usage"사용해야했습니다. echo $__usage작동하지 않았다.
마리오

24

-e옵션을 사용 \n하면 문자열에서 줄 바꿈 문자를 인쇄 할 수 있습니다 .

샘플 (하지만 좋은지 아닌지 확실하지 않음)

재밌는 점은 -e옵션이 여전히 사용 가능하지만 MacOS 매뉴얼 페이지에 설명되어 있지 않다는 것입니다 . 리눅스 매뉴얼 페이지에 설명되어있다 .


6
해당 매뉴얼 페이지는 시스템 제공 echo명령을 위한 것이며 /bin/echo, Mac OS에서는 -e옵션 이 없습니다 . 해당 시스템에서 bash를 사용하면 내장 echo명령이 대신합니다. /bin/echo whatever동작의 차이점 을 명시 적으로 입력 하고 관찰하면 이를 확인할 수 있습니다 . 내장 문서를 보려면을 입력하십시오 help echo.
Mark Reed

1
/bin/echo종종 OS마다 다르고 Bash의 내장과 다릅니다 echo.
추후 공지가있을 때까지 일시 중지되었습니다.

@MarkReed : 나중에 다시 시도하지만 정보를 주셔서 감사합니다. +1. 나는 많은 좋은 토론이 진행되고 있기 때문에 여기에 대답을 남길 것입니다.
nhahtdh 2016 년

7
echo -e예를 들어, 일부 echo 구현은 "-e"를 출력의 일부로 인쇄합니다. 이식성을 원하면 printf를 대신 사용하십시오. 예를 들어, OS X 10.7.4의 / bin / echo가이를 수행합니다. IIRC bash 내장 에코도 10.5.0에서 이상했지만 더 이상 세부 사항을 기억하지 못합니다.
Gordon Davisson

2
echo -e전에 저를 물었습니다 ... 확실히 printf또는 catheredoc와 함께 사용하십시오 . <<-스크립트의 가독성을 위해 당신이 출력에 들여 쓰기를 선도 제거 할 수 있기 때문에 문서가 특히 좋은 여기에의 변형,하지만 들여 쓰기
zbeekman

22

printf의견에서 권장 했으므로 사용법에 대한 몇 가지 예를 제시해야합니다 (사용 메시지를 인쇄하더라도 Dennis 또는 Chris의 답변을 사용할 가능성이 큽니다). printf보다 사용하기가 조금 더 복잡합니다 echo. 첫 번째 인수는 형식 문자열이며 이스케이프 (예 :) \n항상 해석됩니다. 또한 %추가 인수가 포함되는 위치 및 방법을 제어하는 형식 지시문을 포함 할 수 있습니다 . 사용법 메시지에 사용하는 두 가지 방법이 있습니다.

먼저 전체 메시지를 형식 문자열에 포함시킬 수 있습니다.

printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: \nup home page: \n"

와 달리 echo최종 개행 문자를 명시 적으로 포함해야합니다. 또한 메시지에 %문자 가 포함되어 있으면 로 작성해야 %%합니다. 버그 리포트와 홈페이지 주소를 포함하고 싶을 경우, 자연스럽게 추가 할 수 있습니다.

printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: %s\nup home page: %s\n" "$bugreport" "$homepage"

둘째, 형식 문자열을 사용하여 각 추가 인수를 별도의 줄에 인쇄 할 수 있습니다.

printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: " "up home page: "

이 옵션을 사용하면 버그 리포트 및 홈페이지 주소를 추가하는 것이 매우 분명합니다.

printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: $bugreport" "up home page: $homepage"

9

또한 들여 쓰기 된 소스 코드를 사용하면 <<-(후행 대시와 함께) 선행 탭을 무시할 수 있지만 선행 공백은 무시할 수 있습니다. 예를 들면 다음과 같습니다.

if [ some test ]; then
    cat <<- xx
        line1
        line2
xx
fi

선행 공백없이 들여 쓰기 된 텍스트를 출력합니다.

line1
line2

그것은 나를 위해 작동하지 않았다. 어떤 쉘을 사용하고 있습니까?
four43

우분투의 bash 4.4.19에서는 작동하지 않았습니다.
line1

1
@ four43, 네 말이 맞아 선행 공백을 제거하기 위해 작동하지 않습니다. 그러나 선행 탭을 제거합니다. 그래서 탭과 공백에서 공백이 아닌 탭으로 답을 수정했습니다. 실수해서 죄송합니다. 매뉴얼을 확인했는데 탭이 제거되었다는 것을 분명히 나타냅니다. 관심을 가져 주셔서 감사합니다.
타원형보기

0

@jorge의 솔루션을 사용하고 모든 줄이 같은 줄에 있으면 변수를 따옴표로 묶어야합니다.

echo $__usage

한 줄에 모든 것을 인쇄하지만

echo "$__usage"

줄 바꿈을 유지합니다.


이것은 실제로 나를 위해 일한 솔루션입니다. Printf는 많은 작업을 수행하며 여러 줄 XML을 사용하면 내용을 완전히 엉망으로 만들기 때문에 많은 탈출이 필요합니다. 나는 foo = cat <<EOF .... EOF&& echo "$ foo"를 할당합니다
Jilles van Gurp
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.