【问题标题】:/bin/sh: extract command line arguments/bin/sh:提取命令行参数
【发布时间】:2021-10-16 14:21:00
【问题描述】:

我将dash 用作/bin/sh

我的脚本接受任意数量的参数,我需要处理它们,一个变量只包含最后一个参数,另一个变量包含除最后一个参数之外的所有内容。

我知道如何在zsh 中执行此操作,但不幸的是这与dash 不兼容:

last="${@[-1]}"
rest=( ${@[1,-2]} )

如何在/bin/sh 中实现这一点?

【问题讨论】:

  • dash 不支持数组。
  • @400theCat : dash 和 sh 都没有数组。从技术上讲,它们确实有一个(未命名的)数组,您可以使用set 命令设置它,但是您没有此纸牌“数组”的数组切片,使用起来很痛苦。我的建议是,如果你不能坚持使用zsh,你可以从头开始重写整个脚本,而不用过多关注原始的实现。要考虑的另一种选择是切换到更灵活的语言,例如 Perl。

标签: shell command-line sh zsh


【解决方案1】:

您可以简单地轮换现有参数,直到最后一个参数排在第一位,此时您可以将其移除,将剩余的 n-1 参数保留在其原始位置。

n=$#  # Number of arguments

# Rotate the aruguments until the last element is the first
while [ "$n" -gt 1 ]; do
  curr=$1
  shift
  set -- "$@" "$curr"
  n=$((n-1))
done

lastarg=$1
shift

# Now $@ is the same as it started, minus its final element.

以上代码适用于 1 个或多个参数。如果没有参数,您可以在处理之前检查它,或者只是等待最终的shift 失败。 (在后一种情况下,lastarg 将设置为空字符串,如果真正的最后一个参数确实是空字符串,也会发生这种情况。)

【讨论】:

    【解决方案2】:

    使用类似这样的循环(假设至少有一个位置参数):

    rest=""
    while [ $# != 1 ]; do
        rest="$rest $1"
        shift
    done
    last=$1
    

    【讨论】:

    • 当然会遇到带空格的参数问题。数组让处理这类事情变得更加容易......
    • 这比我的想法要好得多。 OP,如果你想决定用这个代替我的
    【解决方案3】:

    Posix 标准(dash 实现的)甚至没有数组。

    您唯一真正的方法是使用 shift 内置和普通 arg 访问: 设置 $2 时,$1 不是最后一个参数。当 $2 未设置时,我们知道 $1 是最后一个参数。现在在循环中执行此操作并相应地处理参数

    【讨论】:

    • Posix sh 是唯一一种 没有 数组的 shell 语言。它们不仅仅是一个 bash 的东西。
    • 我听说有人正在考虑将数组添加到 POSIX 规范中。虽然我相信这一点并没有太大的困难,但我从来没有看到任何关于确切细节的迹象,它可能何时发布,或者不合规的外壳需要多长时间才能合规。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 2021-11-13
    • 2019-04-19
    • 2013-05-16
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多