エイリアスコマンドを持つ関数はevalで使用できますが、シェル拡張には使用できません。

エイリアスコマンドを持つ関数はevalで使用できますが、シェル拡張には使用できません。

以下は私が実行したい機能です。問題は、main_cmd他のコマンドのエイリアスに関連しているようです。私はこれがサブシェルを作成するときの問題にすぎないと思いますが、単純な配列拡張ではなぜこれが起こりますか? IIUC サブシェルは作成されません。

my_function() {
    ... code to set opt1 based on $1 ...
    cmd=(
        main_cmd hard_coded_arg_1 hard_coded_arg_2
        -a "$opt1"
        -b hard_coded_opt
        "'$2'"
    )

    # Doesn't work.
    "$cmd[@]"
    # Works
    eval "$cmd[@]"
}

ただ使用したいのですがeval半パターンのようですね(なぜ表現にだけ重要なのか理解してはいませんが)処刑されるまっすぐ、しかしそれは別のトピックです)。

編集:これを明確にするためにzsh

ベストアンサー1

エイリアスは特別です。構文解析が完全に完了する前にコマンドライン処理の最初に処理され、別の関数を呼び出すのではなく、直接テキスト置換のように機能します。

エイリアスを使用すると、次のことができます。

% alias maybe=if
% maybe true; then echo yes; fi
yes

または

% alias foo='echo hi; '
% foo echo bar
hi
bar

でも

% alias xyz='echo "foo'
% xyz bar"
foo bar

2番目のケースでは、foo echo bar翻訳され、echo hi; echo bar一般的な方法で解析されます。関数の場合、コマンド名と2つのパラメータで解析された後、シェルは後でそれがfoo関数か、組み込みコマンドか、外部コマンドかを決定する必要があります。最後の場合、xyz bar"エイリアスが存在しない場合は、コマンドに閉じられていない引用符が表示されます。

上記の例のどれも関数と連携しません。(まあ、とにかく彼らは一種の「働き」をします。誰かは彼らがもっと似ていると言うかもしれません)。残りシェル構文。 )

ただし、これは"${cmd[@]}"解析と拡張後にエイリアス処理がずっと前に消えたことを意味します。実際には、次のようにすることができます。

% alias runcmd='"${cmd[@]}"'
% cmd=(printf "'%s'\n" "foo bar" abc)
% runcmd
'foo bar'
'abc'

これは、アレイ拡張が完了する前にエイリアスが処理されたことを示します。

を使用すると、エイリアス拡張を含む別のコマンドライン処理を強制するevalという点で「動作」します。evalただし、実際には不要なコマンドパラメータの引用符の処理も含まれます。バラよりステファンの詳細な回答この点について。

main_cmdエイリアスの代わりに関数を使用すると、あまり混乱しない可能性があります。

おすすめ記事