代码之家  ›  专栏  ›  技术社区  ›  Ondra Žižka David Lilljegren

SSH—从“while read”循环调用SSH时,终端行为异常

  •  0
  • Ondra Žižka David Lilljegren  · 技术社区  · 8 年前

    我正在编写一个Bash脚本来跨多个服务器自动化任务。

    我正在通过SSH登录Centos 7计算机以运行一些编辑器( nano ,则, vi ,…)

    ssh -tt centos@... '/bb/Conf edit'
    

    这个 /bb/Conf edit 基本上只是 vi /bb/conf.yaml

    当我从shell运行SSH命令时,它运行得很好。但是,当从 while read ...; do 循环,编辑器的大小错误(我猜是80x40),似乎忽略了我按的键-即 纳米级 ,Ctrl+x不起任何作用。唯一有效的键是Ctrl+c,它会关闭连接。

    我想这与 TERM 变量,根据 this ,所以我尝试添加 export TERM=xterm TERM=rxvt /bb/Conf 或者调用SSH的地方。该变量实际上是在目标环境中设置的(我已经尝试 echo $TERM 就在之前 六、 ).但码头仍然行为不端。

    然后我试着只发出一个命令 ssh ... 到新脚本。运行时,编辑器工作正常。

    过了一会儿,我发现它在 while read 循环,但不在内部。我假设编辑们做了一些stdin/stdout魔术,然后 read 不知怎么打破了这一点。

    有没有办法像这样运行编辑器 六、 纳米级 从一个循环中?

    (我的目的是允许用户编辑多台服务器上的文件。)

    1 回复  |  直到 8 年前
        1
  •  2
  •   glenn jackman    8 年前

    那是因为两者 read ssh 正在读取相同的输入流。解决方案是为while read循环使用不同的文件描述符:

    while IFS= read -r -u3 line; do
        ssh ...
    done 3< file
    

    这里,我们使用的是文件描述符3,而不是stdin。


    冗长的管道可能很难阅读和维护,但您可以建设性地使用空格:下面允许换行 | && || 此外,括号还引入了一个子shell,其中包含任意脚本,因此缩进很有帮助。

    while read -u3 line; do
        : do stuff here that needs to read from stdin
    done 3< <(
        command 1 of the pipeline |
        command 2 |
        command 3
    )
    

    这是清晰易读的。缺点是它将管道的最后一部分(while循环)放在第一位,因此代码有点向后流动。