编辑和执行命令被 SIGTSTP 中断

编辑和执行命令被 SIGTSTP 中断

我一直在使用 bashedit-and-execute-command功能:

edit-and-execute-command (C-x C-e)

在当前命令行上调用编辑器,并将结果作为 shell 命令执行。 Bash 尝试按顺序调用$VISUAL$EDITOR、 和作为编辑器。emacs

https://www.gnu.org/software/bash/manual/html_node/Miscellaneous-Commands.html

我注意到,如果我调用编辑器,使用 Ctrl-Z 将其放入后台,然后使用fg将其放回前台,则 shell 不再执行临时文件。

如果我想中止命令,这很方便,但我发现这种行为第一次发生时有点令人惊讶。

我的问题:

  • 为什么会出现这种情况?

    我从源代码中知道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它的基本原理,但它与我可以检查的所有 shell 实现上的普通(和相关的键绑定)相同。

我的想法是,这与 shell 无法递归后台或前台有关本身,但仅限其子作业(进程组)。您可能会注意到同样的事情:

$ 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!

与 in 不同bash,第一个示例实际上会在ksh93or中“工作” zsh;但第二个将是杀不死的ksh93zsh;-)

答案2

Ctrl-Z触发器SIGTSTP,参见https://stackoverflow.com/questions/11886812/whats-the-difference- Between-sigstop-and-sigtstp/11888074SIGTSTP暂停进程:

事实:如果您是一名 Linux 程序员,当您使用 Ctrl-Z 中断 shell 中运行的进程而不杀死它时,您会得到 SIGTSTP。这通常会导致 shell 将其放入挂起的作业列表中。

简单用户第一个答案下的评论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

相关内容