我想检测是否没有参数或传递了无效参数,并打印帮助消息。单独检查空参数 * 是可能的,但不是那么优雅。
我的bash脚本看起来像这样:
COMMAND="$1"
shift
case "$COMMAND" in
loop)
loop_
;;
...
*)
echo $"Usage: $0 {loop|...}"
exit 1
esac
当没有参数传递时,什么也不执行;如果我传递“”,则触发适当的case。如果我直接使用$1
而不是使用临时变量,那么它就能按预期工作。
我甚至尝试为"")
添加一个特定的case,但没有用。
5条答案
按热度按时间yks3o0rb1#
hs1ihplo2#
在线:
echo $"Usage: $0 {loop|...}"
第一个$
是什么?如果你不想重复这个消息,只要把它放在一个函数中,然后在case语句之前检查是否有空字符串。
nnvyjq4y3#
case
语句与没有给出的$1
不匹配的唯一原因是它没有首先输入。考虑以下几点:
当
$1
未被设置时,它不会发出输出--但不会,因为case
语句有任何错误。相反,问题是
shift
在没有任何可用的shift* 时以非零的退出状态退出,并且set -e
导致脚本在该失败时整体退出。这个故事的第一个寓意:不要使用
set -e
(或#!/bin/bash -e
)请参阅BashFAQ #105以获得详细讨论--或者如果赶时间的话,请参阅其中包含的练习。
set -e
is wildly incompatible,因此很难预测行为。手动错误处理可能并不有趣,但它可靠得多。秒:考虑使用函数
这为您提供了一种简洁的方式,可以将使用信息放在一个地方,并在必要时重用它(例如,如果您没有
$1
到shift
):由于
|| usage
,shift
的退出状态被认为是“已检查”,因此即使您使用set -e
运行脚本,它也不会再构成致命错误。或者将
shift
显式标记为选中类似地:
...将运行
shift
,但如果shift
失败,则会回退到运行:
(true
的同义词,这在历史上/传统上意味着使用占位符),类似地防止set -e
触发。题外话:自己的变量使用小写名称
POSIX specifies shell(和其他适用标准的工具)的行为仅由具有全大写名称的环境变量修改:
POSIX. 1 -2017的Shell和Utilities卷中的实用程序所使用的环境变量名称仅由大写字母、数字和Portable Character Set中定义的字符中的('_')组成,并且不以数字开始。实现可能允许其他字符;应用程序应容忍此类名称的存在。大写字母和小写字母应保留其唯一标识,不得折叠在一起。环境变量名中包含小写字母的命名空间为应用程序预留。应用程序可以使用此命名空间中的名称定义任何环境变量,而无需修改标准实用程序的行为。
这甚至适用于常规的非
export
艾德shell变量,因为指定与环境变量同名的shell变量会覆盖后者。例如,
BASH_COMMAND
在bash中有不同的含义,因此可以在脚本的前面设置为非空值。没有什么可以阻止COMMAND
对POSIX兼容的shell解释器同样有意义,并且已经被POSIX兼容的shell解释器使用。如果您想避免shell使用脚本使用的名称设置内置变量,或者脚本意外覆盖对shell有意义的变量的情况下的副作用,请在为POSIX兼容的shell编写脚本时坚持使用小写或大小写混合的名称。
balp4ylt4#
在不改变常规模式的情况下解决问题的最简单方法是使用Bourne shell的“高级”参数扩展特性(这不是特定于bash的)。在这种情况下,我们可以使用
:-
修饰符来提供默认值:有关可用的参数扩展修饰符的简短介绍,请参见shell手册页中的“参数扩展”段落。
(Note退出代码64,在某些操作系统上为这种情况保留)。
0s7z1bwu5#
你可以使用
$#
。它表示给定参数的数量: