28

I have numerous linux boxes with a very limited set of commands and disk space. But it has the telnet command on it.

I remotely connect to each of these probes (programmatically) and issue one line linux command through SSH.

I need to run a single command to connect to a specific machine, using telnet, and then disconnect right away.

I can do all that, but the disconnection right away part. Telnet opens some sort of a console, or terminal and I can't figure out a one-line command to run the telnet command and then disconnect right away.

If I do that, I can easily parse the textual output for error messages for not being able to connect to the machine on the specified port and that's exactly what I am looking for.

So how can I run a one-line command to connect to a machine using telnet and disconnect afterwards ?

Muhammad Gelbana
  • 1,583
  • 8
  • 19
  • 25

10 Answers10

46

You ought to be able to pipe the exit command into STDIN in telnet. Try:

echo 'exit' | telnet {site} {port}

and see if that works. (it seems to work on my web server, but YMMV).

Alexander Mills
  • 9,330
  • 19
  • 95
  • 180
Charles Newey
  • 626
  • 5
  • 5
14

The simplest and easiest method is given below.

 sleep <n> | telnet <server> <port>
  • n - The wait time in seconds before auto exit. It could be fractional like 0.5. Note that some required output may not be returned in the specified wait time. So we may need to increase accordingly.

  • server - The target server IP or hostname.

  • port - Target service port number.

You can also redirect the output to file like this:

sleep 1 | telnet <server> <port> > output.log
StackzOfZtuff
  • 297
  • 2
  • 9
Seff
  • 338
  • 3
  • 6
  • This works perfectly! While the output is indeed redirected, I noticed I still get the "Connection closed by foreign host." output in my console after the sleep rather than in the output.log file. Any way to prevent this? – dan Apr 03 '19 at 18:43
  • 1
    @dan That message is printed to stderr. You can redirect stderr to stdout (which is then redirected to output.log) by appending `2>&1` to the command. – jazzpi May 09 '20 at 16:23
  • Exactly what I needed for quick "waiting on Prometheus" - thank you! `while ! sleep 1 | telnet prometheus 9090 2> /dev/null; do echo "waiting on prometheus"; done` – rjchicago Feb 18 '22 at 23:40
10

In my case this works. (CentOS 7):

while read host port; do
r=$(bash -c 'exec 3<> /dev/tcp/'$host'/'$port';echo $?' 2>/dev/null)
if [ "$r" = "0" ]; then
     echo "$host $port is open"
else
     echo "$host $port is closed"
     exit 1 # To force fail result in ShellScript
fi
done
fpmurphy
  • 4,556
  • 3
  • 23
  • 26
