如何获取 bash 脚本参数给定的从末尾开始的位置?

如何获取 bash 脚本参数给定的从末尾开始的位置?

我有一个 shell 脚本,我想使用最后一个参数:

#!/bin/bash
echo My last param is #somehow put it here

这是我尝试过的:

echo $$#
echo ${$#}
echo ${(($#))}

不幸的是它没有起作用。

我特别想了解为什么我的选择不起作用,我想做一些诸如双重扩展之类的事情。

从更广泛的意义上讲,我想知道如何访问最后的第 N 个参数。我该如何实现这一目标?

答案1

要从bash脚本获取任何参数,您可以使用切片:

#!/bin/bash

# Get 3rd element from the end
from_end1=3
# Get last element
from_end2=1

# Get slice of array [end - from_end1 : end ] of length 1
echo "${@: -$from_end1: 1}"
echo "${@: -$from_end2: 1}"

您还可以使用它来获取第 N 个元素:

# Get 2nd element
from_beginning=2

echo "${@: $from_beginning: 1}"

记得检查长度;这可能会返回您的程序的名称或空字符串。

答案2

bash(版本 4.3+)中,您可以将传递的参数分配给一个数组并通过索引访问最后一个-1

#!/bin/bash

params=( "$@" )
printf 'The last parameter given to the script is %s\n' "${params[-1]}"

foo () {
    params=( "$@" )
    printf 'The last parameter given to the function is %s\n' "${params[-1]}"
}

一般来说,数组的负索引会访问数组末尾的元素。

答案3

另外(库萨拉南达的回答):

#! /bin/bash 

echo "(bash/ksh): ${@: -1}"
echo "(bash 3.x+): ${!#}"
echo "(bash 3.x+): $BASH_ARGV"
echo "(bash 3.x+/ksh): ${@:$#}"
echo "(bash 3.x+): ${BASH_ARGV[0]}"

如果您担心可移植性:

#!/bin/bash

penultimate=''
ultimate=''

for p in "$@" ; do
    penultimate="$ultimate"
    ultimate="$p"
done

echo "penultimate=$penultimate"
echo "ultimate=$ultimate"

答案4

POSIX shell 的经典解决方案(也适用于 ksh、zsh 或 bash)是:

 for last do :;done; echo "last=$last"
 eval "last=\$$#"; echo "last=$last"

对于较新的 shell(ksh93、zsh、bash):

 echo "last=${@: -1}"
 echo "last=${@:(-1)}"
 echo "last=${@:~0}"
 echo "last=${@:$#}"

仅适用于:

echo "last=${!#}"
echo "last=$BASH_ARGV"
echo "last=${@[-1]}"
echo "last=${@[#]}"

对于倒数第二个参数:

 for arg do penultimate=$ultimate; ultimate=$arg; done; echo "$penultimate"
 eval penultimate=\$$((#-1))
 echo "${@:$((#-1)):1}"
 echo "${@: -2:1}"
 echo "${@:~1:1}"

相关内容