間接コマンド(eval)を使用して変数として出力

間接コマンド(eval)を使用して変数として出力

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異なる動作に対して異なる有効なサフィックスを使用して名前を自由にオーバーライドします。

おすすめ記事