2009-11-07 7 views
10

のは、私は別の変数に格納された変数の名前があるとしましょう:今ルックアップシェル変数、間接的

myvar=123 
varname=myvar 

を、私はただの$ VARNAME変数を使用して123を取得したいのですが。 これは直接の方法ですか?私はこの思い付いた、名前による検索には、このような、bashの組み込み見つかりませんでした。

最後にそれほど悪くは見えませんが、私ならば、私は思ったんだけど
function var { v="\$$1"; eval "echo "$v; } 

ので

var $varname # gives 123 

もっと明白な何かを逃した。前もって感謝します! man page of bashから

+0

これは6年後に尋ねられた質問の重複としてマークされていますか?また、IMHOこの質問+答えは、リンクされたものよりも明確です。 – inger

答えて

12

${!varname} 

パラメータの最初の文字が感嘆符である場合、 変数間接のレベルが導入されています。 Bashは残りのパラメータから形成された変数の値を変数の名前として使用します。 この変数が次に展開され、その値はパラメータ自体の値ではなく、 の残りの部分で使用されます。これは間接的な拡張と呼ばれる です。

+0

もちろん、それだけです。 RTFMを試しましたが、何らかの理由でこの説明: ----------------- $ {!prefix *} $ {!prefix @} 接頭辞に一致する名前。名前が接頭辞で始まり、IFS 特殊変数の最初の文字で区切られた変数の名前に展開されます。 @が使用され、展開が二重引用符で囲まれると、各変数名は別の単語に展開されます。 ----------------- 私は明らかな答えとして私を襲っていませんでした。 よろしく! – inger

+0

@ DigitalRoss:質問には「bash」というタグが付いていたので、なぜ答えをposix標準に制限したいのですか? – tangens

+1

これは良い答えです。はい、それはbashにも当てはまります。私は完璧な答えは '$ {!varname}'を発表して、OPを起こりそうなトラブルから守るために移植性の問題に気づくでしょう。 – DigitalRoss

12

直接のPosix準拠の構文はありません。bash ismのみです。

eval t="\$$varname" 

これはbashはログインシェルであると/bin/shが小さく高速ashのようなもので、それらのシステムを含む、任意のPOSIXシェル上で動作します:私は通常これを行います。私はbashが好きで、私のログインシェルのためにそれを使うが、私はコマンドファイルのbashismsを避ける。


注:bash固有のスクリプトを書く上での1つの問題は、インストールされているbashを数えることができても、パスのどこにでもある可能性があることです。その場合、完全に一般的な/usr/bin/envshebangのスタイルを使用することをお勧めしますが、まだ100%ポータブルではなく、セキュリティ上の問題があることに注意してください。

+0

値が必要なコンテキストに応じて、代入ではなく '$(eval \ $$ varname)'を使うことができます。 –

+0

ほとんど試しましたが、それを逃しました。それは私のものよりも短いです! – inger

+0

は '$(....)'ではありません。 '\' eval \ $$ varname' \ 'ではないはずですか? –

1

${!varname}私は私のバッシュスキルをさっぱりする必要があるとき、私は通常、Advance Bash-Scripting Guideを見てトリック

$ var="content" 
$ myvar=var 
$ echo ${!myvar} 
content 
+0

お返事が遅れて到着したようですので、私はその1つを選択しました:) – inger

1

を行う必要があります。 Indirect References

記法であなたの質問の外観について

は次のとおりです。

Version < 2 
\$$var 

Version >= 2 
${!varname} 
+0

うわー、そのガイドをすばやく見ています - 明らかにあまりにも早く:) 私はそれを正しく読む必要があるようです。 ! – inger

+0

これは私のクイックリファレンスです。私はそれをマニュアルページよりも頻繁に使用する傾向があります。しかし、あなたが言うように、一見しただけでは不十分であることがあります。 –

+0

一般に、ABSは巨大な塩で取られるべきです。しかし、この答え自体は間違っていません。 – tripleee

0
# bmuSetIndirectVar() 
# TO DOUBLE CHECK THIS COMMENT AND DEMO 
# This function is an helper to read indirect variables. 
# i.e. get the content of a variable whose name is saved 
# within an other variable. Like: 
# MYDIR="/tmp" 
# WHICHDIR="MYDIR" 
#  bmuSetIndirectVar "WHICHDIR" "$MYDIR" 
# 
bmuSetIndirectVar(){ 
    tmpVarName=$1 
    locVarName=$1 
    extVarName=$2 
    #echo "debug Ind Input >$1< >$2<" 
    eval tmpVarName=\$$extVarName 
    #echo "debug Ind Output >$tmpVarName< >$extVarName<" 
    export $locVarName="${tmpVarName}" 
} 

私は現在、この小さな機能を使用しています。私はそれに完全に満足していません、私はWeb上で(私はここにそれらを書くことを思い出すことができる)異なるソリューションを見てきましたが、それは動作するようです。これらの数行の中にはすでにいくつかの冗長性と余分なデータがありますが、デバッグには役立ちました。

あなたの場所でそれを見たい場合は、つまり、私はそれを使用しています、確認してください。もちろん https://github.com/mariotti/bmu/blob/master/bin/backmeup.shellfunctions.sh

を、それが最善の解決策ではありませんが、私は ご希望の場合、仕事で起こって作られましたもう少し一般的なものに置き換えることができます。

+0

質問の前に;)私はこの機能が気に入らないのは、通常は悪い設計のトリガーである「評価」を使用することです。もちろん、必要な場所があります。私が好きなのは、関数を使って問題からコードを切り離し、後でそれを最適化できるということです。シェルバージョンチェックなどを導入することさえできます。 – mariotti

関連する問題