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


30

我不是Linux的人,但是陷入了一些必须为我的项目阅读的脚本中。那么谁能帮助我这个命令在做什么?

shift $(($optind - 1))

3
如下所述,OPTIND必须为大写,括号内的'$'是可选的。
DarkHeart 2015年

Answers:


49

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

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

从GNU Bash参考手册

getopts optstring名称[args]

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

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

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

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

更新资料

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

shift "$((OPTIND-1))"


似乎只有在所有选项都出现在所有剩余的位置参数之前,这才可以正常工作。正确?
史蒂夫·乔根森

@SteveJorgensen:是的,这是正确的。OTOH,非选项参数后面放置选项违反了sh / bash约定。通常,第一个不以破折号开头的参数表示选项的结尾,并且任何以破折号开头的后续参数均不视为选项。并非所有程序都遵守此约定,但是如果这样做,它会使生活变得简单得多。:)
下午16年

@SteveJorgensen :(续)为什么某些实用程序在选项之前解析操作数?中简要讨论了此主题。正如Gilles在Celada的答案中提到的那样,某些程序(如find)可能看起来像在非选项之后允许选项,但它们却不允许:它们的操作数以破折号开头。
下午

感谢您提供该信息(和编辑)@mosvy这是非常不寻常的IFS,但是安全起着总比后悔好。;)
2

@roaima if IFS=0123456789shift $((OPTIND-1))(不带引号)将变成shift ""静默地被忽略(在中ksh)或生成错误(在bash和中dash)。
mosvy

8

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

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

欲了解更多信息,看看help getoptshelp shift,看man bash的“算术展开”,尤其是谷歌getopts

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.