读取控制字符串的答案发送到xterm

问题描述 投票:0回答:2

在xterm中运行的交互式程序可以将控制代码发送到xterm,这会导致xterm通过发回答案来响应。我想看看答案。这些控制代码中有几个,所以为了便于讨论,让我们坚持使用控制序列ESC Z,这会导致xterm发回其终端ID。例如,当我输入我的shell时(我正在使用Zsh,但据我所知,这也适用于bash)

echo -e '\eZ'

我在终端缓冲区中看到了字符串

63;1;2;4;6;9;15;22;29c

并听到一声嘟嘟声(因为从xterm发送的答案也包含不可打印的字符,特别是它还包含一个ESC)。我的目标是以某种方式将这个字符串63; 1; 2; 4; 6; 9; 15; 22; 29c读入shell变量。我主要使用Zsh,但是bash中的解决方案也是受欢迎的(或者在任何其他脚本语言中,例如Ruby,Perl或Python)。

我的第一次尝试非常简单:

#!/bin/zsh
echo -e '\eZ'
read -rs -k 25
echo $REPLY | xxd

这是有效的,因为我发现(有一点试验和错误),我特定xterm的这个特定示例中的回答字符串的长度为25个字符。当然,在一般情况下,我事先并不知道确切的长度,所以我想要一个更灵活的解决方案。我的想法是一次读一个字符,直到什么都没有留下,然后我编写了以下程序来测试我的想法:

#!/bin/zsh
str=''
echo -e '\eZ'
while :
do
  read -rs -t -k
  if [[ -z $REPLY ]]
  then
    echo '(all read)'
    break
  fi
  str="${str}$REPLY"

完成echo $ str | XXD

但是,这不会读取任何内容。 REPLY总是空的。

我也尝试了变化read -rs -t -k 1(相同的效果)和read -rs -k 1(永远挂起)。即使read -rs k 25不再工作,所以我猜罪魁祸首是while循环,而不是read命令。但是,如果我想一次读取一个字符的回答字符串,我确实需要一个循环。

有人可以解释一下,为什么我的方法失败了,以及我如何解决我的问题?

bash zsh xterm
2个回答
1
投票

您可以直接从终端读取读取语句,例如,

read -rs -t -k < $(tty)

解决shell的重定向问题。


0
投票

由于我在这里没有得到任何关于这个问题的新发现,我在Unix/Linux Forums上转发了这个问题并得到了Zsh的答案,以及对bash的改进答案,我想在此总结一下:

假设tty包含表示我的终端的字符串(这里是@ThomasDickey在他的回答中给出的建议),Zsh命令

read -rs -t 0.2 -k 1 <$tty # zsh

将下一个单个字符读入变量REPLY。重要的是要注意-t必须被赋予超时值,并且没有字符可用的事实不能从空的REPLY推断出,而是从read命令的退出代码推断出来。

至于bash,有一个比我在评论中发布的更简单的解决方案:With

read -rs -t 0.2 -d "" <$tty # bash

整个回答字符串被一次性读入REPLY;没有循环是必要的。

© www.soinside.com 2019 - 2024. All rights reserved.