연속 문자 다음에 주석이있는 다중 행 명령 bash


29

치다

echo \ # this is a comment
foo

이것은 다음을 제공합니다.

$ sh foo.sh
 # this is a comment
foo.sh: line 2: foo: command not found

웹에서 검색 한 후 자매 사이트 Stack Overflow에서 DigitalRoss솔루션을 찾았습니다 . 그래서 할 수 있습니다

echo `: this is a comment` \
foo

또는 대안 적으로

echo $(: this is a comment) \
foo

그러나 DigitalRoss는 이러한 솔루션이 작동하는 이유를 설명하지 않았습니다. 설명해 주셔서 감사합니다. 그는 주석으로 대답했다.

여기에 goto지정된 레이블로 분기 된 쉘 명령이 :있었습니다. (가) goto사라지고 있지만, 여전히 사용할 수있는 : whatever구문을 ... :지금 구문 분석 주석의 일종이다.

그러나 이식성에 대한 토론을 포함하여 더 자세한 내용과 맥락을 원합니다.

물론 다른 솔루션을 가진 사람이 있다면 그것도 좋습니다.

쉘 스크립트에서 여러 줄 명령을 주석 처리하는 방법 은 이전 질문을 참조하십시오 . .


아래 토론에서 집으로 메시지를 보내십시오. 이 `: this is a comment`명령 대체입니다. 의 출력 : this is a comment은 아무것도 아니며 그 대신에 배치 `: this is a comment`됩니다.

더 나은 선택은 다음과 같습니다.

echo `# this is a comment` \
foo

답변:


25

주석은 연속 줄 을 허용하지 않고 첫 번째 줄 바꿈 ( 쉘 토큰 인식 규칙 10 참조)에서 끝나므로이 코드는 별도의 명령 줄에 있습니다.foo

echo # this is a comment \
foo

첫 번째 제안과 관련하여 백 슬래시 다음에는 줄 바꿈이 없으므로 공간을 인용하면됩니다.

echo ' # this is a comment'
foo

$(: this is a comment)명령의 출력을 대체합니다 : this is a comment. 해당 명령의 출력이 비어 있으면 행 중간에 주석을 삽입하는 것이 매우 혼란스러운 방법입니다.

마술 :은 일어나지 않습니다. 일반적인 명령 인 콜론 유틸리티는 아무 것도하지 않습니다. 콜론 유틸리티는 셸 구문에 명령이 필요하지만 할 일이 없을 때 주로 유용합니다.

# Sample code to compress files that don't look compressed
case "$1" in
  *.gz|*.tgz|*.bz2|*.zip|*.jar|*.od?) :;; # the file is already compressed
  *) bzip2 -9 "$1";;
esac

또 다른 사용 사례는 변수가 설정되어 있지 않은 경우 변수를 설정하는 관용구입니다.

: "${foo:=default value}"

goto에 대한 언급은 역사적인 것입니다. 콜론 유틸리티 날짜도 전에에서 백업 Bourne 쉘 받는 사람, 모든 방법을 톰슨 쉘 했다 고토의 지시를. 콜론은 레이블을 의미했다. 콜론은 goto 레이블에 대해 매우 일반적인 구문입니다 ( sed 에도 여전히 존재합니다 ).


알 겠어. 이 상황에서 알고있는 주석을 삽입하는 더 좋은 방법이 있습니까?
Faheem Mitha

3
@FaheemMitha 언급 한 스레드에서 권장하는대로 : 명령을 관리 가능한 덩어리로 나누고 각 덩어리를 주석 처리하십시오. 명령이 너무 복잡해서 중간에 주석이 필요한 경우 간단하게 할 차례입니다!
질 'SO-정지 존재 악마'

1
문제의 명령에는 많은 논증이 있습니다. 많은 비디오 파일을 하나의 파일로 변환하고 있습니다. 나는 그것을 단순화하는 직접적인 방법을 보지 못했다. 어쩌면 일종의 목록을 만들어 인수로 전달할 수 있습니까? 다른 질문이 될 것 같아요.
Faheem Mitha

@FaheemMitha 예 : make_FIND에 대한 긴 인수 목록을 작성하는 quickie 스크립트입니다 find. 여기서 청크별로 청크를 작성하는 동기는 각 청크가 루프 본문에서 나온다는 것입니다. 그러나 동일한 스타일로 각 청크에 주석을 달 수 있습니다.
Gilles 'SO- 악마 그만'

