如何使用"$ {@:2}"进行可移植性? [英] How to portability use "${@:2}"?

查看:98
本文介绍了如何使用"$ {@:2}"进行可移植性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

允许在变量赋值中使用$ {@:2}语法我不应该使用"${@:2}",因为它会在不同的外壳之间使事情破裂,而应该使用"${*:2}".

On Allow for ${@:2} syntax in variable assignment they say I should not use "${@:2}" because it breaks things across different shells, and I should use "${*:2}" instead.

但是使用"${*:2}"代替"${@:2}"是无意义的,因为执行"${@:2}"并不等同于"${*:2}",因为

But using "${*:2}" instead of "${@:2}" is nonsense because doing "${@:2}" is not equivalent to "${*:2}" as the following example:

#!/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}"(如他们所说的),那是什么等价的我可以代替吗?

If I cannot use "${@:2}" (as they say), what is the equivalent can I use instead?

这是原始问题处理所有参数除了第一个(在bash脚本中),它们将参数和空格保持在一起的唯一答案是使用"${@:2}"

This is original question Process all arguments except the first one (in a bash script) and their only answer to keep arguments with spaces together is to use "${@:2}"

推荐答案

除非您遵循链接,否则问题中尚不清楚上下文.这涉及到 shellcheck.net的以下建议:

There's context that's not clear in the question unless you follow the links. It's concerning the following recommendation from shellcheck.net:

local _help_text="${@:2}"
                  ^––SC2124 Assigning an array to a string! Assign as array, or use * instead of @ to concatenate.

简短的回答:不要将事物列表(例如参数)分配给简单变量,而应使用数组.

Short answer: Don't assign lists of things (like arguments) to plain variables, use an array instead.

长答案:通常,"${@:2}"将获得除第一个参数以外的所有参数,每个参数都被视为一个单独的项目(单词").另一方面,"${*:2}"会产生单个项目,其中除了第一个参数之外,所有其他参数都粘在一起,并用空格(或$IFS的第一个字符所分隔)分隔.

Long answer: Generally, "${@:2}" will get all but the first argument, with each treated as a separate item ("word"). "${*:2}", on the other hand, produces a single item consisting of all but the first argument stuck together, separated by a space (or whatever the first character of $IFS is).

但是在特定情况下,您要分配给一个普通变量,该变量只能存储单个项目,因此var="${@:2}" 会将参数折叠为单个项目,但是它的实现方式与"${*:2}"不一致.为了避免这种情况,请使用能够存储多个项目的东西:数组.所以:

But in the specific case where you're assigning to a plain variable, the variable is only capable of storing a single item, so var="${@:2}" also collapses the arguments down to a single item, but it does it in a less consistent way than "${*:2}". In order to avoid this, use something that is capable of storing multiple items: an array. So:

  • 真的很糟糕:var="${@:2}"
  • 稍差一些:var="${*:2}"
  • 更好:arrayvar=("${@:2}")(括号使它成为数组)
  • Really bad: var="${@:2}"
  • Slightly less bad: var="${*:2}"
  • Much better: arrayvar=("${@:2}") (the parentheses make this an array)

注意:要取回数组的元素,并将每个元素都正确地视为一个单独的项目,请使用"${arrayvar[@]}".另外,并非所有外壳程序都支持数组(特别是dash不支持它们),因此,如果使用它们,则应确保使用bash shebang(#!/bin/bash#!/usr/bin/env bash).如果您确实需要可移植到其他shell,则事情会变得更加复杂.

Note: to get the elements of the array back, with each one treated properly as a separate item, use "${arrayvar[@]}". Also, arrays are not supported by all shells (notably, dash doesn't support them), so if you use them you should be sure to use a bash shebang (#!/bin/bash or #!/usr/bin/env bash). If you really need portability to other shells, things get much more complicated.

这篇关于如何使用"$ {@:2}"进行可移植性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