Bash Grep安静的SSH输出

时间:2016-02-19 03:19:34

标签: bash ssh

我正在尝试匹配SSH命令的输出但由于某种原因它无法正常工作。我正在使用authorized_keys来限制登录到一个命令 - 这是一个带参数的包装脚本。

这是我的代码:

for i in `seq 2 254`; do
  myoutput=$( ssh system@server01 ip 192.168.0.$i )
  echo "$myoutput"
  echo "$myoutput" | grep -q "not found"
  if [ $? -eq 0 ]; then
    echo 192.168.0.$i
    exit
  fi
done

这是脚本的输出:

192.168.0.2 not found in DB.  Try searching live (--forcelive)
192.168.0.3 not found in DB.  Try searching live (--forcelive)
192.168.0.4 not found in DB.  Try searching live (--forcelive)

这应该在第一个实例停止并且回显IP但是它继续,因为所有的greps都返回1而不是0.SSH命令本身(没有grep)每次都返回0。

为什么grep错误编码响应?有没有更好的方法来完成我想要做的事情?

1 个答案:

答案 0 :(得分:3)

您尝试搜索的内容几乎肯定是在stderr上,因此您的替换根本不会捕获它;因此,它通过调用ssh的相同命令发送到控制台,而不是放在myoutput变量中。

考虑使用重定向2>&1将stderr重定向到stdout,如下所示:

myoutput=$( ssh system@server01 "ip 192.168.0.$i" 2>&1 )

顺便说一下,如果您对调用ssh超过二百次的开销感到满意,我会认真考虑重写这样:

for ((i=2; i<254; i++)); do
  if ssh system@server01 "ip 192.168.0.$i" 2>&1 | grep -q 'not found'; then
    echo "192.168.0.$i"
    exit
  fi
done

为什么?

  • seq既没有内置到bash中,也没有内置到POSIX中。因此,它甚至不能保证存在,更不用说以任何特定方式表现。
  • ssh传递给远程系统的命令行构建为通过连接参数生成的单个字符串。因此,只传递一个字符串,其中包含您希望执行的确切代码,这样可以更加真实地表达内幕中发生的事情,并避免因忘记ssh 真正所执行的操作而产生的错误线。
  • 当您可以直接测试命令是否成功时,使用$?是不好的形式。

如果您不受authorized_keys的限制,顺便说一下,将脚本评估移至远程系统会更好,例如:

ip_found=$(ssh system@server01 bash -s <<'EOF'
  for ((i=2; i<254; i++)); do
    content=$(ip "192.168.0.$i" 2>&1)
    if [[ $content = *"not found"* ]]; then
      echo "192.168.0.$i"
      exit 0
    fi
  done
  exit 1
EOF
)

echo "Remote system found $ip_found"

...由于 受到如此限制,出于性能原因,您可以考虑使用SSH multiplexing在多个查询中重复使用单个经过身份验证的连接。