在我的 bash 脚本中,我解析参数。我想尝试只允许一个参数没有特定的模式,即“路径”。任何其他不符合情况的参数都应该导致脚本退出。这是一个例子:
#!/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
或者您可以使用here文档将多行使用消息组装成字符串变量,然后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 命令那么混乱,而且文本中的空行或引号也不会有问题。此外,由于它没有缩进,您可以看到每行在终端窗口中延伸了多远,并且可以将较长的行换行以获得更好的易读性。