我想检测是否传递了任何参数或无效的参数,并输出帮助消息。可以单独检查空参数 ,但不太好。
我的bash脚本如下:
realloc
不传递任何参数时,将不执行任何操作;如果我通过“”,则将触发适当的情况。如果我直接使用COMMAND="$1"
shift
case "$COMMAND" in
loop)
loop_
;;
...
*)
echo $"Usage: $0 {loop|...}"
exit 1
esac
而不是使用临时变量,那么它将按预期工作。
我什至尝试为$1
添加一个特定的案例,但无济于事。
答案 0 :(得分:4)
您的case
语句与没有给出的$1
不匹配的唯一方法是,如果不是首先输入它的话。
请考虑以下内容:
#!/usr/bin/env bash
set -e
command=$1
shift
case $command in
*) echo "Default case was entered";;
esac
在未设置$1
时,此命令不会输出-但不会,因为case
语句有任何问题。
相反,问题在于shift
退出时的退出状态为非零值,当没有可用的移位键时,,并且set -e
导致脚本整体退出那失败。
set -e
(或#!/bin/bash -e
)请参阅BashFAQ #105进行更详细的讨论-或急着使用exercises included therein。 set -e
is wildly incompatible在不同的“符合POSIX的”外壳之间,因此行为难以预测。手动错误处理可能不会很有趣,但是更加可靠。
这为您提供了一种简洁的方法,可将您的使用情况信息放在一个地方,并在必要时重复使用(例如,如果您没有$1
至shift
):< / p>
#!/usr/bin/env bash
usage() { echo "Usage: $0 {loop|...}" >&2; exit 1; }
command=$1
shift || usage
case $command in
*) usage ;;
esac
由于|| usage
,shift
的退出状态被视为“选中”,因此即使您使用set -e
运行脚本,它也会将不再构成致命错误。
shift
标记为明确选中类似地:
shift ||:
...将运行shift
,但是如果:
失败,则会退回到运行true
(shift
的同义词,在历史上/传统上,这意味着使用占位符) ,同样可以阻止set -e
触发。
POSIX specifies,仅通过具有全大写名称的环境变量来修改外壳(以及标准所适用的其他工具)的行为:
POSIX.1-2017的Shell and Utilities卷中的实用程序使用的环境变量名称仅由大写字母,数字和可移植字符集中定义的字符中的('_')组成,并且不以一个数字。实现可能允许使用其他字符;申请应容忍此类名称的存在。大写字母和小写字母应保留其唯一标识,并且不能折叠在一起。 包含小写字母的环境变量名称的名称空间保留给应用程序。应用程序可以使用此名称空间中的名称定义任何环境变量,而无需修改标准实用程序的行为。
这甚至适用于非export
的常规shell变量,因为指定与环境变量同名的shell变量将覆盖后者。
BASH_COMMAND
在bash中具有不同的含义-因此可以在脚本的开头将其设置为非空值。没有任何事情可以阻止COMMAND
对兼容POSIX的Shell解释程序有意义并且已经被其使用。
如果要避免在shell设置了内置变量并使用脚本名称的情况下产生副作用,或者脚本意外覆盖了对shell有意义的变量,请使用小写或大小写混合的名称为兼容POSIX的外壳编写脚本时。
答案 1 :(得分:0)
您可以简单地使用$#
。它代表给定参数的数量:
if [ $# = 0 ]
then
echo "help ..."
fi
答案 2 :(得分:0)
在不更改常规模式的情况下解决问题的最简单方法是使用Bourne Shell中的“高级”参数扩展功能(这不是 bash 特定的)。在这种情况下,我们可以使用:-
修饰符来提供默认值:
COMMAND="${1:-triggerusagemessage}"
shift
case "$COMMAND" in
loop)
loop_
;;
...
triggerusagemessage)
echo $"Usage: $0 {loop|...}"
exit 64
;;
esac
有关可用参数扩展修饰符的简短介绍,请参见外壳手册页中的“参数扩展”段落。
(请注意退出代码64,在某些操作系统上是为这种情况保留的。)
答案 3 :(得分:-2)
该行:echo $"Usage: $0 {loop|...}"
的第一个$
是做什么用的?
如果您不想重复此消息,只需将其放入函数中,并在case语句之前检查空字符串。
#! /bin/bash
die()
{
"Usage: $0 {loop|...}"
exit 1
}
COMMAND="$1"
[ -z $COMMAND ] && die
shift
case "$COMMAND" in
loop)
loop_
;;
*)
die
exit 1
;;
esac