これを実装するより良い方法は何ですかprint_last_arg
?
#!/bin/sh
print_last_arg () {
eval "echo \${$#}" # this hurts
}
print_last_arg foo bar baz
# baz
(そうであれば、どうすればいいかわかります#!/usr/bin/zsh
。#!/bin/sh
私の問題は、これを達成するための合理的な方法を見つけることです#!/bin/sh
。)
編集:上記は愚かな例です。私の目標は印刷最後のパラメータですが、シェル関数で最後のパラメータを参照する方法があります。
編集2:このように明確ではない質問についてお詫び申し上げます。 今回はきちんと解決してほしい。
これが代わりに/bin/zsh
、/bin/sh
私はこのようなものを書くことができたでしょう
#!/bin/zsh
print_last_arg () {
local last_arg=$argv[$#]
echo $last_arg
}
表現は、$argv[$#]
最初の編集で説明した例です。シェル関数で最後のパラメータを引用する方法。
したがって、元の例を次のように書く必要がありました。
print_last_arg () {
local last_arg=$(eval "echo \${$#}") # but this hurts even more
echo $last_arg
}
...私が望むものが何であるかを明確にするために、課題の右側にあまり怖いものが配置されています。
ただし、すべての例で最後のパラメータにアクセスされることに注意してください。非破壊的。 IOW、最後のパラメータにアクセスしても、全体の位置パラメータには影響しません。
答え1
オープンピラー(スペースなしの位置パラメータ)を提供する例:
print_last_arg foo bar baz
基本項目の場合はIFS=' \t\n'
次のとおりです。
args="$*" && printf '%s\n' "${args##* }"
より安全に拡張するには、"$*"
IFSを設定します(@StéphaneChazelasベース)。
( IFS=' ' args="$*" && printf '%s\n' "${args##* }" )
ただし、位置パラメータにスペースを含めることができる場合、上記の方法は失敗します。この場合は、以下を使用してください。
for a in "$@"; do : ; done && printf '%s\n' "$a"
これらの技術は回避され、eval
副作用はありません。
テスト対象shellcheck.net
答え2
この質問は2年を超えましたが、もっと簡単なオプションを共有したいと思いました。
print_last_arg () {
echo "${@:${#@}:${#@}}"
}
実行してみましょう
print_last_arg foo bar baz
baz
吹くシェルパラメータ拡張。
編集する
より簡潔に言えば:
echo "${@: -1}"
(空間に注目してください)
macOS 10.12.6でテストされていますが、利用可能なほとんどの* nixバージョンでは最後の引数も返す必要があります...
はるかに害が少ない¯\_(ツ)_/¯
答え3
簡単な方法は次のとおりです。
print_last_arg () {
if [ "$#" -gt 0 ]
then
s=$(( $# - 1 ))
else
s=0
fi
shift "$s"
echo "$1"
}
(引数が渡されなかったときに元のバージョンが失敗したという@cuonglmのポイントに基づいて更新されました。空の行がエコーされます。else
必要に応じて句の動作を変更してください。)
答え4
これは、すべてのPOSIX互換シェルだけでなく、既存のPOSIX以前のSolaris Bourneシェルでも機能します。
do=;for do do :;done;printf "%s\n" "$do"
以下は、同じアプローチに基づく関数です。
print_last_arg()
if [ "$*" ]; then
for do do :;done
printf "%s\n" "$do"
else
echo
fi
PS:関数本体の周りに中かっこを忘れてしまったとは言わないでください;-)