- How to open a TCP/UDP socket in a bash shell
- Open or Close a TCP/UDP Socket in Bash Shell
- Read from or Write to a TCP/UDP Socket in Bash Shell
- TCP/UDP Socket Examples in Bash Shell
- 1. Fetch a remote web page and print its content.
- 2. Display a remote SSH server version.
- 3. Display the current time from nist.gov.
- 4. Check the Internet connectivity.
- 5. Perform TCP port scanning against a remote host.
- Final Notes
- If you find this tutorial helpful, I recommend you check out the series of bash shell scripting tutorials provided by Xmodulo.
- Support Xmodulo
- Linux: is there a read or recv from socket with timeout?
- 5 Answers 5
How to open a TCP/UDP socket in a bash shell
Suppose you want to open a TCP/UDP socket on a Linux server for various reasons. For example, you want to check if a specific address/port is reachable. Or you want to fetch a remote web page or invoke a restful API for testing. Or you want to connect to a remote IRC server, etc. However, what if the Linux server you are on is very restrictive? On that server, none of standard tools such as netcat , curl or wget may be available, and you are pretty much left with the bash shell only.
In fact, one of built-in features of bash shell is to open TCP/UDP sockets via /dev/tcp (and /dev/udp ) device file. In the rest of this tutorial, let’s find out how to open a TCP/UDP socket, and read to and write from the socket in bash shell.
Open or Close a TCP/UDP Socket in Bash Shell
In a nutshell, you can open a TCP/UDP socket using the following syntax in bash shell.
The file descriptor is a unique non-negative integer associated with each socket. File descriptors 0, 1 and 2 are reserved for stdin , stdout and stderr , respectively. Thus you must specify 3 or higher (whichever is unused) as a file descriptor.
The protocol field can be either tcp or udp. The host and port fields are self-explanatory.
For example, to open a bi-directional TCP socket for xmodulo.com with HTTP port and file descriptor 3 :
Once opened, a read/write socket can be closed using the following syntax. The first command close an input connection, while the latter closes an output connection.
Read from or Write to a TCP/UDP Socket in Bash Shell
Once a socket is opened, you can write a message to or read a message from the socket.
To write a message stored in $MESSSAGE to a socket:
$ echo -ne $MESSAGE >&3 $ printf $MESSAGE >&3
To read a message from a socket and store it in $MESSAGE :
$ read -r -u -n $MESSAGE /dev/null)
TCP/UDP Socket Examples in Bash Shell
Here I present several shell script examples that open and use a TCP socket.
1. Fetch a remote web page and print its content.
#!/bin/bash exec 3<>/dev/tcp/xmodulo.com/80 echo -e "GET / HTTP/1.1rnhost: xmodulo.comrnConnection: closernrn" >&3 cat2. Display a remote SSH server version.
In fact, the above script can be shortened to the following one-liner:
3. Display the current time from nist.gov.
4. Check the Internet connectivity.
#!/bin/bash HOST=www.mit.edu PORT=80 (echo >/dev/tcp/$/$) &>/dev/null if [ $? -eq 0 ]; then echo "Connection successful" else echo "Connection unsuccessful" fi5. Perform TCP port scanning against a remote host.
#!/bin/bash host=$1 port_first=1 port_last=65535 for ((port=$port_first; port/dev/tcp/$host/$port) >/dev/null 2>&1 && echo "$port open" doneFinal Notes
Opening a socket in bash requires that the bash shell have net-redirections enabled (i.e., compiled with --enable-net-redirections ). Old distributions may have this feature disabled for bash , in which case you will encounter the following error.
/dev/tcp/xmodulo.com/80: No such file or directoryBesides bash , socket support is known to be available in other shells such as ksh or zsh .
If you find this tutorial helpful, I recommend you check out the series of bash shell scripting tutorials provided by Xmodulo.
Support Xmodulo
This website is made possible by minimal ads and your gracious donation via PayPal or credit card
Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.
Linux: is there a read or recv from socket with timeout?
How can I try to read data from socket with timeout? I know, select, pselect, poll, has a timeout field, but using of them disables "tcp fast-path" in tcp reno stack. The only idea I have is to use recv(fd, . MSG_DONTWAIT) in a loop
5 Answers 5
You can use the setsockopt function to set a timeout on receive operations:
SO_RCVTIMEO
Sets the timeout value that specifies the maximum amount of time an input function waits until it completes. It accepts a timeval structure with the number of seconds and microseconds specifying the limit on how long to wait for an input operation to complete. If a receive operation has blocked for this much time without receiving additional data, it shall return with a partial count or errno set to [EAGAIN] or [EWOULDBLOCK] if no data is received. The default for this option is zero, which indicates that a receive operation shall not time out. This option takes a timeval structure. Note that not all implementations allow this option to be set.
// LINUX struct timeval tv; tv.tv_sec = timeout_in_seconds; tv.tv_usec = 0; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv); // WINDOWS DWORD timeout = timeout_in_seconds * 1000; setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout); // MAC OS X (identical to Linux) struct timeval tv; tv.tv_sec = timeout_in_seconds; tv.tv_usec = 0; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
Reportedly on Windows this should be done before calling bind . I have verified by experiment that it can be done either before or after bind on Linux and OS X.