我有一个 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}"