use*_*ser 3 arrays bash shell posix shellcheck
在允许变量赋值中的 ${@:2} 语法上,他们说我不应该使用,"${@:2}"因为它破坏了不同 shell 的内容,而我应该使用它"${*:2}"。
但是,使用"${*:2}"的,而不是"${@:2}"完全是无稽之谈,因为这样做"${@:2}"不等同于"${*:2}"如下面的例子:
#!/bin/bash
check_args() {
echo "\$#=$#"
local counter=0
for var in "$@"
do
counter=$((counter+1));
printf "$counter. '$var', ";
done
printf "\\n\\n"
}
# setting arguments
set -- "space1 notspace" "space2 notspace" "lastargument"; counter=1
echo $counter': ---------------- "$*"'; counter=$((counter+1))
check_args "$*"
echo $counter': ---------------- "${*:2}"'; counter=$((counter+1))
check_args "${*:2}"
echo $counter': ---------------- "${@:2}"'; counter=$((counter+1))
check_args "${@:2}"
Run Code Online (Sandbox Code Playgroud)
-->
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
1: ---------------- "$*"
$#=1
1. 'space1 notspace space2 notspace lastargument',
2: ---------------- "${*:2}"
$#=1
1. 'space2 notspace lastargument',
3: ---------------- "${@:2}"
$#=2
1. 'space2 notspace', 2. 'lastargument',
Run Code Online (Sandbox Code Playgroud)
如果我不能使用"${@:2}"(正如他们所说的),我可以使用什么等价物代替?
这是原始问题处理除第一个参数(在 bash 脚本中)之外的所有参数,并且他们将参数与空格放在一起的唯一答案是使用"${@:2}"
除非您按照链接操作,否则问题中的上下文不清楚。它与shellcheck.net 的以下建议有关:
local _help_text="${@:2}"
^––SC2124 Assigning an array to a string! Assign as array, or use * instead of @ to concatenate.
Run Code Online (Sandbox Code Playgroud)
简短回答:不要将事物列表(如参数)分配给普通变量,而是使用数组。
长答案:通常,"${@:2}"将获得除第一个参数之外的所有参数,每个参数都被视为一个单独的项目(“单词”)。"${*:2}",另一方面,产生一个由除第一个参数之外的所有参数组成的单个项目,由空格分隔(或第一个字符$IFS是什么)。
但是在您分配给普通变量的特定情况下,该变量只能存储单个项目,因此var="${@:2}" 也会将参数折叠为单个项目,但它的执行方式不如"${*:2}". 为了避免这种情况,请使用能够存储多个项目的东西:数组。所以:
var="${@:2}"var="${*:2}"arrayvar=("${@:2}")括号使它成为一个数组)注意:要取回数组的元素,将每个元素正确视为单独的项目,请使用"${arrayvar[@]}". 此外,并非所有 shell 都支持数组(特别dash是不支持它们),因此如果您使用它们,您应该确保使用 bash shebang(#!/bin/bash或#!/usr/bin/env bash)。如果您真的需要可移植到其他 shell,事情就会变得更加复杂。