Zsh 如何停止当前的前台进程并重新执行它?

Zsh 如何停止当前的前台进程并重新执行它?,zsh,sigint,Zsh,Sigint,我经常不得不重新启动服务器,看看我的更改是否正常。我在shell中保持此服务器的打开状态,以便快速访问当前日志。下面是我在shell中键入的内容:^C!!⏎。即send SIGINT,然后重新启动历史记录中的最后一个事件 所以我想要的是键入,比如说^R,并得到相同的结果 (注意:我使用zsh) 我尝试了以下方法: 重新启动-函数(){ kill-INT%%&!! } zle-N重新启动小部件重新启动功能 bindkey“^R”重新启动小部件 但是,在运行我的服务器时,^R似乎不会被传递到she

我经常不得不重新启动服务器,看看我的更改是否正常。我在shell中保持此服务器的打开状态,以便快速访问当前日志。下面是我在shell中键入的内容:
^C!!⏎。即
send SIGINT
,然后
重新启动历史记录中的最后一个事件

所以我想要的是键入,比如说
^R
,并得到相同的结果

(注意:我使用zsh)

我尝试了以下方法:

重新启动-函数(){
kill-INT%%&!!
}
zle-N重新启动小部件重新启动功能
bindkey“^R”重新启动小部件

但是,在运行我的服务器时,^R似乎不会被传递到shell,而是传递到没有注意到shell的服务器。所以我看不到通用的解决方案,而测试返回值和进程名应该是可行的。

只要作业在前台运行,键就不会传递给shell。因此,设置一个用于终止前台进程并再次启动它的键绑定是行不通的

但由于您可以无休止地启动服务器,因此它会自动重新启动。假设命令名为
run\u server
,您可以在shell上这样启动它:

(TRAPINT(){};while sleep .5; do run_server; done)
周围的括号开始一个子shell,
TRAPINT(){}
为此shell禁用
SIGINT
。while循环将继续重新启动
run_服务器
,直到
sleep
退出,退出状态不为零。这可以通过使用
^C
中断
睡眠来实现。(如果不设置
TRAPINT
,中断
run\u server
也会中断循环)

因此,如果要重新启动服务器,只需按
^C
并等待0.5秒。如果要停止服务器而不重新启动,请在0.5秒内按两次
^C

要保存某些键入,您可以为此创建一个函数:

doloop() {(
    TRAPINT(){}
    while sleep .5
    do
        echo running \"$@\"
        eval $@
    done   
)}
然后用doloop run\u server调用它。注意:您仍然需要附加的
()
,因为函数本身不会打开子shell

eval
允许使用shell构造。例如
doloop LANG=C locale
。在某些情况下,您可能需要使用(单个):


太好了,谢谢。现在我遇到了一个小问题,尝试启动
LANG=C./run\u服务器将无法工作,并给出
doloop:5:command not found:LANG=C
。大多数情况下,我的本地代码都很好,但这里我想访问原始日志,翻译对调试没有帮助。也就是说,带有单个
$@
的行不由shell计算。我更新了脚本以使用
eval$@
。谢谢。我还用
tput setaf 6
tput setaf 7
包装了回音,因此我可以很容易地看到重新启动的开始位置。
$ doloop echo $RANDOM
running "echo 242"
242
running "echo 242"
242
running "echo 242"
242
^C
$ doloop 'echo $RANDOM'
running "echo $RANDOM"
10988
running "echo $RANDOM"
27551
running "echo $RANDOM"
8910
^C