![在使用标准输入时是否可以保存当前的“stty -g”设置?](https://linux22.com/image/161019/%E5%9C%A8%E4%BD%BF%E7%94%A8%E6%A0%87%E5%87%86%E8%BE%93%E5%85%A5%E6%97%B6%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E4%BF%9D%E5%AD%98%E5%BD%93%E5%89%8D%E7%9A%84%E2%80%9Cstty%20-g%E2%80%9D%E8%AE%BE%E7%BD%AE%EF%BC%9F.png)
我想保存然后恢复stty
脚本中的当前设置,该脚本也很消耗,stdin
但stty -g
正在抱怨它:
stty:“标准输入”:设备的 ioctl 不合适
我尝试关闭stdin
文件描述符并stty
在具有覆盖 FD 的子 shell 中调用。我不知道如何分离stdin
,stty -g
希望得到帮助或建议。
请注意,我对 POSIX 兼容性特别感兴趣。请不要使用 Bash/Zsh 主义。
重现问题的最小脚本:
#!/usr/bin/env sh
# Save this so we can restore it later:
saved_tty_settings=$(stty -g)
printf 'stty settings: "%s"\n' "$saved_tty_settings"
# ...Script contents here that do something with stdin.
# Restore settings later
# (not working because the variable above is empty):
stty "$saved_tty_settings"
运行print 'foo\nbar\n' | ./sttytest
查看错误。
答案1
@icarus 的评论:
或许
saved_tty_settings=$(stty -g < /dev/tty)
?
实际上指向了正确的方向,但这并不是故事的结局。
您需要在以下情况下应用相同的重定向:恢复 stty
状态也是如此。否则,您仍然会遇到Invalid argument
ioctl 失败的情况恢复阶段...
正确的做法:
saved_tty_settings="$(stty -g < /dev/tty)"
# ...do terminal-changing stuff...
stty "$saved_tty_settings" < /dev/tty
这是我测试的实际脚本;我将整个过程重写为经典的 Bourne shell 脚本:
#!/bin/sh
# This is sttytest.sh
# This backs up current terminal settings...
STTY_SETTINGS="`stty -g < /dev/tty`"
echo "stty settings: $STTY_SETTINGS"
# This reads from standard input...
while IFS= read LINE
do
echo "input: $LINE"
done
# This restores terminal settings...
if stty "$STTY_SETTINGS" < /dev/tty
then
echo "stty settings has been restored sucessfully."
fi
测试运行:
printf 'This\ntext\nis\nfrom\na\nredirection.\n' | sh sttytest.sh
结果:
stty settings: 2d02:5:4bf:8a3b:3:1c:7f:15:4:0:1:ff:11:13:1a:ff:12:f:17:16:ff:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
input: This
input: text
input: is
input: from
input: a
input: redirection.
stty settings has been restored sucessfully.
使用 Debian Almquist Shell dash
0.5.7 和 GNU Coreutils 8.13 的stty
.