找到你要的答案

Q:Test from shell script if remote TCP port is open Using bash and timeout: Using nc: Remarks:

Q:如果远程TCP端口是打开shell脚本测试 使用bash和超时: 采用数控: 评论:

I'm looking for a quick and simple method for properly testing if a given TCP port is open on a remote server, from inside a Shell script.

I've managed to do it with the telnet command, and it works fine when the port is opened, but it doesn't seem to timeout when it's not and just hangs there...

Here's a sample:

l_TELNET=`echo "quit" | telnet $SERVER $PORT | grep "Escape character is"`
if [ "$?" -ne 0 ]; then
  echo "Connection to $SERVER on port $PORT failed"
  exit 1
else
  echo "Connection to $SERVER on port $PORT succeeded"
  exit 0
fi

I either need a better way, or a way to force telnet to timeout if it doesn't connect in under 8 seconds for example, and return something I can catch in Shell (return code, or string in stdout).

I know of the Perl method, which uses the IO::Socket::INET module and wrote a successful script that tests a port, but would rather like to avoid using Perl if possible.

Note: This is what my server is running (where I need to run this from)

SunOS 5.10 Generic_139556-08 i86pc i386 i86pc

我寻找适当的测试的快速和简单的方法,如果一个给定的TCP端口是开放的远程服务器上,从一个shell脚本。

我设法用telnet命令做它,和它正常工作时,端口是打开的,但似乎没有超时,当它不只是挂在那儿…

这是样品:

l_TELNET=`echo "quit" | telnet $SERVER $PORT | grep "Escape character is"`
if [ "$?" -ne 0 ]; then
  echo "Connection to $SERVER on port $PORT failed"
  exit 1
else
  echo "Connection to $SERVER on port $PORT succeeded"
  exit 0
fi

我需要一个更好的办法,或者一种用力Telnet连接超时如果不在8秒为例,和回报的东西我可以赶在壳(返回码,或字符串输出)。

我知道Perl的方法,它使用IO::::inet模块插座和写了一个成功的脚本测试端口,但宁愿要尽可能避免使用Perl。

注:这是我的服务器正在运行(我需要运行此从)

SunOS 5.10 generic_139556-08 i86pc i386 i86pc

answer1: 回答1:

As pointed by B. Rhodes, nc will do the job. A more compact way to use it:

nc -z <host> <port>

That way nc will only check if the port is open, exiting with 0 on success, 1 on failure.

For a quick interactive check (with a 5 seconds timeout):

nc -z -v -w5 <host> <port>

正如B. Rhodes指出,NC将做这项工作。更紧凑的方式使用它:

nc -z <host> <port>

那样NC只检查端口是否打开,成功退出0,失败1。

快速交互检查(5秒超时):

nc -z -v -w5 <host> <port>
answer2: 回答2:

It's easy enough to do with the -z and -w TIMEOUT options to nc, but not all systems have nc installed. If you have a recent enough version of bash, this will work:

# Connection successful:
$ timeout 1 bash -c 'cat < /dev/null > /dev/tcp/google.com/80'
$ echo $?
0

# Connection failure prior to the timeout
$ timeout 1 bash -c 'cat < /dev/null > /dev/tcp/sfsfdfdff.com/80'
bash: sfsfdfdff.com: Name or service not known
bash: /dev/tcp/sfsfdfdff.com/80: Invalid argument
$ echo $?
1

# Connection not established by the timeout
$ timeout 1 bash -c 'cat < /dev/null > /dev/tcp/google.com/81'
$ echo $?
124

