我有一个简单的脚本,其中第一个参数是为文件名保留的,所有其他可选参数都应该传递给脚本的其他部分。
使用 Google 我找到了 this wiki,但它提供了一个文字示例:
echo "${@: -1}"
我无法进行其他任何工作,例如:
echo "${@:2}"
或者
echo "${@:2,1}"
我从终端收到“错误替换”。
问题是什么,除了传递给 bash 脚本的第一个参数之外,我该如何处理?
"{@:2}"
不起作用,这就是正确答案与上面匹配的原因。
用这个:
echo "${@:2}"
以下语法:
echo "${*:2}"
也可以,但不推荐使用,因为正如 @Gordon 已经解释的那样,使用 *
,它将所有参数作为带有空格的单个参数一起运行,而 @
保留它们之间的中断(即使一些参数本身包含空格)。它与 echo
没有区别,但对许多其他命令很重要。
如果您想要一个同样适用于 /bin/sh
的解决方案,请尝试
first_arg="$1"
shift
echo First argument: "$first_arg"
echo Remaining arguments: "$@"
shift [n]
移动位置参数 n 次。 shift
将 $1
的值设置为 $2
的值,将 $2
的值设置为 $3
的值,依此类推,将 $#
的值减一。
foo=shift
并没有达到我的预期。
foo=$(shift)
shift
(在shell中)没有任何输出。它只是丢弃 $1
并将所有内容向下移动。 2) $(...)
启动一个子shell,它有自己的本地参数。它移动子shell中的参数,这不会影响父shell
somecommand "$1" "${@:2}"
使用这种方法(即移位“内联”)吗?
在 bash 4 或更高版本中工作:
#!/bin/bash
echo "$0"; #"bash"
bash --version; #"GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)"
在功能上:
echo $@; #"p1" "p2" "p3" "p4" "p5"
echo ${@: 0}; #"bash" "p1" "p2" "p3" "p4" "p5"
echo ${@: 1}; #"p1" "p2" "p3" "p4" "p5"
echo ${@: 2}; #"p2" "p3" "p4" "p5"
echo ${@: 2:1}; #"p2"
echo ${@: 2:2}; #"p2" "p3"
echo ${@: -2}; #"p4" "p5"
echo ${@: -2:1}; #"p4"
注意 ':' 和 '-' 之间的空格,否则表示不同:
${var:-word} 如果 var 为 null 或未设置,则 word 将替换 var。 var 的值不会改变。 ${var:+word} 如果设置了 var,则用 word 代替 var。 var 的值不会改变。
如下所述:Unix / Linux - Shell Substitution
bash
时示例运行良好。尽管如此,我不能使用“减号”元素。这对我没有用。不像预期的那样。谢谢
http://wiki.bash-hackers.org/scripting/posparams
它解释了 shift
的使用(如果你想丢弃前 N 个参数),然后是 implementing Mass Usage
遇到这个寻找别的东西。虽然这篇文章看起来相当陈旧,但下面使用 set -- "${@:#}"
说明了 bash 中最简单的解决方案(至少是 bash 4),其中 # 是我们要向前保留的数组元素的起始编号:
#!/bin/bash
someVar="${1}"
someOtherVar="${2}"
set -- "${@:3}"
input=${@}
[[ "${input[*],,}" == *"someword"* ]] && someNewVar="trigger"
echo -e "${someVar}\n${someOtherVar}\n${someNewVar}\n\n${@}"
基本上,set -- "${@:3}"
只是像 perl 的 shift 一样弹出数组中的前两个元素,并保留包括第三个在内的所有剩余元素。我怀疑还有一种方法可以弹出最后一个元素。
#!/usr/bin/env sh
这就是我遇到问题的原因。您的示例工作正常,与上面提供的相同,在我删除了那个 shebang 之后"${@:2}"
- 使用*
将所有参数作为带有空格的单个参数一起运行,而@
保留它们之间的中断(即使某些参数本身包含空格)。echo
的差异并不明显,但它对许多其他事情都很重要。echo
足以为您连接它们;其他命令可能不太好。不要只使用其中一个:了解*
和@
之间的区别,以及何时使用它们。您应该大致平等地使用它们。一个很好的例子说明何时会出现问题:如果$3
包含换行符 (\n
),它将被替换为空格,前提是您有一个默认的$IFS
变量。echo
仅用作示例——在这种情况下,它们应该 不 i> 一起运行。根据我的经验,您希望它们一起运行的情况很少见(请参阅 this question for one example),而"$@"
几乎总是您想要的。此外,仅当$@
(或$*
)不在双引号中时才会出现您提到的换行问题。$*
。