고려하다
echo \ # this is a comment
foo
이는 다음을 제공합니다:
$ sh foo.sh
# this is a comment
foo.sh: line 2: foo: command not found
몇번의 온라인 검색 끝에 한 곳을 발견했습니다.디지털로스 솔루션자매 사이트 Stack Overflow에서. 그래서 사람은 할 수 있습니다
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
답변1
주석은 첫 번째 개행 문자로 끝납니다(참조쉘 토큰 인식 규칙 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?)
: # do nothing, the file is already compressed
;;
*)
bzip2 -9 "$1"
;;
esac
또 다른 사용 사례는 변수가 아직 설정되지 않은 경우 변수를 설정하는 관용구입니다.
: "${foo:=default value}"
goto에 대한 의견은 역사적입니다. 콜론 유틸리티는 심지어본 쉘,까지톰슨 쉘, 그것 중 하나가다지침. 콜론은 레이블을 의미합니다. 콜론은 goto 레이블에 대한 매우 일반적인 구문입니다(아직도 존재합니다).sed).
답변2
Bash 배열을 사용하여 이 작업을 수행할 수 있습니다.
#!/bin/bash
CMD=(
echo # this is a comment
foo
)
"${CMD[@]}"
이는 배열을 정의한 $CMD
다음 확장합니다. 확장되면 결과 행이 평가되어 echo foo
이 경우 실행됩니다.
(
와 사이의 텍스트는 )
배열을 정의하고 일반적인 bash 구문을 따르므로 다음 줄의 모든 내용은 #
무시됩니다.
명령 및 매개변수 유지에 대한 참고 사항
${CMD[@]}
공백이나 와일드카드 구두점과 같이 셸에서 해석될 각 요소의 문자를 유지하지 않고 배열 요소를 확장합니다. 확장되면 Bash는 발견된 모든 토큰을 일반적인 방법으로 구문 분석합니다(참조$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
답변3
이렇게 하지 마십시오 $(: 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