SIGTSTPによって中断されたコマンドの編集と実行

SIGTSTPによって中断されたコマンドの編集と実行

私は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/11888074SIGTSTPプロセスを一時停止します。

事実: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)

関連情報