在允许在变量赋值中使用${@: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}"-->
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',如果我不能使用"${@:2}" (像他们说的),那么我可以使用什么等效的?
这是一个原始的问题处理除第一个参数外的所有参数(在bash脚本中),他们唯一的解决方法是使用"${@:2}"。
发布于 2019-06-30 04:00:21
问题中的上下文是不清楚的,除非你遵循这些链接。是关于以下来自shellcheck.net的建议的
local _help_text="${@:2}"
^––SC2124 Assigning an array to a string! Assign as array, or use * instead of @ to concatenate.简单回答:不要将事物列表(如参数)分配给普通变量,而是使用数组。
长答案:通常,"${@:2}"将得到除第一个参数之外的所有参数,并将每个参数作为一个单独的项("word")处理。另一方面,"${*:2}"生成一个单独的项,其中除了第一个参数外,由一个空格(或$IFS的第一个字符)分隔。
但是,在将变量赋值给普通变量的特定情况下,变量只能存储单个项,因此var="${@:2}"也将参数折叠为单个项,但它以比"${*:2}"更不一致的方式执行。为了避免这种情况,可以使用能够存储多个项的东西:数组。所以:
var="${@:2}"var="${*:2}"arrayvar=("${@:2}") (括号使它成为一个数组)注意:要获得数组的元素,并将每个元素正确地作为一个单独的项处理,请使用"${arrayvar[@]}"。而且,并不是所有的shell都支持数组(特别是dash不支持它们),所以如果使用它们,您应该确保使用bash (#!/bin/bash或#!/usr/bin/env bash)。如果您真的需要其他shell的可移植性,事情就会变得更加复杂。
发布于 2019-06-30 04:37:32
${@:2}和${*:2}都不是可移植的,许多shell都会拒绝这两种无效的语法。如果您想要处理除第一个参数之外的所有参数,则应该使用移位来消除第一个参数。
first="${1}"
shift
echo The arguments after the first are:
for x; do echo "$x"; done此时,第一个参数在"$first“中,位置参数向下移动。
发布于 2019-06-30 05:29:20
这演示了如何将所有${@}参数组合为一个没有hack ${@:1}或${@:2} (实例化)的变量:
#!/bin/bash
function get_all_arguments_as_single_one_unquoted() {
single_argument="$(printf "%s " "${@}")";
printf "unquoted arguments %s: '%s'\\n" "${#}" "${single_argument}";
}
function get_all_arguments_as_single_one_quoted() {
single_argument="${1}";
printf "quoted arguments %s: '%s'\\n" "${#}" "${single_argument}";
}
function escape_arguments() {
escaped_arguments="$(printf '%q ' "${@}")";
get_all_arguments_as_single_one_quoted "${escaped_arguments}";
get_all_arguments_as_single_one_unquoted ${escaped_arguments};
}
set -- "first argument" "last argument";
escape_arguments "${@}";-->
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
quoted arguments 1: 'first\ argument last\ argument '
unquoted arguments 4: 'first\ argument last\ argument '正如@William Pursell答案所指出的,如果您只想获得{@:2}参数,可以在"${@}"之前添加一个shift调用
function escape_arguments() {
shift;
escaped_arguments="$(printf '%q ' "${@}")";
get_all_arguments_as_single_one_quoted "${escaped_arguments}";
get_all_arguments_as_single_one_unquoted ${escaped_arguments};
}-->
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
quoted arguments 1: 'last\ argument '
unquoted arguments 2: 'last\ argument 'https://stackoverflow.com/questions/56822216
复制相似问题