$@ 除了第一个参数

use*_*780 64 shell scripting bash

我需要编写一个以这种方式运行的shell脚本:

./myscript arg1 arg2_1 arg2_2 arg2_3 ....... arg2_#
Run Code Online (Sandbox Code Playgroud)

脚本中有一个 for 循环

for i in $@
Run Code Online (Sandbox Code Playgroud)

但是,据我所知,$@ 包括 $1 到 $($#-1)。但是对于我的程序 $1 与 $2 $3 $4 等明显不同。我想从 $2 循环到最后......我该如何实现?谢谢:)

Sté*_*las 76

首先,请注意,$@没有引号是没有意义的,不应使用。$@只应在引用 ( "$@") 和列表上下文中使用。

for i in "$@" 有资格作为列表上下文,但在这里,要循环位置参数,规范的、最便携和更简单的形式是:

for i
do something with "$i"
done
Run Code Online (Sandbox Code Playgroud)

现在,要从第二个元素开始循环遍历元素,规范且最便携的方法是使用shift

first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Run Code Online (Sandbox Code Playgroud)

之后shift,过去的内容$1已从列表中删除(但我们已将其保存在 中$first_arg),而过去的$2内容现在在$1. 位置参数已向左移动 1位置(用于shift 2移动 2...)。所以基本上,我们的循环是从过去的第二个参数循环到最后一个。

使用bash(and zshand ksh93,但仅此而已),另一种方法是:

for i in "${@:2}"
do something with "$i"
done
Run Code Online (Sandbox Code Playgroud)

但请注意,它不是标准sh语法,因此不应在以#! /bin/sh -.

zshor 中yash,您还可以执行以下操作:

for i in "${@[3,-3]}"
do something with "$i"
done
Run Code Online (Sandbox Code Playgroud)

从第三个到第三个最后一个参数循环。

zsh,$@也称为$argv数组。因此,要从数组的开头或结尾弹出元素,您还可以执行以下操作:

argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
Run Code Online (Sandbox Code Playgroud)

shift也可以被写1=()zsh

在 中bash,您只能分配给$@具有set内置函数的元素,因此要从末尾弹出 3 个元素,这将类似于:

set -- "${@:1:$#-3}"
Run Code Online (Sandbox Code Playgroud)

并从第 3 个循环到第 3 个最后:

for i in "${@:3:$#-5}"
do something with "$i"
done
Run Code Online (Sandbox Code Playgroud)

POSIXly,要弹出 的最后 3 个元素"$@",您需要使用循环:

n=$(($# - 3))
for arg do
  [ "$n" -gt 0 ] && set -- "$@" "$arg"
  shift
  n=$((n - 1))
done
Run Code Online (Sandbox Code Playgroud)

  • 另一种(丑陋的)bash 可能性:间接变量:`for ((i=2; i<=$#; i++)); 用“${!i}”做点什么;完成` (3认同)

Joh*_*ohn 14

我想你想要shift内置的。它重命名$2$1$3$2等。

像这样:

shift
for i in "$@"; do
    echo $i
done
Run Code Online (Sandbox Code Playgroud)