evalで実行すると、この間接コマンドにどのような問題がありますか?
#!/bin/bash
OS=AIX
host=myhost
CMD_AIX="(o=\`host \"$host\" \`)"
CMD=\$CMD_$OS
echo $CMD
eval echo $CMD
eval "$CMD"
出力:
$ myscript.sh
$CMD_AIX
(o=`host "myhost" `)
myscript.sh: line 12: (o=`host: command not found
編集 - 注:SCO、AIX、およびLinuxが混在しており、それぞれ32ビットおよび64ビットのバリエーションを含む、複数のバージョンを持つ約40台のサーバーで構成される非常に異質な構造を持っています。 SCOとAIXは更新できません。 BashとKornシェルはすべてのサーバーで共通ですが、bashバージョン3(SCOでは)に制限されており、Kshにはいくつかの違いがあるため、v3で連想配列をサポートしていないbashを好む(更新できません)。これらのサーバーは数ヶ月以内にAIX 7およびLinuxに置き換えられ始めます。
すでにshとbshベースのいくつかのスクリプトを含むメンテナンスが必要な大規模システムがあります。今は再構築せず、再構築することもできません。交換が完了するまで数ヶ月間ヘッダーのメンテナンスを行うだけです。
これらのスクリプトで使用される方法は、一部のスクリプトを生成する大規模なソリューションに主に分散されており、最初から変更することはできません。
上記のサンプルコードは採用されたコードの一部であり、実際のコードではありません。論理について考えるのではなく、間接参照(評価)についてのみ考えてください。
解決策:非常に効果的なソリューションを得ましたリンク評価、よい:
torun=`eval $CMD`
output=`eval torun`
ベストアンサー1
私の考えであなたがしていることの問題は、それが何の意味もないということです。攻撃しようとする意図はありませんが、私のポイントは、あなたが何をしているのかについて間違った考えを持っていると思うということですeval
。コマンドを実行するためにそれを使用したいようです。これはデフォルトのシェル機能であり、シェルが最後の拡張を新しいコマンドとして解釈しようとする必要はありません。これがまさにそれですeval
。
すべての引用を書く方法は、何も評価されないようにすることです。あるいは、むしろ最初のレベルを保護しています。完全- だから、2番目のパスまでは何も起こりません。これらすべての問題は、あなたもそうすることができるということです。いいえ2回目の評価を実施(および2番目のレベルの引用符)別言します。
$OS
- 値に基づいていくつかのコマンドを実行したいようです。おそらく…?さて、これはシェルで最もアクセスしやすいAPI機能の1つです。
たとえば、
OS=AIX
host=myhost
_cmd_AIX() { host "$host"; }
_cmd_WIN() { exit "$((LOSE=1))"; }
ご覧のとおり、参照されている定義された関数を実行できます。そのコマンド名は、拡張の結果として発生しても意味を持つために特別な2番目のソルバーは必要ありません。ちょうどコマンドの位置にする必要があります。このように引数を受け入れることもできるので、必要に応じて$host
引数を渡すことができます。$1
ただこう呼んでください。
"_cmd_$OS"
varが$OS
展開され、AIX
結果のコマンドワードは、_cmd_AIX
名前が完全に表示され、コマンドの場所で適切に区切られたシェルワードを持つ事前定義されたシェル関数であるために実行されます。それはすべてです。ねじる必要はありません。独自の配列も付属しています。
$OS
異なる動作に対して異なる有効なサフィックスを使用して名前を自由にオーバーライドします。