Zsh
実行前に、Bash
すべての入力にカスタムコマンド(名前付けなど)を自動的に追加するために、シェルの動作を変更(または)しようとしています。myapp
デフォルトでは、ユーザーの入力を傍受して変更し、ユーザーがを押すと、変更されたENTER_KEY
コマンドを実行する必要があります。
シェルに入力するすべてのコマンドは次のとおりです。
grep -rn hello
私が入力したように処理する必要があります。
$ myapp grep -rn hello
別の例として、 を入力するとls
で実行する必要がありますmyapp ls
。
ターゲット
いくつかのcliツールのビューアでvimを自動的に試してみたいです。
# myapp
vim -c "term $*"
答え1
目標を考慮する際の最も簡単な解決策は、以下のようにコマンドの結果をvimにパイプすることです。
$ yourcommand | vim -
例えば、
$ grep -rn hello | vim -
答え2
私はあなたがこの配列に入って出て行きたいとし、次のことをしました。 zsh の場合、DEBUG トラップ・ハンドラーは ERR_EXIT オプションを設定することによって、サブミットされたコマンドの実行をスキップし、代わりにカスタム・コマンドを実行できます。
# this is run before every command
debug_trap() {
# get last submitted command
cmd="${history[$HISTCMD]}";
if [ "$cmd" ]; then
# catch the unwrap command and remove the trap
if [ "$cmd" = "unwrap" ]; then
print 'Unwrapping command-line';
trap - DEBUG;
return;
fi
# make sure multiple trap triggers only handle this once
if [ "$handled" != "$HISTCMD;$cmd" ]; then
# when either history index or command text
# changes, we can assume its a new command
handled="$HISTCMD;$cmd";
# do whatever with $cmd
myapp $cmd;
fi
# optionally skip the raw execution
setopt ERR_EXIT;
fi
}
# start the debug trap
wrap() {
print 'Wrapping command-line';
trap 'debug_trap' DEBUG;
}
# this is just defined in order to avoid errors
# the unwrapping happens in the trap handler
unwrap() {}
Bashと同じ:
# bash requires this option in order to skip execution
# inside the debug trap
shopt -s extdebug;
# this is run before every command
debug_trap() {
cmd="$BASH_COMMAND";
# catch the unwrap command and remove the trap
# notice how the alias is expanded here and
# the command is no longer 'unwrap'
if [[ "$cmd" == 'trap - DEBUG' ]]; then
echo 'Unwrapping command-line';
# the trap is unset by the submitted command
else
# do whatever with $cmd
myapp $cmd;
# optionally skip the raw execution
return 1;
fi
}
# start the debug trap
wrap() {
echo 'Wrapping command-line';
trap debug_trap DEBUG;
}
# we can't unset global traps inside a function
# so we use an alias instead
alias unwrap='trap - DEBUG';
使用例:
> myapp() { echo "### $1"; }
> wrap
Wrapping command-line
> echo 123
### echo 123
> unwrap
Unwrapping command-line
> echo 123
123
vim機能を実装するには、myapp関数で "vim -c"を使用するか、トラップ関数で "myapp $ cmd;"行を変更してください。
ただし、使用前の注意事項です。デバッグトラップは非常に難しいので、エラーを減らすためにzshバージョンを試しました。 oh-my-*shなどのプラグインを使用すると、信頼性の高い実装を達成するのに困難を大幅に増やすフック、トラップ、およびその他のメカニズムを導入できます。 zshバージョンはoh-my-zshに対してテストされており、機能する必要があります。 bashのバージョンは修正されていないbash v4.2でのみテストされました。
zshの他の潜在的な実装:テキストバッファを実行する前に操作する戻りキーにバインドされているデフォルトのzleウィジェット「accept-line」をオーバーライドすることができ、これはよりきれいな解決策かもしれません。役に立つ「preexec」フック機能もありますが、独自にコマンドを変更したりスキップしたりする方法はないようです。
その他の使用のアイデア:1つ以上のリモートシステムに(ssh)コマンドを送信したり、スクリプトファイルに書き込んで実行を延期したり、実行前に静的分析を実行したり、確認を要求したり、誤字修正を要求したりするために使用できます。