我一直在使用 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
,第一个示例实际上会在ksh93
or中“工作” zsh
;但第二个将是杀不死的在ksh93
或zsh
;-)
答案2
Ctrl-Z
触发器SIGTSTP
,参见https://stackoverflow.com/questions/11886812/whats-the-difference- Between-sigstop-and-sigtstp/11888074。SIGTSTP
暂停进程:
事实:如果您是一名 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)