35

I found this line in a script. While I globally understand what it does--opening a bidirectional TCP connection--, I need some explanations on the syntax. Here's the line:

exec 5<>"/dev/tcp/${SERVER}/${PORT}"

And my questions:

  1. < and > are usually used to redirect IOs. What does it mean there? Is it usable in another context? How?
  2. Why does it work, while /dev/tcp doesn't exists?
  3. Why 5? Can it be another number? What are the values allowed?
  4. Why is exec necessary? (given nothing is actually executed)

Thanks.

gregseth
  • 12,952
  • 15
  • 63
  • 96

2 Answers2

22

< and > are usually used to redirect IOs. What does it mean there? Is it usable in another context? How?

It's the same - input and output is redirected to fd 5.

Why does it work, while /dev/tcp doesn't exists?

It's a special file: 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.

Why 5? Can it be another number? What are the values allowed?

Yes, it can be any value, but you need to ensure you don't use an fd already in use.

Why is exec necessary? (given nothing is actually executed)

exec means the redirection happens in the current shell, not within a subshell.

Karl Nicoll
  • 16,090
  • 3
  • 51
  • 65
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • 9
    There is an important caveat on this answer. Bash will only honor the "/dev/tcp" *if* support for it is enabled when bash is built. In particular, Red Hat builds bash with it enabled, while Debian does not (or at least they did not the last time I checked, which was ages ago). Do not expect this to work in all shells, nor in all bash. – William Pursell Oct 14 '11 at 12:09
6

I can only answer for the exec part:

exec without a command given may be used to change I/O redirections. <> in this case means open for read+write. 5 is the channel number (or file descriptor). This makes sense if other commands send their output / read their input from channel 5.

For "/dev/tcp/${SERVER}/${PORT}" I don't know if it's a feature of a specific Linux version or if it's a bash feature (I assume the latter).

-- EDIT: from the bash manual page: --

 Bash handles several filenames specially when they are  used
 in redirections, as described in the following table:

      /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.
ktf
  • 6,865
  • 1
  • 13
  • 6
  • 9
    These are extensions that have to be enabled when compiling bash (--enable-net-redirections). Not all Linux distros compile bash that way. Debian and Ubuntu for example don't enable it. – Nordic Mainframe Oct 14 '11 at 09:06
  • Good point! I really appreciate warnings about compatibility. – ktf Oct 14 '11 at 09:10