Chuss
  • 111
  • 1
  • 2
  • 1
    Hey, this is great. I am a user on all the Linux systems at my job, but not the admin (and have no admin rights). I'm sick of asking them to install telnet all the time so I can test network connectivity (I'm a network engineer). This is an excellent workaround. I changed it a little to perform more like telnet. I provided my own answer here with the modifications. – theglossy1 Nov 22 '17 at 16:39
  • 1
    would someone please explain the shell/bash magic of "3<>" and the Linux magic of /dev/tcp/$host/$port? In other words, wot in heck does this do? – chrisinmtown Jan 29 '21 at 15:29
  • @chrisinmtown I was also wondering and did some digging and found [this](https://catonmat.net/bash-one-liners-explained-part-three) (scroll down to item 11) which explains that "exec 3<>file" opens 'file' for reading and writing as file descriptor number 3. So it would seem doing that with /dev/tcp/host/port opens a bidirectional TCP connection. – Jeff Feb 26 '22 at 22:59
9

Try

echo -e '\x1dclose\x0d' | telnet {HOSTNAME} {PORT}

Best part of above is you get exit status also. If telnet is success exit code will be 0 or else its 1

4

This is another version of the answer above that makes it act a little more like "normal" telnet syntax. If you like my answer, please give an upvote not to this, but to the original.

#!/bin/bash
if [ "$2" == "" ]; then
 echo "Syntax: $0 <host> <port>"
 exit;
fi

host=$1
port=$2

r=$(bash -c 'exec 3<> /dev/tcp/'$host'/'$port';echo $?' 2>/dev/null)
if [ "$r" = "0" ]; then
     echo "$host $port is open"
else
     echo "$host $port is closed"
     exit 1 # To force fail result in ShellScript
fi
theglossy1
  • 141
  • 3
3

I think better tool for sending commands directly and just getting output would be netcat. It just simple, but powerful tool for putting commands through ports. You could see usage example in this superuser question: https://superuser.com/questions/261900/how-can-i-pipe-commands-to-a-netcat-that-will-stay-alive - asker gives working example in which connection closes after few seconds.

And if you want just to test connectivity use this: http://terminalinflection.com/use-netcat-not-telnet-to-test-network-connectivity/

IBr
  • 1,745
  • 3
  • 17
  • 26
  • I'm trying to install netcat right now but I'm unable to do so. I downloaded a compiled powerpc version but glibc library was missing. I downloaded a compiled powerpc version but the device didn't have enough space to copy the library files ! Is it possible that the glibc library already exists but netcat can't find it ? – Muhammad Gelbana Aug 13 '13 at 12:13
  • Netcat is needed only on client side: on server (probe) can be the same plain old telnet. – IBr Aug 13 '13 at 13:23
  • Also Glibc should exist already, it is used on much stuff in usual system. – IBr Aug 13 '13 at 13:28
  • You could try to add to telnet scripts `&& exit` see if it disconnects (in ssh at least it is enough). – IBr Aug 13 '13 at 13:35
  • `&& exit` didn't work. If glibc should exist and I believe it does. Why would `nc.traditional` complain about it as if it's missing ? – Muhammad Gelbana Aug 13 '13 at 14:38
  • 1
    In case the link gets broken, the actual solution I ended up using was `nc -zv `. The man page explains the flags quite well. –  Oct 05 '17 at 21:09
  • the link is broken. Thanks for the guide user253179 – Rainb Dec 08 '20 at 14:34
  • I prefer `ncat`, which is part of the [nmap package](https://nmap.org/), and is an even more-flexible, modern version of netcat (`nc`) – theglossy1 Mar 02 '22 at 21:57
1

Here is solution I found on Internet:

( echo open 127.0.0.1 23
sleep 5
echo your_login
sleep 5
echo your_password
sleep 5
echo hostname
sleep 5
echo exit ) | telnet

It works for me on SunOS & HP-UX

Vladimir
  • 11
  • 1
1

Avoid netcat if you have custom routes, since it does not obey routing rules. Similar to how nslookup, dig & host ignore the /etc/hosts file (nslookup, dig, firefox ignoring /etc/hosts file entries).

i.e.: unlike applications and tools like telnet and /dev/tcp(Testing remote TCP port using telnet by running a one-line command) which follow the system's routing rules, nc uses the default gateway unless specifically told to use a source IP address with -s:

nc -w 3 -s 192.168.1.12 example.com 8080

I needed to test if an application could reach the resource, and if the routes were down, netcat reported that all was well since the source address had been specified in the test. I'm switching to using /dev/tcp.

Paulo Tomé
  • 3,754
  • 6
  • 26
  • 38
0

Use this method for minimal os :
example open port (only for test):

nc -l 1234    

now test socket :

echo > /dev/tcp/127.0.0.1/1234

now test result with echo $?
on success : std output result is 0 .
on failure : std output result is 1 .

mah454
  • 227
  • 2
  • 11
0

Based on previous answers with a slight modification...

while ! sleep 1 | telnet $HOSTNAME $PORT 2> /dev/null; do
  echo "waiting on $HOSTNAME:$PORT"
done

Explained...

sleep $N | telnet $HOSTNAME $PORT will exit 0 or 1 after N seconds. Set N as needed.

2> /dev/null sends any error message to /dev/null so we can log our own message.

The ! negates the exit above and the while loop will keep retrying every N seconds.

rjchicago
  • 101
  • 1