旧Linux内核的怪异行为

旧Linux内核的怪异行为,linux,bash,timeout,Linux,Bash,Timeout,我有一个旧设备,它有一个最小的定制linux内核。大约20年前,我们从一家公司购买了该设备,并对其进行了编程以满足我们的需要 uname -r 2.4.21 我在这个设备上开发了一个基于文本的用户界面,我允许通过telnet和串口访问它 使用telnet连接时,调用两次read-s STR,会导致忽略第二次读取。这是因为telnet以“\r\n”结束行 e、 g: 令我惊讶的是,read-t1有时会阻塞。因此,我运行以下命令来说明这种行为: set -x while true; do rea

我有一个旧设备,它有一个最小的定制linux内核。大约20年前,我们从一家公司购买了该设备,并对其进行了编程以满足我们的需要

uname -r
2.4.21
我在这个设备上开发了一个基于文本的用户界面,我允许通过telnet和串口访问它

使用telnet连接时,调用两次
read-s STR
,会导致忽略第二次读取。这是因为telnet以
“\r\n”
结束行

e、 g:

令我惊讶的是,
read-t1
有时会阻塞。因此,我运行以下命令来说明这种行为:

set -x

while true;
do
read -t 1 -n 10000 STR
echo "timeout"
sleep 5
done
脚本在两次循环后挂起,仅在我按enter键时才继续

最后,我尝试了以下方法:

set -x
unset STR
while true;
do
read -s -n 1 char
if [[ $char == $'\r' ]]
then
read -s -n 1 ignore
break
elif [[ $char == $'\n' ]]
then
break
fi
STR=$STR$char
done
这导致:

++ true
++ read -s -n 1 char
 ]][[ a == \
++ [[ a == \
 ]]
++ STR=a
++ true
++ read -s -n 1 char   <-------- HERE I PRESSED ENTER
 ]][[ '' == \
++ [[ '' == \
 ]]
++ STR=a
++ true
++ read -s -n 1 char
该问题不会发生,即调用read两次不会导致忽略第二次read调用


有人知道如何解决这个问题吗?

终端正在将每个'\r'翻译成'\n',因此您看不出两者之间有什么区别。您可以使用
stty igncr
完全忽略CR。这样,您的第一种方法应该可以:

stty igncr
echo "Enter new password: "; read -s password1
echo "Enter new password again: "; read -s password2
stty sane
最后的
sttysane
可能不是必需的


如果这种方法不起作用,试着改用
stty-icrnl
(但是这样,
$password1
$password2
将在末尾有一个
\r
;你可以用
tr-d'\r'
来抑制它。)

关于这个声音的一些事情是错误的。首先,由于该对是
\r\n
,因此第一次读取应包括参数中存储的字符串末尾的
\r
,而不需要第二次读取才能清除它。第二,虽然telnet协议可能使用
\r\n
,但这些不应传递给通过telnet接收其输入的底层shell。@chepner这确实很奇怪。在我看来,
\r
包含在内部字段分隔符(IFS)中。但是,由于内核中缺乏对基本系统命令的支持,我无法打印
IFS
。我尝试了导出IFS='\t\n',但没有成功。顺便问一下,除了
[$char==$'\r'].[124;[$char==$'\r']].[$char==$'\n'].
之外,还有其他方法来测试
\r
\n
吗?或者甚至可以用十六进制打印接收到的字符?我认为内核版本一点都不重要。你能告诉我们你正在使用的shell和它的版本吗?@mkalkov-GNU-bash,版本2.05.8(1)-发行版(i386-redhat-linux-GNU)
++ true
++ read -s -n 1 char
 ]][[ a == \
++ [[ a == \
 ]]
++ STR=a
++ true
++ read -s -n 1 char   <-------- HERE I PRESSED ENTER
 ]][[ '' == \
++ [[ '' == \
 ]]
++ STR=a
++ true
++ read -s -n 1 char
uname -r
2.6.24.6
stty igncr
echo "Enter new password: "; read -s password1
echo "Enter new password again: "; read -s password2
stty sane