以下は私が実行したい機能です。問題は、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
エイリアスの代わりに関数を使用すると、あまり混乱しない可能性があります。