正如@Bakuriu 在评论中指出的那样,这与BASH 中的问题基本相同:输入期间的 Ctrl+C 会中断当前终端 但是,我只能在 bash 作为另一个可执行文件的子进程运行时重现该问题,而不是直接从 bash ,它似乎可以很好地处理终端清理。我很想知道为什么 bash 在这方面似乎被打破了。
我有一个 Python 脚本,用于记录由该脚本启动的子进程的输出。如果子进程恰好是一个 bash 脚本,该脚本在某些时候通过调用read -s
内置函数(-s
用于防止输入字符回显的键)读取用户输入,并且用户中断脚本(即通过 Ctrl-C),然后 bash 无法将输出恢复到 tty,即使它继续接受输入。
我将其缩减为一个简单的示例:
$ cat test.py
#!/usr/bin/python
import subprocess as sp
p = sp.Popen(['bash', '-c', 'read -s foo; echo $foo'])
p.wait()
运行./test.py
后它将等待一些输入。如果您键入一些输入并按 Enter,则脚本会按预期返回并回显您的输入,并且没有问题。但是,如果您立即按下“Ctrl-C”,Python 会显示 的回溯KeyboardInterrupt
,然后返回到 bash 提示符。但是,您键入的任何内容都不会显示在终端上。但是,键入reset<enter>
成功会重置终端。
我不知道这里到底发生了什么。
更新:我也设法在没有 Python 的情况下重现了这一点。我试图在 strace 中运行 bash 以查看是否可以收集正在发生的任何事情。使用以下 bash 脚本:
$ cat read.sh
#!/bin/bash
read -s foo
echo $foo
运行strace ./read.sh
并立即按 Ctrl-C 会产生:
...
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon -echo ...}) = 0
brk(0x1a93000) = 0x1a93000
read(0, Process 25487 detached
<detached ...>
PID 25487 在哪里read.sh
。这使终端处于相同的损坏状态。但是,strace -I1 ./read.sh
只需中断该./read.sh
过程并返回到正常的、未损坏的终端。