我需要在PS *中使用哪些转义码来确保终端在shell提示符下恢复正常设置?


2

有时我偶然cat会有一些二进制数据; 有时一些ncurses程序崩溃 - 由于充足的原因终端可能最终处于不良状态,需要手动reset。这种情况经常发生。

这种糟糕的状态可能是无回声,或将所有东西都转换成中国垃圾或许多其他东西。

有什么简单的方法可以确保当shell恢复控制时终端(没有硬重置,清洁屏幕等)设置被恢复?

它是bashTerminal.app但我猜这个问题非常普遍。

Answers:


4

你提到的问题出现在不同的层中,只有一些问题可以通过“转义码”来解决。

终端仿真中的备用字符集

有一个常见的终端问题,可能被描述为“(某些)小写字母显示为符号或线条图”(请参阅其他SO问题)。这可能与你的“中国垃圾”问题无关,但这是我所见过的最接近的问题。在将几乎任何8位数据流解释为UTF-16编码文本时,您也可能遇到“中国垃圾”。通常这不是一个需要重置的“粘性”问题,因此可能不是您所看到的问题。

“卡住线条绘制字符”问题通常来自于向终端仿真器发送无意识的控制序列(或者在切换到备用字符集之后重置终端之前停止程序)。当显示某些二进制数据并且字节流包含选择备用字符集的终端控制序列时,可能会发生这种情况。

这很容易在大多数VT-100型终端上触发,因为只需要一个字节(0x0e;请参阅我之前链接的SO问题的答案)。重置此条件的控制序列也是单个字节(0x0f;通常通过echo ^V^O(键入为echo Control+ V Control+ O,或直接键入printf '\017')生成。

您可以通过提示包含0x0f字节来清除此类问题**
**如果您的“中国垃圾”是由于其他一些问题,那么它可能会有不同的解决方案。

PS1="\[\017\]… "

\[\]在那里告诉bash的,有限制字符非打印。这让bash能够准确了解“物理”光标位置(这对于使用命令行编辑功能时的正确重新显示非常重要)。


正如Ignacio Vazquez-Abrams在他的回答中指出的那样,获得所需控制序列的另一种方法是通过tput命令:

tput rmacs

使用此方法可以避免修改PS1,只需将上面的命令放在PROMPT_COMMAND中:

PROMPT_COMMAND='tput rmacs'

TTY(termios)选项

“无回声”问题***来自基于操作系统的tty设备的选项的意外设置,该设备将终端仿真器连接到终端窗口内运行的所有程序。这通常是由具有错误,崩溃或被杀死的交互式文本UI程序引起的,因此它们无法将tty恢复到其原始状态。

您可以使用stty命令控制这些设置。使用“转义码”无法解决此类问题,因为tty选项是通过软件API配置的(请参阅tcsetattr(3)termios(4))。通常stty sane是一个很好的重置机制。
***同样“no ^ C / ^ Z / ^ /”,“阶梯式输出”(收到LF时没有自动CR)和其他几个问题。

重启

复位命令通常可以与这两种类型的问题有所帮助。它将发送通常会修复备用字符集问题的终端初始化控制序列,并将tty选项重置为合理的值。

重置的问题是它还会在某些系统上打印额外的消息(例如“Erase is ...”,“Interrupt is ......”); 您可能不希望在每个提示之前显示这些内容。如果你的重置实现将消息和控制序列发送到不同的地方(例如一个转到stdout而另一个转到stderr)那么你可能能够过滤掉消息(例如PROMPT_COMMAND='reset 2>/dev/null'(见下文)并跳过将^ O放入提示)。

^ O和 stty sane

bash中,您可以将参数设置PROMPT_COMMAND为command,如果在显示主提示之前bash将运行。您可以将所有呼叫都放在stty sane那里并在提示中输入^ O:

PROMPT_COMMAND='stty sane'
PS1="\[\017\]… "

同样,您可以避免使用tput修改PS1(并处理非VT-100型终端)(如Ignacio Vazquez-Abrams所建议):

PROMPT_COMMAND='stty sane; tput rmacs'

这必须不止一个字节,因为我无法通过head /dev/urandom它重现它- 它按预期输出垃圾,但后来我得到正常的提示。当然终端设置为UTF-8,它是自同步的。这可能是一些终端转义序列。有没有简单的方法来测试常见问题,如果特定的解决方案修复它们?
TAW

@taw:听起来你的“中国垃圾”问题不是由备用字符集选择引起的。实际上,“线条画而不是小写字母”通常是人们在交替字符集模式下楔入时看到的。不幸的是,我不知道诊断终端仿真问题的简单方法。您可以尝试捕获一些有问题的输出script(如果您可以可靠地重现该情况)并通过在新终端中重放捕获的输出的部分来隔离有问题的序列(使用二进制搜索技术以避免必须测试每个字节偏移)。
克里斯约翰森2010年

@taw:您可以触发备用字符集问题(“其他符号和线条图而不是小写”)head /dev/urandom,但您必须首先启用备用字符集tput enacs(或等效的多字节控制序列<ESC> ) 0;这明显不如plain ^ N in a random binary stream)。几乎任何以前运行过使用线条绘图字符的程序的终端实例都已启用此功能; 所以,您可以head /dev/urandom在运行一些线条绘制程序后尝试查看效果并测试^ O.
克里斯约翰森2010年

1

echo -n "$(tput rmacs)"

$PROMPT_COMMAND


1
tput rmacs是一种更好的退出替代字符集模式的方法(它不是特定于VT-100风格的终端),但它对termios问题没有帮助。此外,可能不需要回显命令替换的结果(只是直接运行;输出的控制序列tput极不可能有自己的换行符)。
克里斯约翰森2010年

0

所以我将减少命令行,你总是在xterm或任何终端中有一个“按钮”重置或硬重置,对于terminal.app它在Shell菜单下。发送硬重置alt-command-r。


那么,OP确实在问题中说“没有硬重置”。
克里斯约翰森2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.