내 bash 스크립트에서 매개변수를 구문 분석합니다. 특정 패턴 없이 "path"라는 하나의 매개변수만 허용하려고 합니다. 대소문자에 맞지 않는 다른 매개변수는 스크립트를 종료하게 합니다. 예는 다음과 같습니다.
#!/bin/bash
while [ "$#" -gt 0 ]; do
case "$1" in
-v|--verbose) verbose=1 ;;
-h|--help)
echo "Usage: $(basename "$0") [OPTIONS] [PATH]"
echo "Does something interesting with the given path."
echo ""
echo "OPTIONS"
echo " -v, --verbose Prints verbose information."
echo " -h, --help Prints this help message."
exit 0
;;
*) { test -z $path && path=$1 } || { echo "Invalid command line flag $1" >&2 && exit 1 } ;;
esac
shift
done
그러나 이 줄은 { test -z $path && path=$1 } || { echo "Invalid command line flag $1" >&2 && exit 1 } ;;
다음과 같은 경우 실패합니다.
myscript: line 14 syntax error near unexpected token `;;' myscript: line 14: ` *) { test -z $path && path=$1 } || { echo "Invalid command line flag $1" >&2 && exit 1 } ;;'
간단하게 if-else 문을 작성할 수 있다는 것을 알고 있지만 인라인으로 그룹화할 수 없는 이유가 궁금합니다. 중괄호를 제거하면 exit 1
항상 도달합니다.
답변1
한 줄 명령 그룹 내의 명령 목록은 세미콜론으로 끝나야 합니다. { list; }
그렇지 않으면{ list }
예를 들어,
$ bash -c 'case $1 in *) { echo foo && echo bar } ;; esac' bash baz
bash: -c: line 0: syntax error near unexpected token `;;'
bash: -c: line 0: `case $1 in *) { echo foo && echo bar } ;; esac'
실패하다,
$ bash -c 'case $1 in *) { echo foo && echo bar; } ;; esac' bash baz
foo
bar
효과가 있었습니다.
바라보다명령 목록과 } 사이의 구분 기호그리고 bash 매뉴얼 섹션명령 그룹화.
답변2
이전 답변과 의견은 주요 오류 원인을 다룹니다.
나는 여러 줄 사용 메시지를 스크립트의 다른 부분(예: 서브루틴)으로 이동하고 절에서 -h|-help)
간단히 서브루틴을 호출하도록 제안을 게시했습니다.
USAGE () {
echo "This is the first line of my usage message"
echo "This is another line"
echo "Etc."
}
(farther down the script)
case "$1" in
-v|--verbose) verbose=1 ;;
-h|--help) USAGE ; exit 0 ;;
*) # your code here ;;
esac
또는 여기 문서를 사용하여 여러 줄의 사용법 메시지를 문자열 변수로 조합한 다음 Case 문 절을 사용하여 해당 변수를 표시하고 종료할 수 있습니다.
# fill $USAGE with a here document that isn't indented
USAGE=$(cat - <<EOUSAGE
Usage: $(basename "$0") [OPTIONS] [PATH]
Does something interesting with the given path.
OPTIONS
-v, --verbose Prints verbose information.
-h, --help Prints this help message.
EOUSAGE
) # USAGE=$( ... ) ends here
(farther down the script)
case "$1" in
-v|--verbose) verbose=1 ;;
-h|--help) echo "$USAGE" ; exit 0 ;;
*) # your code here ;;
esac
여러 줄로 된 메시지를 작성하는 것이 여러 개의 echo 명령을 작성하는 것보다 훨씬 덜 혼란스럽고 텍스트의 빈 줄이나 따옴표가 문제가 되지 않기 때문에 여기서는 문서화 방법을 사용하는 것을 선호합니다. 또한 들여쓰기가 되어 있지 않기 때문에 터미널 창에서 각 줄이 얼마나 멀리 확장되는지 확인할 수 있으며 더 긴 줄은 가독성을 높이기 위해 줄 바꿈될 수 있습니다.