Bash:接受第一个命令行参数,然后传递其余参数


78

例:

check_prog hostname.com /bin/check_awesome -c 10 -w 13

check_remote -H $HOSTNAME -C "$ARGS"
#To be expanded as
check_remote -H hostname.com -C "/bin/check_awesome -c 10 -w 13"

我希望以上所述是有道理的,因为我将在大约20多个命令中使用该参数,所以参数会发生变化。它是包装程序的一种奇怪方法,但是可以解决我们在此处使用的一些系统的一些问题(70年代的爱代码)

上面的代码可以用perl或python编写,但是Bash是首选方法

Answers:


103

您可以使用班次

shift是一个内置的shell,可对位置参数进行操作。每次调用shift时,它会将所有位置参数“下移”一位。$ 2变成$ 1,$ 3变成$ 2,$ 4变成$ 3,依此类推

例:

$ function foo() { echo $@; shift; echo $@; } 
$ foo 1 2 3
1 2 3
2 3

9
太棒了!像灵符一样工作echo $1 shift echo $* 是如何为将来的人们使用shift进行搜索的一个示例,像这样运行它./script.sh cmd1 cmd2 cmd3 cmd4,它将把$ 1设置为cmd1,其余的将像我想要的那样设置为cmd2 cmd3 cmd4
user554005 2012年

3
$#减1,除非它已经是0。你也可以给shift一个数值参数由不止一个地方转移。
基思·汤普森

8
@ user554005:你应该总是使用echo "$@"替代echo $*echo "$*"因为未加引号形式和引用$*形式“扁平化”,这通常是不想要的参数。
暂停,直到另行通知。

1
因此通常使用SOME_VAR=$1; shift; some_cmd "$*"。现在some_cmd传递参数2..n。效果很好...谢谢!
布莱德·帕克斯

5
@BradParks在将文件名作为参数传递时将被另一个命令读取,并且如果文件名包含空格,我认为您想要这样做是SOME_VAR=$1; shift; some_cmd "$@"因为"$@"确保确保转义的空格将以反斜杠作为前缀传递。"$*"将删除\ 字符(或如上所述平化文件名)

11

作为程序员,我强烈建议您不shift要这样做,因为修改状态的操作会影响脚本的大部分内容,并使之难以理解,修改和调试:sweat_smile:。您可以改为使用以下内容:

#!/usr/bin/env bash

all_args=("$@")
first_arg=$1
second_args=$2
rest_args=("${all_args[@]:2}")

echo "${rest_args[@]}"

3
我强烈建议不要将参数列表存储在简单的字符串变量中和/或扩展变量时不要使用双引号(例如REST_ARGS此处)。使用数组(如ALL_ARGS),并使用[@]和双引号将其展开。
戈登·戴维森

1
@GordonDavisson您可以bash根据自己的建议重写代码段,也可以编写其他代码段吗?我非常想了解它,并在bash我现在正在使用的某些脚本中使用它。在此先感谢您,并继续努力!
阿卜杜拉

3
我已对其进行编辑以显示推荐的表单。将参数列表存储为字符串会丢失多个参数与包含空格的单个参数之间的区别;不使用双引号将其展开将在所有空格(包括原来位于参数中的空格)上进行分割,并且还将展开任何类似于文件名通配符的内容。例如,如果将原始./script "foo" "bar" "six * nine"文件运行为,它将显示“六个<当前目录中的文件列表>九个”。
戈登·戴维森,

2
我还建议使用小写或大小写混合的变量名,以避免与具有特殊含义的各种全大写字母名称发生冲突。哦,shellcheck.net擅长指出有问题的引号和其他常见错误。
戈登·戴维森,

感谢@GordonDavisson现在,我可以编写更好的BASH脚本,遵循我的回答的人不会重复我的错误。
阿卜杜拉
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.