zshコマンドラインですべてのエイリアスを解決する


12

エイリアスをネストしており、コマンドを実行する前にそれらすべてを解決したい。それ、どうやったら出来るの?

どのキーにもバインドされていない関数がある場合は、M-x foobar私にとっても問題ありません。私も(外部コマンドを使用することができtypecommandwhich、何でも)。私はスレッドからすべてを試しましたなぜ「which」を使用しないのですか?次に何を使用しますか?しかし、何も動作しません。


2
C-x aカーソルの下のエイリアスを展開します(補完システムを使用している場合)。
ステファンシャゼル14

そうですね_expand_alias (^Xa): expands the word the cursor is on if it is an alias。これは便利ですが、bashでは行全体を展開できますが、zshでは展開できません。
WeSenseASoulInSearchOfAnswers 14

_expand_alias編集バッファーが変更されなくなるまで呼び出すバインド可能なコマンドを作成できると思います。
vinc17 14

回答:


10

Ctrl-Alt-E in bashはエイリアスを展開するだけではないことに注意してください。また、変数、コマンド置換(!)、プロセス置換(!)、算術展開、引用符の削除(ファイル名生成(グロビング)またはチルダ展開は行いません)も展開します。

常にエイリアスを展開できるとは限りません。そのため、その用途はありますが、その結果がコマンドラインの意味を潜在的に変え、副作用があり、潜在的に危険であることを認識することが重要です。

例えば:

$ a=';w' b=1
$ alias foo=bar
$ b=2; echo $b $a; cd /tmp/dir && for i do foo $(pwd) <(ls); done

M-C-Eここを押すと、次のようになります。

$ b=2; echo 1 ;w; cd /tmp/dir && for i do foo / /dev/fd/63; done

これにより、まったく異なるコマンドラインが提供され(上記のrm -rf *代わりに持っていたらどうなるか想像してくださいpwd)、fooエイリアスは展開されません。

zsh、関数内で展開されたエイリアスに関するGillesのメモを作成するには、次のようにします。

expand-aliases() {
  unset 'functions[_expand-aliases]'
  functions[_expand-aliases]=$BUFFER
  (($+functions[_expand-aliases])) &&
    BUFFER=${functions[_expand-aliases]#$'\t'} &&
    CURSOR=$#BUFFER
}

zle -N expand-aliases
bindkey '\e^E' expand-aliases

これは、現在のコマンドラインが構文的に有効な場合にのみエイリアスを展開します(したがって、構文チェッカーとしても機能します)。

bashのMCEとは異なり、エイリアスも完全に解決します。たとえば、次の場合:

$ alias ll='ls -l'; alias ls='ls --color'
$ ll

に展開されます:

$ ls --color -l

次のような構文も正規化することに注意してください。

$ for i (*) cmd $i; foo

次のように変更されます:

$ for i in *
        do
                cmd $i
        done
        foo

これはバグです。私が持っている場合alias ls='ls --color'と入力C-x aオーバーls、私が得る:\ls --color(新しいがそうすることをls別名として誤解されていません)。しかし、あなたのでexpand-aliases、私は得ます:ls --color結果を曖昧にします。
vinc17 14

@ vinc17、エイリアスを完全に解決するという点で曖昧ではありません(その点で、bash同等のものよりバグが少ないです)。しかし、それはあなたがそれ以降のコマンドを実行した場合、あなたは(のようにエイリアスの展開の別のラウンドを取得します本当だbashので、理想的にあなたがなるように、例えばラップのために、一時的に無効にエイリアス展開したいと思い、) (){ setopt localoptions noexpandalias; ...; }。を_expand_alias実行するとエイリアスが展開されるだけでなく、バ​​グがあると言うことができることに注意してください\ls
ステファンシャゼル14

@ vinc17、バックスラッシュによるエスケープ_expand_aliasも、alias 'foo=repeat 3 foo'orのように簡単にだまされalias ls='ls --color'; alias '\ls=echo fooled'ます。ここには完璧な解決策はありません。
ステファンシャゼル14

について_expand_aliasalias 'foo=repeat 3 foo'、欠落しているバックスラッシュをバグと見なします。そしてalias '\ls=echo fooled'許可されるべきではありません。ここでは、bashの方が好きですbash: alias: '\ls': invalid alias name
vinc17 14

@ vinc17、私はそれがの制限以外の何かとしてどのように見ることができるか見ることができませんbash。バックスラッシュ付きのエイリアスが気に入らない場合は使用しないでください。しかし、なぜシェルにそれらを拒否させたいのでしょうか?エイリアスはcsh(由来)での貧弱な人の関数置換ですが、Bourneのようなシェルでは、関数では実行できないトリックを実行するためのハックです。 、できることを制限する意味がわからない。
ステファンシャゼル14

6

コマンドラインを関数定義に挿入してから関数を出力すると、エイリアスが展開されます。正規化された空白も取得します。

% alias foo='bar -1'
% alias bar='qux -2'
% f () foo -3
% which f
f () {
        qux -2 -1 -3
}

これらすべてをインタラクティブなコマンドに入れるために、zleウィジェットを作成できます。functions配列のエントリにコードを詰め込むことで、関数を直接定義できます。読み返すときに正規化効果が得られます。

normalize-command-line () {
  functions[__normalize_command_line_tmp]=$BUFFER
  BUFFER=${${functions[__normalize_command_line_tmp]#$'\t'}//$'\n\t'/$'\n'}
  ((CURSOR == 0 || CURSOR = #BUFFER)
  unset 'functions[__normalize_command_line_tmp]'
}
zle -N normalize-command-line
bindkey  normalize-command-line

preexecフックでも同じ正規化効果が得られます。エイリアスは、関数が自動ロードされるときにも展開されます(autoload -Uエイリアスの展開を避けるために一般的に使用されます)。

_expand_aliasそれは別名かどう補完機能は、カーソルの下の単語を拡張します。aliases配列を使用します。再帰的ではありません。を使用してより一般的なエイリアスエクスパンダーを実装できaliasesますが、エイリアスが展開される場所を特定することはシェル構文と密接に関連しているため、やや困難です。


2
autoload -Uzshのドキュメントで推奨されているという理由だけで使用していましたが、-Uこれを読むまで実際に何をしたのか理解できませんでした:)。誰もが興味のためにも、一つは呼び出すことができ_expand_aliasを打つ、コマンドラインにあなたのエイリアスを入力して、直接機能し<Esc>xその後、入力、ミニバッファを起動するには、_expand_alias<Enter>
the_velour_fog

2

ネストされた派手なエイリアスがたくさんあり、zshが実際にそれらを使って何をしているのか、オプションがコマンドに渡される順序がわからない場合は、いつでもzshを起動できます -xオプション付きのます。これにより、コマンドと引数が実行されると出力されます。

ただし、このオプションは、デバッグ目的ではなく、zsh -x呼び出し直後(基本的には.zshrcのすべての関数/ウィジェット/プラグイン)に多くの無駄なものを出力し、コマンドの実行中に冗長になる可能性があることに注意してください定義preexecしてprecmdフックしている場合。

私はまた、それが印刷される、言及する必要がありますだけで、最後に実行され、コマンドを分離して、これらのコマンドがそのように後に別々に印刷されています

alias a='echo a'
alias b='echo b'
alias c='echo c'
alias d='echo d'
a && b || c; d

表示されます

+zsh:1> echo a
a
+zsh:1> echo b
b
+zsh:1> echo d
d
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.