使用 SSH 运行脚本时,为什么 stdin 输入会替换或损坏我的变量?

使用 SSH 运行脚本时,为什么 stdin 输入会替换或损坏我的变量?

GNU bash,版本 4.3.27

我遇到了一个将输出写入文件的脚本的奇怪问题。脚本 ssh 连接到服务器列表并记录一些服务的状态/子状态。然后我将结果存储在一个数组中。

但是,如果我在控制台窗口运行时输入内容,输入将存储到数组中$result_arr,我不知道为什么

#!/bin/bash


check_services()
{
  server_number="$1"
  local result
  local result_arr
  local error_flag="OK"

  #Get service status
  result=$(ssh server.$host -t "$cmds_services")

  #trim carriage returns if present
  result=$(echo "$result" | tr -d '\r')

  #split result into array by line
  readarray -t result_arr <<<"$result" 

  echo "$server_number,${result_arr[0]},${result_arr[1]},${result_arr[2]},${result_arr[3]},${result_arr[4]},${result_arr[5]},${result_arr[6]},${result_arr[7]}" >> "$OUTFILE"
}

main()
{
  for server in $(cat /home/data/serverlist)
  do
    clear -x
    echo "Gathering Data...Server $server"
    check_services "$server"
  done

}

当我在脚本运行时发送垃圾邮件“a”并输入时,$OUTFILE将如下所示:

1234,active,mounted,active,mounted,a,,a,a 

代替

1234,active,mounted,active,mounted,active,mounted,active,mounted

答案1

发生这种情况是因为您使用了ssh -t.该-t选项在远程端分配一个 tty。

当远程命令工作时,远程 tty 很可能处于回显输入的模式。就像当您在本地运行cat并键入它时,您会看到 tty (而不是 )回显的输入,cat并且只有在Enteror Ctrl+d cat读取它并打印为输出时。

在您的情况下,远程 tty 会回显本地ssh从其标准输入读取的内容。然后将其result=$(ssh …)与远程命令的“真实”输出一起捕获。

如果您不需要远程 tty,请不要传递-tssh

如果您确实需要远程 tty,请传递-t但不要ssh从本地 stdin: 读取</dev/null ssh -t …。请注意,您根本无法输入远程命令。

如果您确实需要远程 tty 并且确实需要将某些内容从本地 stdin 传递(键入)到远程命令,请传递-t,不要将 stdin 重定向到/dev/null,而是告诉远程 tty 关闭其回显。您可以通过添加stty -echo;$cmds_services.您不需要stty echo在最后打开 echo(使用 ),因为远程 tty 无论如何都会被破坏。请注意,中的任何命令$cmds_services都可能重新配置 tty;根据命令,您可能能够也可能无法阻止这种情况。

在一个非常苛刻的情况下,你可能会发现我的这个问题很有用:ssh具有单独的 stdin、stdout、stderr 和 tty。即使您不需要它,您也可以从它、我的回答以及其中的链接中获得一些见解。

相关内容