bashスクリプト引数として与えられた終わりから場所を取得するには? [コピー]

bashスクリプト引数として与えられた終わりから場所を取得するには? [コピー]

シェルスクリプトがありますが、最後のパラメータを使用したいと思います。

#!/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

(バージョン4.3+)では、bash渡された引数を配列に割り当て、インデックスで最後の引数にアクセスできます-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

また(Kusalanandaの答え):

#! /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シェル(ksh、zsh、またはbashでも動作します)の基本的な解決策は次のとおりです。

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

最新のシェル(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=${@[#]}"

2番目のパラメータの場合:

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

関連情報