如何在 bash 脚本中省略某些输入变量(如 $1 和 $2)时使用 $*?

Ore*_*asm 15 command-line bash scripts

例如,

elif [[ $append = $1 ]]
then
  touch ~/directory/"$2".txt
  echo "$variable_in_question" >> ~/directory/"$2".txt
Run Code Online (Sandbox Code Playgroud)

要创建一个包含所有后续输入的文本文件"$2",或者附加一个包含所有后续输入的现有文本文件"$2",我将使用什么来代替"$variable_in_question"第 4 行?

我基本上想要"$*",但省略了"$1""$2"

des*_*ert 34

您可以使用bash参数扩展来指定范围,这也适用于位置参数。对于$3......$n它会是:

"${@:3}" # expands to "$3" "$4" "$5" …
"${*:3}" # expands to "$3 $4 $5 …"
Run Code Online (Sandbox Code Playgroud)

要知道,无论$@$*忽略第一个参数$0。如果您想知道在您的情况下使用哪个:可能您想要一个引用的$@. $*除非您明确希望单独引用参数,否则不要使用。

您可以按如下方式尝试:

$ bash -c 'echo "${@:3}"' 0 1 2 3 4 5 6
3 4 5 6
$ echo 'echo "${@:3}"' >script_file
$ bash script_file 0 1 2 3 4 5 6
2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)

请注意,在第一个示例$0中填充了第一个参数,0而在脚本中使用时$0填充了脚本的名称,如第二个示例所示。脚本的名称 tobash当然第一个参数,只是它通常不被认为是这样——对于一个可执行的脚本并称为“直接”也是如此。所以在第一个例子中我们有$0= 0$1=1等,而在第二个例子中它是$0= script_file$1= 0$2=1等;${@:3}选择每个以 开头的参数$3

可能范围的一些附加示例:

 # two arguments starting with the third
$ bash -c 'echo "${@:3:2}"' 0 1 2 3 4 5 6
3 4
 # every argument starting with the second to last one
 # a negative value needs either a preceding space or parentheses
$ bash -c 'echo "${@: -2}"' 0 1 2 3 4 5 6
5 6
 # two arguments starting with the fifth to last one
$ bash -c 'echo "${@:(-5):2}"' 0 1 2 3 4 5 6
2 3
Run Code Online (Sandbox Code Playgroud)

进一步阅读:


ste*_*ver 27

您可以使用shift内置:

$ help shift
shift: shift [n]
    Shift positional parameters.

    Rename the positional parameters $N+1,$N+2 ... to $1,$2 ...  If N is
    not given, it is assumed to be 1.

    Exit Status:
    Returns success unless N is negative or greater than $#.
Run Code Online (Sandbox Code Playgroud)

前任。给予

$ cat argtest.bash 
#!/bin/bash

shift 2

echo "$*"
Run Code Online (Sandbox Code Playgroud)

然后

$ ./argtest.bash foo bar baz bam boo
baz bam boo
Run Code Online (Sandbox Code Playgroud)

  • 当第一个或多个参数是特殊的时,`shift` 很好,并且将它们挑选到单独的变量中是有意义的(`foo="$1"; bar="$2";`,或 `if [[ something with $1 ] ];then blah blah; shift`。但是@dessert 的非破坏性方法的回答在其他情况下很好,当您*做* 以后仍然需要完整列表时,或者当您使用更高级的语法来挑选有限范围的参数时, 不是无穷大,如果 `$@` 没有那么多元素,则不会向命令引入空参数。 (6认同)
  • @Oreoplasm 我认为值得一提的是,`shift` 方法将使您无法访问 `$1` 和 `$2`。在您的脚本中,您将“$2”与“$variable_in_question”一起使用,您要么需要更改它,要么使用参数扩展方法。 (3认同)

mur*_*uru 13

通常,您可以将位置参数复制到数组,删除数组的任意索引,然后使用数组扩展到您想要的索引,而不会丢失原始参数。

例如,如果我想要除第一个、第四个和第五个参数之外的所有参数:

args=( "$@" )
unset args[0] args[3] args[4]
echo "${args[@]}"
Run Code Online (Sandbox Code Playgroud)

在副本中,索引移动 1,因为$0不是 的一部分$@