解释shell命令: shift $(($optind - 1))

Gau*_*ant 45 shell bash shell-script

我不是一个 Linux 人,但被困在一些我必须为我的项目阅读的脚本中。那么任何人都可以帮助我这个命令在做什么吗?

shift $(($optind - 1))
Run Code Online (Sandbox Code Playgroud)

PM *_*ing 66

shift $((OPTIND-1))(注意OPTIND是大写)通常在getopts while循环后立即找到。$OPTIND是由 找到的选项数getopts

正如 pauljohn32 在评论中提到的,严格来说,OPTIND给出了下一个命令行参数的位置。

来自 GNU Bash 参考手册

getopts optstring 名称 [args]

getoptsshell 脚本使用它来解析位置参数。 optstring包含要识别的选项字符;如果一个字符后跟一个冒号,则该选项应该有一个参数,应该用空格将它与它分开。冒号 (':') 和问号 ('?') 不能用作选项字符。每次调用时,getopts将下一个选项放在shell变量名中,name如果不存在则进行初始化,并将下一个要处理的参数的索引放入变量中OPTINDOPTIND每次调用 shell 或 shell 脚本时都会初始化为 1。当一个选项需要一个参数时,getopts 将该参数放入变量中OPTARG。外壳不重置OPTIND 自动地; 如果要使用getopts一组新参数,则必须在同一个 shell 调用内的多次调用之间手动重置它 。

当遇到选项结束时,getopts以大于零的返回值退出。OPTIND设置为第一个非选项参数的索引,名称设置为“?”。

getopts通常分析位置参数,但是如果有更多的参数在给定的argsgetopts解析那些代替。

shift n从位置参数列表中
删除n 个字符串。因此从参数列表中shift $((OPTIND-1))删除所有已解析的选项,getopts因此在此之后,$1将引用传递给脚本的第一个非选项参数。

更新

正如 mikeserv 在评论中提到的那样,shift $((OPTIND-1))可能不安全。为了防止不必要的分词等,所有参数扩展都应该用双引号引起来。所以命令的安全形式是

shift "$((OPTIND-1))"

  • 如果攻击者试图破坏某些东西,他们可能会将这种 IFS 注入到 shell 环境中。我的意思是,可以说,如果他们可以修改你的脚本的父环境,你无论如何都会受到影响,但是好的 shell 脚本会尝试在面对意外的外部更改时保持弹性。 (2认同)

mic*_*has 12

$((...))只是计算东西。在您的情况下,它取值$optint并减去 1。

shift删除位置参数。在您的情况下,它会删除optint-1参数。

有关更多信息,请查看help getopts, help shift,查看man bash“算术扩展”,尤其是 google for getopts.