Bash脚本自动Telnet



我正在尝试自动telnet,使用这个命令可以很好地进行

echo -e "x1dclosex0d" |
  telnet abc.gc.ca 100 |
  grep Connected>/dev/null && printf "PASSEDn" || printf "FAILEDn"

但如果我把它放在剧本里,它就会挂起来,我不知道为什么。

#!/bin/bash
SERVERS=(
   "abc.gc.ca 100"
   "defg.gc.ca 101"
   "123.gc.ca 102"
   "xyz.gc.ca 103"
)
for host in ${SERVERS[@]}; do
  echo -e "x1dclosex0d" |
    telnet $host |
    grep Connected > /dev/null && printf "PASSEDn" || printf "FAILEDn"
done

最大的问题是数组取消引用:使用不带引号的${SERVERS[@]}将端口视为单独的主机名。

#!/bin/bash
servers=(
   abc.gc.ca:100
   defg.gc.ca:101
   123.gc.ca:102
   xyz.gc.ca:103
)
for host_port in "${servers[@]}"; do
  host=${host_port%:*}   # put everything before the last : into host
  port=${host_port##*:}  # put everything after the last : into port
  if printf 'x1dclosex0d' | telnet "$host" "$port" | grep -q Connected; then
    printf "PASSEDn"
  else
    printf "FAILEDn"
  fi
done

其他注意事项:

  • 所有caps变量名称都用于对shell或操作系统有意义的名称;其他名称是保留给应用程序使用的(比如您的脚本!(,所以您应该尽可能使用小写名称
  • CCD_ 2与CCD_ 3不相同。对于可靠的代码,当您想要if的行为时,请使用if,而不是短路三进制
  • 使用grep -q会导致grep不发出任何输出,因此不需要重定向该输出
  • echo -e是不可靠的:即使shell 100%肯定是bash,如果在运行时编译或配置shell以提供与XPG兼容的echo(可以通过环境变量进行配置(,echo -e也可能在输出中打印-e,而不是将其视为参数

尽管如此,如果要用于任何类型的真实世界用例,请考虑使用专用端口扫描工具。这样的工具(nmap&c(可以并行扫描大量主机,而不需要为每个主机运行一个子流程,更不用说这里使用的几个子流程了。

您可以尝试使用"/dev/tcp"文件。

SERVERS=(
   "abc.gc.ca/100"
   "defg.gc.ca/101"
   "123.gc.ca/102"
   "xyz.gc.ca/103"
)
for host in ${SERVERS[@]}; do
     timeout 3 bash -c "cat < /dev/null > /dev/tcp/$host" &&
         echo "PASSED" || echo "FAILED"
done

最新更新