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

rle*_*eon 12 shell shell-script telnet netcat

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

nc 192.168.10.5 23 -w 1 | grep -q login 
if [ $? -eq 1 ]
then
    echo "console is down"
fi
Run Code Online (Sandbox Code Playgroud)

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

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

\echo "\035" | telnet 192.168.10.5
Run Code Online (Sandbox Code Playgroud)

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

slm*_*slm 15

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.
Run Code Online (Sandbox Code Playgroud)

例子

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

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

$ echo > /dev/tcp/skinner/22 && echo "it's up" || echo "it's down"
it's up
Run Code Online (Sandbox Code Playgroud)

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

$ 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
Run Code Online (Sandbox Code Playgroud)

嗯,这有效,但它的输出非常丑陋。不要担心。您可以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
Run Code Online (Sandbox Code Playgroud)


Dop*_*oti 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
Run Code Online (Sandbox Code Playgroud)


小智 5

我知道答案有点晚了,但我一直在寻找如何做到这一点,出于安全原因,使用 nc 不是一个选择,所以这里是它是否可以帮助某人。

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

   -e     enable interpretation of backslash escapes
   -E     disable interpretation of backslash escapes (default)
Run Code Online (Sandbox Code Playgroud)

以及换行符 + quit 命令以在断开连接后退出 telnet。像这样:

echo -e '\035\nquit' | telnet 10.0.0.1 23 && echo "success" || echo "failed"
Run Code Online (Sandbox Code Playgroud)

显然,如果您使用块样式 if 语句并评估 $? ,同样会起作用。正如您最初所做的那样:

echo -e '\035\nquit' | telnet 10.0.0.1 23
if [ $? -eq 1 ]
then
  echo "Console is down."
fi
Run Code Online (Sandbox Code Playgroud)

当我们讨论这个问题时,就 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)
Run Code Online (Sandbox Code Playgroud)

而另一个不会,你必须将一个空行连接到你的 nc 才不会被卡住:

echo | nc 10.0.0.1 23
# (evaluate $? here)
Run Code Online (Sandbox Code Playgroud)