1
예를 주셔서 감사합니다. 내 예제는 기본적으로 명령에 대한 인수로 제공된 긴 이름 목록입니다. 컨텍스트를 유지하는 가장 쉬운 방법이기 때문에 각 이름에 주석을 첨부하고 싶습니다. 나는 명령을 여러 조각으로 나눌 수있는 확실한 방법을 보지 못했으며, 그렇게하면 명령이 더 길어질 수 있으며 이미 충분히 길었습니다.
Faheem Mitha

6

Bash 배열을 사용하여이를 달성 할 수 있습니다. 예 :

#!/bin/bash
CMD=(
  echo  # this is a comment
  foo
  )

"${CMD[@]}"

배열을 정의한 $CMD다음 확장합니다. 확장되면 결과 라인이 평가되므로이 경우 echo foo에 실행됩니다.

사이의 텍스트 ()배열을 정의하고 라인에있는 모든이 후, 그래서 보통 bash는 구문이 적용됩니다 #무시됩니다.

따옴표로 묶은 공백 유지에 대한 참고 사항

${CMD[@]}공백으로 구분 된 모든 요소를 ​​연결 하는 단일 문자열로 확장됩니다 . 일단 확장되면 Bash는 일반적인 방식으로 문자열을 토큰으로 구문 분석합니다 (cf $ IFS ). 이는 종종 우리가 원하는 것이 아닙니다.

반대로 확장이 큰 따옴표로 묶인 경우 즉 "${CMD[@]}", 배열의 각 요소는 유지됩니다. 의 차이 고려 hello world second item"hello world" "second item".

예시적인 예 :

# LIST=("hello world" "second item")

# for ITEM in ${LIST[@]}; do echo $ITEM; done
hello
world
second
item

# for ITEM in "${LIST[@]}"; do echo $ITEM; done
hello world
second item

@RobM의 답변에 감사드립니다. 따라서 bash 배열 자체의 목록에있는 항목에 대한 의견 / 메타 정보를 포함시키는 것이 좋습니다. 이 질문은 내가 사용하려고했던 명령의 예를 포함 시키면 더 유용 할 것입니다. 왜 내가 몰랐는지 모르겠다.
Faheem Mitha

바, 나는 당신의 질문을주의 깊게 읽지 않았다는 것이 밝혀졌습니다. 당신이 연결 한 질문을하고 있다고 생각했습니다. 죄송합니다. :)
RobM

${CMD[@]}단일 문자열로 확장되지 않습니다 . – 많은 문자열로 확장됩니다. 배열의 각 요소에 대해 분할 될뿐만 아니라 각 요소의 공백에도 적용됩니다. (즉 : 완전히 쓸모가 없음)
Robert Siemer

4

하지 마십시오 $(: comment). 그것은 주석이 아닙니다-그것은 서브 쉘입니다 – 대부분의 쉘을위한 또 하나의 완전히 새로운 쉘 프로세스입니다. 당신의 목표는 입력 이 적고 더 적은 것이 아니라 무의미하더라도 그렇게 할 것입니다.

대신 할 수 있습니다 ...

printf '<%s>\n' some args here ${-##*"${--

                my long comment block

                }"}  and "more ${-##*"${--

                and another one in the
                middle of the quoted string
                there shouldn\'t b\e any special &
                (character) `echo issues here i hope >&2`
                basically anything that isn\'t a close \}
                $(echo the shell is looking for one >&2)
                }$(echo "}'"\" need backslash escaping >&2
                                )${-##*${--

                nesting is cool though

             }}"}here too"

}'" need backslash escaping
<some>
<args>
<here>
<and>
<more here too>

기본적으로 셸이 대체를 수행하고 있습니다. $-매번 특수 쉘 매개 변수의 값을 두 번 대체합니다 . 어쨌든 짧은 문자열이지만 항상 설정되므로 외부에서 제거하는 패턴으로 해석되는 내부 대체 는 확장 양식을 사용할 때 괄호 사이의 내용으로 확장 되지 않습니다- .

이리:

bash -x <<""
printf %s\\n '${-##*"'${-- a set param doesn\'t expand to this optional text }'"}'

+ printf '%s\n' '${-##*"hxB"}'
${-##*"hxB"}

만나다? 따라서 두 번 확장되었습니다. 쉘이 매개 변수를 설정하자마자 선택적인 확장 필드의 모든 것을 버리고 거의 모든 값으로 확장되어 자체에서 제거되어 전혀 아무것도하지 않습니다. 대부분의 셸에서는 따옴표를 이스케이프 할 필요는 없지만 따옴표 bash가 필요합니다.

더 나은 방법은 다음과 같습니다.

COMMENT=
echo      ${COMMENT-"
           this will work the same way
           but the stripping isn\'t
           necessary because, while
           the variable is set, it is also
           empty, and so it will expand to
           its value - which is nothing
           "} this you\'ll see

this you'll see
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.