测试Shell脚本中telnet端口是否处于活动状态


11

我正在尝试创建一个脚本来测试是否可以通过telnet登录。我不想真正登录;因此,不需要期望。我只想查看是否能够获得登录提示。这是从Linux系统完成的,所以我一直在尝试使用nc

nc 192.168.10.5 23 -w 1 | grep -q login 
if [ $? -eq 1 ]
then
    echo "console is down"
fi

问题是这导致我的控制台锁定。似乎-w并没有真正取消连接。

我也尝试使用telnet,但无法从脚本内断开连接。试

\echo "\035" | telnet 192.168.10.5

在收到登录提示之前中断。


Answers:


14

Bash提供了您可能熟悉的伪设备/dev/null。但是,还有其他设备,例如/dev/tcp/dev/udp用于测试网络连接的设备,也可以从Bash脚本中使用。

摘自Bash的手册页

Bash专门用于重定向时会处理多个文件名,如下表所示:

          /dev/fd/fd
                 If fd is a valid integer, file descriptor fd is duplicated.
          /dev/stdin
                 File descriptor 0 is duplicated.
          /dev/stdout
                 File descriptor 1 is duplicated.
          /dev/stderr
                 File descriptor 2 is duplicated.
          /dev/tcp/host/port
                If  host  is a valid hostname or Internet address, and port 
                is an integer port number or service name, bash attempts to 
                open a TCP connection to the corresponding socket.
          /dev/udp/host/port
                If host is a valid hostname or Internet address, and port 
                is an integer port number or service name, bash attempts to 
                open a  UDP  connection to the corresponding socket.

这是我正在测试与我的域名“ skinner”中的主机的连接,并查看是否可以连接到其端口22。

注意:端口22用于SSH,用于telnet使用端口23。

$ echo > /dev/tcp/skinner/22 && echo "it's up" || echo "it's down"
it's up

太好了,让我们尝试一个非端口:

$ echo > /dev/tcp/skinner/223 && echo "it's up" || echo "it's down"
bash: connect: Connection refused
bash: /dev/tcp/skinner/223: Connection refused
it's down

那行得通,但是输出却很丑陋。不要担心。您可以echo > /dev/tcp/...在子shell中运行,并将所有输出重定向到/dev/null进行清理。您可以在Shell脚本中使用以下模式:

$ (echo > /dev/tcp/skinner/22) > /dev/null 2>&1 \
    && echo "it's up" || echo "it's down"
it's up

$ (echo > /dev/tcp/skinner/223) > /dev/null 2>&1 \
    && echo "it's up" || echo "it's down"
it's down

如果您特别想测试telnet,则默认情况下该端口运行在端口23上,因此slm使用22和223时,使用23。–
Warwick

@Warwick-谢谢,我在示例部分中添加了该注释。
slm

@sim感谢您的评论。我以前看过这个,但是我无法使其使用。我的问题是我需要能够grep或测试登录提示。在这种情况下,控制台将被锁定,并且没有登录提示。 # telnet 192.168.10.5 Trying 192.168.10.5... Connected to 192.168.10.5 (192.168.10.5). Escape character is '^]'. Connection closed by foreign host.
rleon 2014年

# cat < /dev/tcp/192.168.10.12/23 给我一个登录提示,但我无法中断它。
rleon 2014年

1
哇..那里的重定向分配。# cat afile ^] 运行后,它只是回声到afile。仍然在玩它,但我感觉我快要到了。
rleon 2014年

7

使用nc,您的方向正确,但是如果您真的想测试是否可以建立连接,请使用nc的-zswitch

#!/bin/bash
REMOTEHOST=10.11.12.13
REMOTEPORT=1234
TIMEOUT=1

if nc -w $TIMEOUT -z $REMOTEHOST $REMOTEPORT; then
    echo "I was able to connect to ${REMOTEHOST}:${REMOTEPORT}"
else
    echo "Connection to ${REMOTEHOST}:${REMOTEPORT} failed. Exit code from Netcat was ($?)."
fi

这不适用于所有系统,我的数控系统没有-z标志
Shapeshifter

有趣。这nc是哪个版本?
DopeGhoti

我使用的是CentOS 7,nc替换为没有该选项的nmap-ncat :(
Shapeshifter

如果我没记错的话,您在CentOS中想要的软件包就是nc
DopeGhoti

nc是centos 7中的nmap-ncat
Shapeshifter

2

我知道答案有点晚了,但是我一直在寻找方法,出于安全原因,不建议使用nc,因此可以帮助某人。

您最初的回声中缺少的是-e开关:

   -e     enable interpretation of backslash escapes
   -E     disable interpretation of backslash escapes (default)

和换行符+ quit命令在断开连接后退出telnet。因此:

echo -e '\035\nquit' | telnet 10.0.0.1 23 && echo "success" || echo "failed"

显然,如果您使用块样式的if语句并求值$ ?,同样的方法也会起作用。就像您最初所做的那样:

echo -e '\035\nquit' | telnet 10.0.0.1 23
if [ $? -eq 1 ]
then
  echo "Console is down."
fi

就我们而言,就nc而言,这取决于您所拥有的nc风格(gnu ncat与nmap-ncat)。Gnu将具有-z开关:

  -z                         Zero-I/O mode, report connection status only
nc -z 10.0.0.1 23
# (evaluate $? here)

而另一个则不会,您必须将一条空行传送到nc上以免被卡住:

echo | nc 10.0.0.1 23
# (evaluate $? here)

1

nc -z 192.168.10.5 23在命令提示符下运行 或创建bash脚本以运行此命令。

如果连接成功,它将返回以下语句。

连接到192.168.10.5 23端口[tcp / *]成功!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.