【问题标题】:"Can't shift that many" error in dash case statement破折号案例语句中的“不能转移那么多”错误
【发布时间】:2020-11-22 22:17:04
【问题描述】:

我正在运行 Arch Linux 并在 Dash 中编写脚本。

我有一个虚拟脚本,可以输出我使用参数设置的所有变量。我遵循了一个建议以这种方式获取输入的教程。 Link to article

while [ ! -z "$1" ]; do
    case "$1" in
        --param|-p)
            shift
            #code
            ;;
        --other-param|-op)
            shift
            # code
            ;;
    esac
shift
done

在下面的 MRE 中,输入 -e 参数会在该参数代码内的 shift 行上产生错误“shift: can't shift that many”。这是一致的,我不知道这意味着什么。

为什么会抛出这个错误?

我的 MRE 脚本以 dash 作为 shell 运行,如下所示。

#!/bin/dash

while [ ! -z "$1" ]; do
    case "$1" in
        -e)
            shift
            echo "Error right about..."
            ;;
    esac
shift
done

./mre.sh -e的输出

Error right about...
./mre.sh: 32: shift: can't shift that many

【问题讨论】:

  • 当您使用参数启动脚本时(例如./script A B "C D",三个参数"A""B""C D" 被称为位置参数$1 访问第一个位置参数,$2 第二个等等...当您需要遍历所有位置参数或按顺序获取它们时,您使用 $1 然后调用 shift 删除该位置参数移动下一个到它的位置进行处理(例如shift 使$2 成为新的$1)这样您就可以处理所有位置参数,直到没有剩余要处理。
  • 处理完一个选项后,您将其从参数列表中删除。这就是shift 所做的。如果您不删除刚刚处理的选项,您将在无限循环中一次又一次地处理它。我怀疑错误来自esac 之后的第二个班次,但这太乱了,不能花更多时间。
  • 相比这里的这么多Q,你的看起来很好。实际上,正如其他人所指出的那样,它太长了。有几个人似乎在不发表评论的情况下投反对票。别担心。继续发布这样的 Q,您将获得所需的所有帮助。也许您因使用 dash 而被否决;-)。 ...如果您要继续在“常规”大小的计算机上使用arch,请切换到使用bash。感谢 DavidRankin,您完美地解释了 O.P.s Q!祝大家好运。
  • (见我上面的轻微编辑)。另外,我发现minimal reproducible example 非常“高级”,对新用户没有帮助。我建议通过tags/bash/infoBefore asking about problematic code 部分按您的方式工作。 (并查看同一链接中的如何将糟糕的脚本变成好问题部分)。祝你好运。
  • 是的,通过进一步的研究,我了解了什么是 shift,但我仍然不明白为什么会出现错误。我会做一个MRE。我确实知道那些是什么,但我只是认为靠近顶部的示例将被视为 MRE。它与我在脚本中使用的结构相同,这就是我包含它的原因。大致参见第 18 行和该代码。如果仍然出错,我将尝试制作完整的 MRE 并更新帖子。破折号还有什么问题?我是 Linux 新手,但我听说 bash 不兼容 POSIX,兼容性较差且速度较慢。这不是真的吗?

标签: linux scripting sh


【解决方案1】:

问题是esac 之后的shift。您已经在演示中处理了 "$@" 中的所有参数,所以没有什么需要改变的了。

您正在遵循的教程试图演示一个选项带有参数(如-t 12)如何在第一次移位后将参数留在$1 中,然后在完成时也将其关闭它。 (我不会这样做;当您完成该特定选项时,第二个转变应该发生在 case 内,这样您就不会强制 all 您的选项需要参数。 )

在这方面,Bash 的工作方式与 Dash 完全一样,但当它不能再 shift 时,它不会给你一个明确的错误消息。

【讨论】:

    猜你喜欢
    • 2018-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多