Bashのコマンド置換を含む変数

Bashのコマンド置換を含む変数

私はbash(GNU bash、バージョン4.4.20(1)-release(i686-pc-linux-gnu))のシェル拡張を理解しようとしています。

私の対話型bashシェル型から

x='$(id)'
$x
$(echo $x)

最後の 2 行のいずれかで、次の形式のエラーが発生すると予想されます。

bash: uid=xxx(user): command not found

しかし、得た

bash: $(id): command not found

ここでコマンド置換がなぜ起こらないのか理解できません。変数拡張によって達成すべきではないでしょうか?私の考えでは、ここで説明されているようにShell操作に関連しているようです。https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Operation

誰かがこの動作を説明できますか?

私はbash拡張をより正確に理解したいと思います。私の質問に実際のスクリプトを実行することに興味はありません。

ベストアンサー1

$(…)コマンド置換です(「プロセス置換」<(…)など)。変数置換とコマンド置換は、文字列の左から右に同じパスで発生します。これらの代替結果によって引き起こされる唯一の作業は、ワードセパレータとワイルドカードです。

したがって、5文字の文字列にx='$(id)'設定してください。その後、実行するためにシェルは値を置き換えます。スペースやワイルドカードが含まれていないため、コマンド名として扱われます。x$(id)$x$x$(id)

比較:

x='@(id)'
shopt -s extglob
echo /none/$x /usr/bin/$x

ファイル/none/idが存在しないが/usr/bin/id存在すると仮定すると、echoコマンドは(echo明らかに)、/none/@(id)( globパターン/none/@(id)が何も一致しないので変更されていないまま)、/usr/bin/id(globパターンが/usr/bin/@(id)ファイルと一致するので変更されていない)の3つの単語で拡張されます。一致する単一要素のリスト)。

bashのマニュアルでは、関連文は次のとおりです。シェル拡張部分。

拡張順序は、中かっこ拡張、引数と変数拡張、算術拡張、コマンド置換(左から右へ)です。

2つのセミコロンの間のすべての内容は一度に渡されます。各パスは前のパスの結果に基づいています。

単一の文章(上記で引用した文章と同じくらい複雑な文章でも)で全体の話を伝えることはできません。シェルセマンティクスは複雑です。私はどのシェルのマニュアルにも特別なケースの詳細がすべて含まれているかどうか疑問に思います。これPOSIX仕様より形式的ですが、bash固有の拡張を扱うことはなく、非常に奇妙なケースも未定義のままにしておきます。

おすすめ記事