魚の殻でのコマンド代替を理解することはできません
-
17-09-2020 - |
質問
SH:
~$ `echo ls`
bin/ Desktop/
.
しかし魚の中の:
fish: Illegal command name “(echo ls)”
~% (echo ls)
.
(エラーメッセージがコマンドラインの上に表示されます。)
~% echo (echo ls)
ls
~% eval (echo ls)
bin/ Desktop/
fish: Illegal command name “(echo ls)”
exec (echo ls)
^
~% exec (echo ls)
.
コマンド置換はコマンド自体としてではなく、コマンドのパラメータとしてのみ機能するようです。なぜ?
ええと、ヘルプ文書は
を言うパラメータに一連の括弧が含まれている場合、括弧で囲まれたテキストはコマンドのリストとして解釈されます。
しかしそれでも、なぜ?
解決
コマンドの置換はパラメータ展開に属し、コマンドとしては許可されていません。
同様の例:
SH:
tmpls=ls
$tmpls
.
しかし魚の中の:
% set cmd ls; $cmd
fish: Variables may not be used as commands.
...
.
なぜ
です短い、検証可能性に適しています
この記事詳細:< / P>
通常のシェルのコマンドとして変数を使用することは許可されているため、スクリプトの構文を確実に確認することは不可能です。たとえば、このBASH / ZSHコードのこのスニペットは、あなたの運によって合法的であるかもしれません。あなたはラッキー?
.if true; then if [ $RANDOM -lt 1024 ]; then END=fi; else END=true; fi; $END
bashとzshの両方が、ユーザーがリターンキーを押すと現在のバッファ内のコマンドが終了したかどうかを判断しますが、このような問題のために、それらは失敗することがあります。さらに悪いことに、この完全に合法的なコードはBashによって拒否されます:
.FI=fi; foo() { if true; then true; $FI; }
魚は、変数がコマンドとして許可されていないため、このような問題を回避します。 evalコマンドまたは関数を使用して、コマンドとして変数を使用できるものは、evalコマンドまたは機能を使用して行うことができます。
同じ理由で、コマンドの置換はコマンドとして許可されていません。
(引用例は、 'if'と 'fi'が単純なコマンドではなく予約語であるため、公正ではありません。以下のコメントを参照してください。)
他のヒント
拡張順序では関係ありません。
help expand-command-substitution
のfish
からの:
複数のパラメータ展開を組み合わせるときは、拡張が実行されます 次の順序で:
* Command substitutions
* Variable expansions
* Bracket expansion
* Pid expansion
* Wildcard expansion
.
展開は右から左へ、ネストされたブラケットの拡張 内外から実行されます。
man bash
:
拡張順序は、ブレース展開、チルダ拡張、パラメータ、変数、算術展開とコマンドの置換(行われた)です。 左から右への方法で)、単語分割、およびパス名の拡張。