What's happening here is that timeout will run the subcommand and kill it if it doesn't exit within the specified timeout (1 second in the above example). In this case bash is the subcommand and uses its special /dev/tcp handling to try and open a connection to the server and port specified. If bash can open the connection within the timeout, cat will just close it immediately (since it's reading from /dev/null) and exit with a status code of 0 which will propagate through bash and then timeout. If bash gets a connection failure prior to the specified timeout, then bash will exit with an exit code of 1 which timeout will also return. And if bash isn't able to establish a connection and the specified timeout expires, then timeout will kill bash and exit with a status of 124.

这是很容易做的Z和W超时选项NC,但不是所有的系统都安装了NC。如果你最近一个bash足够的版本,这将工作:

# Connection successful:
$ timeout 1 bash -c 'cat < /dev/null > /dev/tcp/google.com/80'
$ echo $?
0

# Connection failure prior to the timeout
$ timeout 1 bash -c 'cat < /dev/null > /dev/tcp/sfsfdfdff.com/80'
bash: sfsfdfdff.com: Name or service not known
bash: /dev/tcp/sfsfdfdff.com/80: Invalid argument
$ echo $?
1

# Connection not established by the timeout
$ timeout 1 bash -c 'cat < /dev/null > /dev/tcp/google.com/81'
$ echo $?
124

这里发生的事情是,超时将运行命令并杀死它如果它不退出在指定的超时(在上面的例子中是1秒)。在这种情况下,Bash是命令,利用其特殊的/ dev / TCP处理试图打开一个连接到指定的服务器和端口。如果bash可以打开在超时的连接,猫会立即关闭(因为它的阅读从/dev/null)和一个0将通过bash然后超时传播状态代码退出。如果bash会连接失败指定的超时之前,然后攻击将退出,退出代码1,超时也会恢复。如果bash不能建立连接和指定的超时时间到期,然后超时将状态124杀bash和退出。

answer3: 回答3:

TOC:

  • Using bash and timeout
    • Command
    • Examples
  • Using nc
    • Command
    • RHEL 6 (nc-1.84)
      • Installation
      • Examples
    • RHEL 7 (nmap-ncat-6.40)
      • Installation
      • Examples
  • Remarks

Using bash and timeout:

Note that timeout should be present with RHEL 6+, or is alternatively found in GNU coreutils 8.22. On MacOS, install it using brew install coreutils and use it as gtimeout.

Command:

$ timeout $TIMEOUT_SECONDS bash -c "</dev/tcp/${HOST}/${PORT}"; echo $?

If parametrizing the host and port, be sure to specify them as ${HOST} and ${PORT} as is above. Do not specify them merely as $HOST and $PORT, i.e. without the braces; it won't work in this case.

Example:

Success:

$ timeout 2 bash -c "</dev/tcp/canyouseeme.org/80"; echo $?
0

Failure:

$ timeout 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
124

If you must preserve the exit status of bash,

$ timeout --preserve-status 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
143

Using nc:

Note that a backward incompatible version of nc gets installed on RHEL 7.

Command:

Note that the command below is unique in that it is identical for both RHEL 6 and 7. It's just the installation and output that are different.

$ nc -w $TIMEOUT_SECONDS -v $HOST $PORT </dev/null; echo $?

RHEL 6 (nc-1.84):

Installation:

$ sudo yum install nc

Examples:

Success:
$ nc -w 2 -v canyouseeme.org 80 </dev/null; echo $?
Connection to canyouseeme.org 80 port [tcp/http] succeeded!
0
Failure:
$ nc -w 2 -v canyouseeme.org 81 </dev/null; echo $?
nc: connect to canyouseeme.org port 81 (tcp) timed out: Operation now in progress
1

If the hostname maps to multiple IPs, the above failing command will cycle through many or all of them. For example:

$ nc -w 2 -v microsoft.com 81 </dev/null; echo $?
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
1

RHEL 7 (nmap-ncat-6.40):

Installation:

$ sudo yum install nmap-ncat

Examples:

Success:
$ nc -w 2 -v canyouseeme.org 80 </dev/null; echo $?
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connected to 52.202.215.126:80.
Ncat: 0 bytes sent, 0 bytes received in 0.22 seconds.
0
Failure:
$ nc -w 2 -v canyouseeme.org 81 </dev/null; echo $?
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connection timed out.
1

If the hostname maps to multiple IPs, the above failing command will cycle through many or all of them. For example:

$ nc -w 2 -v microsoft.com 81 </dev/null; echo $?
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connection to 104.43.195.251 failed: Connection timed out.
Ncat: Trying next address...
Ncat: Connection to 23.100.122.175 failed: Connection timed out.
Ncat: Trying next address...
Ncat: Connection to 23.96.52.53 failed: Connection timed out.
Ncat: Trying next address...
Ncat: Connection to 191.239.213.197 failed: Connection timed out.
Ncat: Trying next address...
Ncat: Connection timed out.
1

Remarks:

The -v (--verbose) argument and the echo $? command are of course for illustration only.

TOC:

  • Using bash and timeout
    • Command
    • Examples
  • Using nc
    • Command
    • RHEL 6 (nc-1.84)
      • Installation
      • Examples
    • RHEL 7 (nmap-ncat-6.40)
      • Installation
      • Examples
  • Remarks

Using bash and timeout:

注意,超时应与RHEL 6 +,或是另外发现在GNU Coreutils 8.22。在MacOS,安装使用BREW的安装和使用它作为gtimeout Coreutils。

Command:

$ timeout $TIMEOUT_SECONDS bash -c "</dev/tcp/${HOST}/${PORT}"; echo $?

如果参数化的主机和端口,可以指定主机}和{美元} {港是美元以上。不要仅将它们指定为$主机和$端口,即没有括号,它不会在这种情况下工作。

Example:

Success:

$ timeout 2 bash -c "</dev/tcp/canyouseeme.org/80"; echo $?
0

Failure:

$ timeout 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
124

如果你要保存bash的退出状态,

$ timeout --preserve-status 2 bash -c "</dev/tcp/canyouseeme.org/81"; echo $?
143

Using nc:

值得注意的是,一个落后的不兼容版本的NC被安装在RHEL 7。

Command:

注意,下面的命令,为RHEL 6和7是相同的都是独一无二的。这只是安装和输出是不同的。

$ nc -w $TIMEOUT_SECONDS -v $HOST $PORT </dev/null; echo $?

RHEL 6 (nc-1.84):

Installation:

$ sudo yum install nc

Examples:

Success:
$ nc -w 2 -v canyouseeme.org 80 </dev/null; echo $?
Connection to canyouseeme.org 80 port [tcp/http] succeeded!
0
Failure:
$ nc -w 2 -v canyouseeme.org 81 </dev/null; echo $?
nc: connect to canyouseeme.org port 81 (tcp) timed out: Operation now in progress
1

如果主机名映射到多个IP地址,上面没有命令将循环通过许多或所有的。例如:

$ nc -w 2 -v microsoft.com 81 </dev/null; echo $?
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
nc: connect to microsoft.com port 81 (tcp) timed out: Operation now in progress
1

RHEL 7 (nmap-ncat-6.40):

Installation:

$ sudo yum install nmap-ncat

Examples:

Success:
$ nc -w 2 -v canyouseeme.org 80 </dev/null; echo $?
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connected to 52.202.215.126:80.
Ncat: 0 bytes sent, 0 bytes received in 0.22 seconds.
0
Failure:
$ nc -w 2 -v canyouseeme.org 81 </dev/null; echo $?
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connection timed out.
1

如果主机名映射到多个IP地址,上面没有命令将循环通过许多或所有的。例如:

$ nc -w 2 -v microsoft.com 81 </dev/null; echo $?
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connection to 104.43.195.251 failed: Connection timed out.
Ncat: Trying next address...
Ncat: Connection to 23.100.122.175 failed: Connection timed out.
Ncat: Trying next address...
Ncat: Connection to 23.96.52.53 failed: Connection timed out.
Ncat: Trying next address...
Ncat: Connection to 191.239.213.197 failed: Connection timed out.
Ncat: Trying next address...
Ncat: Connection timed out.
1

评论:

- V(详细)的论点和echo $?命令仅用于说明。

answer4: 回答4:

With netcat you can check whether a port is open like this:

nc my.host.com 80 < /dev/null

The return value of nc will be success if the TCP port was opened, and failure (typically the return code 1) if it could not make the TCP connection.

你可以检查与netcat的端口是否打开这样:

nc my.host.com 80 < /dev/null

数控机床返回值如果TCP端口是打开成功,失败(通常返回代码1)如果不能使TCP连接。

shell  tcp  port  solaris  telnet