Rei*_*ica 1 bash shell switch-statement
我想检测是否传递了无参数或无效参数并打印帮助消息。一个空的参数单独检查是可能的,但不是那么优雅。
我的 bash 脚本如下所示:
COMMAND="$1"
shift
case "$COMMAND" in
loop)
loop_
;;
...
*)
echo $"Usage: $0 {loop|...}"
exit 1
esac
Run Code Online (Sandbox Code Playgroud)
当没有参数传递时,什么都不执行;如果我通过“”,则会触发正确的情况。如果我$1直接使用而不是使用临时变量,那么它会按预期工作。
我什至尝试添加一个特定的案例,"")但无济于事。
您的case语句与 no $1given不匹配的唯一方法是首先没有输入它。
考虑以下:
#!/usr/bin/env bash
set -e
command=$1
shift
case $command in
*) echo "Default case was entered";;
esac
Run Code Online (Sandbox Code Playgroud)
这在$1未设置时不发出任何输出——但不是因为case语句有任何问题。
相反,问题在于当没有可用的内容时shift以非零退出状态退出shift,并且set -e导致整个脚本在该失败时退出。
set -e(或#!/bin/bash -e)请参阅BashFAQ #105进行扩展讨论——或者如果赶时间的话,可以查看其中包含的练习。在不同的“符合 POSIX 标准”的 shell 之间set -e 完全不兼容,因此使得行为难以预测。手动错误处理可能并不有趣,但它更可靠。
这为您提供了一种将使用信息放在一个地方的简洁方法,并在必要时重新使用它(例如,如果您没有$1to shift):
#!/usr/bin/env bash
usage() { echo "Usage: $0 {loop|...}" >&2; exit 1; }
command=$1
shift || usage
case $command in
*) usage ;;
esac
Run Code Online (Sandbox Code Playgroud)
由于中|| usage,退出状态shift被认为是“检查”,所以即使你不使用运行脚本set -e,它将不再构成致命的错误。
shift显式标记为已检查相似地:
shift ||:
Run Code Online (Sandbox Code Playgroud)
... will run shift,但然后回退到 running :( 的同义词true,历史上/传统上暗示占位符使用)应该shift失败,同样阻止set -e触发。
POSIX 指定shell(以及其他标准适用的工具)的行为仅由具有全大写名称的环境变量修改:
POSIX.1-2017 的 Shell 和 Utilities 卷中的实用程序使用的环境变量名称仅由大写字母、数字和可移植字符集中定义的字符中的 ( '_' ) 组成,并且不以数字开头。实现可能允许其他字符;应用程序应容忍此类名称的存在。大写和小写字母应保留其唯一标识,不得折叠在一起。包含小写字母的环境变量名称的命名空间是为应用程序保留的。应用程序可以使用该命名空间中的名称定义任何环境变量,而无需修改标准实用程序的行为。
这甚至适用于常规的、非export编辑的 shell 变量,因为指定一个与环境变量同名的 shell 变量会覆盖后者。
BASH_COMMAND例如,在 bash 中具有独特的含义——因此可以在脚本的前面设置为非空值。COMMAND对于符合 POSIX 的 shell 解释器来说,同样有意义并且已经被它们使用,没有什么可以阻止的。
如果您想避免 shell 使用脚本使用的名称设置内置变量的情况,或者脚本意外覆盖对 shell 有意义的变量的情况下的副作用,请在编写脚本时坚持使用小写或大小写混合的名称用于符合 POSIX 的 shell。