gpt4 book ai didi

bash - 案例声明没有捕获空字符串

转载 作者:行者123 更新时间:2023-12-04 16:17:07 24 4
gpt4 key购买 nike

我想检测是否传递了任何参数或无效参数并打印帮助消息。单独检查空参数是可能的,但不是那么优雅。

我的 bash 脚本如下所示:

COMMAND="$1"
shift
case "$COMMAND" in
loop)
loop_
;;
...
*)
echo $"Usage: $0 {loop|...}"
exit 1
esac

当没有传递参数时,什么都不执行;如果我通过“”然后触发正确的情况。如果我直接使用 $1 而不是使用临时变量,那么它会按预期工作。

我什至尝试为 "") 添加一个特定的大小写,但无济于事。

最佳答案

您的 case 语句与未给定的 $1 不匹配的唯一方法是一开始就没有输入它。

考虑以下几点:

#!/usr/bin/env bash
set -e

command=$1
shift
case $command in
*) echo "Default case was entered";;
esac

$1 未设置时,这不会发出任何输出——但不会,因为 case 语句有任何问题。

相反,问题在于 shift 以非零退出状态退出 当没有任何可用的 shift 时,set -e 导致整个脚本在失败时退出。


这个故事的第一个寓意:不要使用set -e(或#!/bin/bash -e)

参见 BashFAQ #105进行更深入的讨论——或 exercises included therein如果赶时间。 设置-e is wildly incompatible在不同的“符合 POSIX 标准”的 shell 之间,从而使行为难以预测。手动错误处理可能并不有趣,但它更可靠。


第二:考虑一个使用函数

这为您提供了一种简洁的方式,可以将您的使用信息放在一个地方,并在必要时重新使用它(例如,如果您没有 $1shift):

#!/usr/bin/env bash

usage() { echo "Usage: $0 {loop|...}" >&2; exit 1; }

command=$1
shift || usage
case $command in
*) usage ;;
esac

因为 || usageshift 的退出状态被认为是“checked”,所以即使您确实使用set -e 运行您的脚本,将不再构成 fatal error 。


或者,将 shift 显式标记为已检查

类似地:

shift ||:

...将运行 shift,但随后回退到运行 :(true 的同义词,历史上/习惯上暗示占位符use) should shift 失败,类似地阻止 set -e 触发。


旁白:为您自己的变量使用小写名称

POSIX specifies shell(以及标准适用的其他工具)的行为仅由具有全大写名称的环境变量修改:

Environment variable names used by the utilities in the Shell and Utilities volume of POSIX.1-2017 consist solely of uppercase letters, digits, and the ( '_' ) from the characters defined in Portable Character Set and do not begin with a digit. Other characters may be permitted by an implementation; applications shall tolerate the presence of such names. Uppercase and lowercase letters shall retain their unique identities and shall not be folded together. The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.

这甚至适用于常规的、非exported shell 变量,因为指定与环境变量同名的 shell 变量会覆盖后者。

例如,

BASH_COMMAND 在 bash 中有不同的含义——因此可以在脚本的开头设置为非空值。没有什么可以阻止 COMMAND 对 POSIX 兼容的 shell 解释器具有类似的意义,并且已经被其使用。

如果您想避免 shell 使用脚本使用的名称设置内置变量或脚本意外覆盖对 shell 有意义的变量的情况,请坚持使用小写或混合大小写的名称在为 POSIX 兼容的 shell 编写脚本时。

关于bash - 案例声明没有捕获空字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51579102/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com