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

おすすめ記事