私はbashを使ってきました。edit-and-execute-command
機能:
edit-and-execute-command (C-x C-e)
現在のコマンドラインからエディタを呼び出し、結果をシェルコマンドとして実行します。 Bashは
$VISUAL
、$EDITOR
およびエディタを順番に呼び出そうとします。emacs
https://www.gnu.org/software/bash/manual/html_node/Miscellaneous-Commands.html
エディタを呼び出してCtrl-Zを使用して背景に配置してから、前景に戻すと、シェルはもはや一時fg
ファイルを実行しないことがわかりました。
コマンドを中断したいときにこの機能は便利ですが、最初に発生したときにこの動作が少し驚くべきことです。
私の質問:
なぜこれが起こるのですか?
ソースコードで知っています
edit_and_execute_command
最終呼び出しfc
しかし、私は知りません。 なぜSIGTSTPを送信すると、bashが一時ファイルを実行するのを防ぎます。誤ってCtrl-Zを押したが、それでもエディタで開かれた一時ファイルからスクリプトを実行したい場合は、最良の方法は何ですか?
答え1
誤ってクリックしてもエディタが開いているときに一時ファイルのスクリプトを実行し続けたい場合は、
Ctrl-Z
最良の方法は何ですか?
エディタラッパーを使用して最後のコマンドをどこかに保存し、readlineバインディングを使用して復元できます。最後のバッファを保存~/.last_fcedit
してバインディングEsc-/
(Alt-/
)してコマンドラインを置き換える例:
LAST_FCEDIT=$HOME/.last_fcedit
fc(){ case $1 in -e) _fce=$2; set -- "$@" -e _fcedit; esac; command fc "$@"; }
_fcedit()("$_fce" "$@"; s=$?; test -f "$1" && mv "$1" "$LAST_FCEDIT"; exit "$s")
bind -x '"\e/":READLINE_LINE=$(<"$LAST_FCEDIT")'
それから
$ echo FOO<Ctrl-X Ctrl-E>
... in editor ...
<Ctrl-Z>
[1]+ Stopped ( "$_fce" "$@"; s=$?; mv "$1" "$LAST_FCEDIT"; exit "$s" )
$ fg<Enter>
... edit FOO to BAR and exit the editor ...
( "$_fce" "$@"; s=$?; mv "$1" "$LAST_FCEDIT"; exit "$s" )
$ <Alt-/>echo BAR<Enter>
BAR
なぜこれが起こるのですか?
見つかりません。説得力のあるfc
基本ですが、確認できるすべてのシェル実装の一般(および関連するキーバインディング)と同じです。
私の考えでは、これはシェルが後ろまたは前景に再帰できないことに関連していると思います。それ自体、サブタスク(プロセスグループ)のみ可能です。あなたも同じことを見つけることができます:
$ foo(){ cat; echo DONE; }
$ foo
^Z
[1]+ Stopped cat
DONE # but cat is still running!
$ fg
cat
^D
$
または
$ foo=$(cat)
^Z^Z^Z^Z^Z^Z # no way to suspend it!
とは異なり、bash
最初の例は実際にまたはksh93
「動作」ですzsh
が、2番目の例は次のとおりです。殺せないまたはksh93
;-)zsh
答え2
Ctrl-Z
トリガーSIGTSTP
、リファレンスhttps://stackoverflow.com/questions/11886812/whats-the-difference-Between-sigstop-and-sigtstp/11888074。SIGTSTP
プロセスを一時停止します。
事実:Linuxプログラマの場合、Ctrl-Zを使用してシェルで実行されているプロセスを終了せずに中断すると、SIGTSTPが発生します。これにより、通常、シェルはそのジョブを保留中のジョブのリストに入れます。
シンプルユーザー最初の回答の下にコメントするhttps://stackoverflow.com/questions/11886812/whats-the-difference-Between-sigstop-and-sigtstp/11888074
プロセスが中断される理由SIGTSTP
は、これがカーネルで定義されてSIGTSTP
プロセスを中断するためです(http://man7.org/linux/man-pages/man7/signal.7.html)