This article is part of the article series "Unix Utilities You Should Know About."
<- previous article next article ->
Unix Utilities

This is the second post in the article series about Unix utilities that you should know about. In this post I will introduce you to the netcat tool or simply nc.

Netcat is often referred to as a "Swiss Army knife" utility, and for a good reason. Just like the multi-function usefulness of the venerable Swiss Army pocket knife, netcat's functionality is as helpful. Some of its features include port scanning, transferring files, port listening and it can be used a backdoor.

In 2006 netcat was ranked #4 in "Top 100 Network Security Tools" survey, so it's definitely a tool to know.

See the first post on pipe viewer for the introduction to this article series. If you feel like you are interested in this stuff, I suggest that you subscribe to my rss feed to receive my future posts automatically.

How to use nc?

Let's start with a few very simple examples and build up on those.

If you remember, I said that netcat was a Swiss Army knife. What would a Swiss Army knife be if it also wasn't a regular knife, right? That's why netcat can be used as a replacement of telnet:

$ nc 80

It's actually much more handy than the regular telnet because you can terminate the connection at any time with ctrl+c, and it handles binary data as regular data (no escape codes, nothing).

You may add "-v" parameter for more verboseness, and two -v's (-vv) to get statistics of how many bytes were transmitted during the connection.

Netcat can also be used as a server itself. If you start it as following, it will listen on port 12345 (on all interfaces):

$ nc -l -p 12345

If you now connect to port 12345 on that host, everything you type will be sent to the other party, which leads us to using netcat as a chat server. Start the server on one computer:

# On a computer A with IP
$ nc -l -p 12345

And connect to it from another:

# On computer B
$ nc 12345

Now both parties can chat!

Talking of which, the chat can be turned to make two processes talk to each other, thus making nc do I/O over network! For example, you can send the whole directory from one computer to another by piping tar to nc on the first computer, and redirecting output to another tar process on the second.

Suppose you want to send files in /data from computer A with IP to computer B (with any IP). It's as simple as this:

# On computer A with IP
$ tar -cf - /data | nc -l -p 6666

# On computer B
$ nc 6666 | tar -xf -

Don't forget to combine the pipeline with pipe viewer from previous article in this series to get statistics on how fast the transfer is going!

A single file can be sent even easier:

# On computer A with IP
$ cat file | nc -l -p 6666

# On computer B
$ nc 6666 > file

You may even copy and restore the whole disk with nc:

# On computer A with IP
$ cat /dev/hdb | nc -l -p 6666

# On computer B
$ nc 6666 > /dev/hdb

Note: It turns out that "-l" can't be used together with "-p" on a Mac! The solution is to replace "-l -p 6666" with just "-l 6666". Like this:

$ nc -l 6666

# nc now listens on port 6666 on a Mac computer

An uncommon use of netcat is port scanning. Netcat is not the best tool for this job, but it does it ok (the best tool is nmap):

$ nc -v -n -z -w 1 1-1000 
(UNKNOWN) [] 445 (microsoft-ds) open
(UNKNOWN) [] 139 (netbios-ssn) open
(UNKNOWN) [] 111 (sunrpc) open
(UNKNOWN) [] 80 (www) open
(UNKNOWN) [] 25 (smtp) : Connection timed out
(UNKNOWN) [] 22 (ssh) open

The "-n" parameter here prevents DNS lookup, "-z" makes nc not to receive any data from the server, and "-w 1" makes the connection timeout after 1 second of inactivity.

Another uncommon behavior is using netcat as a proxy. Both ports and hosts can be redirected. Look at this example:

$ nc -l -p 12345 | nc 80

This starts a nc server on port 12345 and all the connections get redirected to If you now connect to that computer on port 12345 and do a request, you will find that no data gets sent back. That's correct, because we did not set up a bidirectional pipe. If you add another pipe, you can get the data back on another port:

$ nc -l -p 12345 | nc 80 | nc -l -p 12346

After you have sent the request on port 12345, connect on port 12346 to get the data.

Probably the most powerful netcat's feature is making any process a server:

$ nc -l -p 12345 -e /bin/bash

The "-e" option spawns the executable with it's input and output redirected via network socket. If you now connect to the host on port 12345, you may use bash:

$ nc localhost 12345
ls -las
total 4288
   4 drwxr-xr-x 15 pkrumins users    4096 2009-02-17 07:47 .
   4 drwxr-xr-x  4 pkrumins users    4096 2009-01-18 21:22 ..
   8 -rw-------  1 pkrumins users    8192 2009-02-16 19:30 .bash_history
   4 -rw-r--r--  1 pkrumins users     220 2009-01-18 21:04 .bash_logout

The consequences are that nc is a popular hacker tool as it is so easy to create a backdoor on any computer. On a Linux computer you may spawn /bin/bash and on a Windows computer cmd.exe to have total control over it.

That's everything I can think of. Do you know any other netcat uses that I did not include?

How to install nc?

If you're on Debian or Debian based system such as Ubuntu do the following:

$ sudo aptitude install netcat

If you're on Fedora or Fedora based system such as CentOS do:

$ sudo yum install netcat

If you're on Slackware, FreeBSD, NetBSD, Solaris or Mac, download the source code of nc and just:

$ tar -zxf nc-version.tar.gz
$ cd nc-version
$ ./configure && sudo make install

Another way to do it on Mac, if you have MacPorts is:

$ sudo port install netcat

On Slackware you can actually install it as a package from n/ package directory:

$ sudo installpkg nc-1.10-i386-1.tgz

If you're on Windows, download the Windoze port of it from securityfocus.

The manual of the utility can be found here man nc.

Have fun netcatting, and until next time!

This article is part of the article series "Unix Utilities You Should Know About."
<- previous article next article ->


Mark Permalink
February 17, 2009, 18:48
# On computer A with IP
$ cat file | nc -l -p 6666

And of course, if you've been following along for a week or two, you know that this (BING!) is a Useless Use of Cat!

Remember, nearly all cases where you have:

cat file | some_command and its args ...

you can rewrite it as:

some_command and its args ... < file

and in some cases, but not this one, you can move the filename to the arglist as in:

some_command and its args ... file

Just another Useless Use of the Internet...

August 05, 2013, 04:26

I see your point and for everyone that doesn't see this tip, it's a great one.

I personally just prefer to use cat. It keeps the data flow a nice left-to-right, which makes it easier to read.

Data flow <------
cmd < file | cmd

Data flow -------->
cat file | cmd | cmd

Steve Massey Permalink
January 30, 2017, 00:18

you can do
<file cmd | cmd

which is the same as
cmd <file | cmd

but with the right flow

August 05, 2013, 21:47

That's fine until you get the redirect the wrong way around and blow away a file...

TheDude Permalink
February 17, 2009, 18:48

Apparently on some distros, its an error to specify -p with -l. nc -l 6666 works.

TheDude Permalink
February 17, 2009, 18:52

Except in this case.

nc -l -p 6666 file

doesn't work.

You also wouldn't be able to use pv to view the progress of the stream.

yitzle Permalink
February 17, 2009, 18:53

And for the commands that do not take a filename as an argument, you can do:

$ command < file


$ nc -l -p 6666 < file

Regarding tar, by default it uses STDIN, so -f - is the default behavior. Therefore, these two commands do the same thing:

$ tar -c /data
$ tar -cf - /data

(Ditto with the tar -x)

All in all, great article! Thanks.

February 17, 2009, 18:56

Mark, your comment is something that people call sometimes call "useless use" of "useless use". There is nothing wrong with uselessly using cat. It makes it more readable sometimes.

February 17, 2009, 19:10

cat file | nc -l -p 6666

Bzzzzt. Useless use of cat.

nc -l -p 6666 < file

Mark Permalink
February 17, 2009, 19:12

Yes, I know there is no practical reason to avoid using cat. But readers of a blog discussing command-line utilities should know about the <file command syntax.

I won't try editing my comment for html compliance, rather I would direct you to

February 17, 2009, 20:05

Used netcat as part of a bigger pipe to "mirror traffic" over from a simple box that only had tcpdump to a fancier box where it can be analyzed with ethereal/tethereal:

Command 1:
nc -l -p 6666 | tethereal -V -i -

Command 2:
ssh -R 6666: remotemachine "tcpdump -l -p -s 0 port not 22 -w - | nc localhost 6666"

james Permalink
February 17, 2009, 20:40

this netcat guide is based on a version of netcat that isn't universal. There is the original, the gnu version and a number of rewrites with different options

Tim Permalink
February 17, 2009, 21:45

So if I create a named pipe with mkfifo or mknod -p, can I create a general port-swapping proxy with it?

Roman Permalink
February 17, 2009, 21:48

> That’s why netcat can be used as a replacement of telnet

In order to use netcat as telnet, you need to use the -t option. It does nothing more than rejecting all options, though, and it doesn't prevent weird characters showing on your screen.

It's also kind of amusing that the link to SecurityFocus doesn't actually lead there.

@james: What do you mean by universal? I'm not seeing any options that aren't supported by the original netcat.

@TheDude: I wonder which distros and which version of netcat don't support -p.

Galactic Dominator Permalink
February 17, 2009, 21:59

I take it you're unfamiliar with the FreeBSD ports tree.

cd /usr/ports/net/netcat
make install clean

or install the bin

pkg_add -r netcat

February 17, 2009, 22:14

A more powerfull utility than netcat is socat.

Very easy to translate any typ of traffic to another.

Tarrant Permalink
February 17, 2009, 22:15

@Roman: The original version (BSD's) I know for sure can't have the -p following a -l.

I think this is one of the points that james was trying to make about the gnu version being different. Other than that I'm sure there are differences but I haven't gone and
compared the man pages to each other.

@Galatic Dominator: I'm not sure why but my FreeBSD box had it automatically is that just a matter of which package set I grabbed in the begging?

Jon Craton Permalink
February 17, 2009, 23:06

You have linked to a copy of netcat on my server in your link to netcat for windows. That's totally fine with me, but just to be clear, I am not affiliated with security focus in any way. They simply link to my server as well.

Pat Permalink
February 18, 2009, 05:11

Check out the instructions at this webpage under the title Piping Audio Around the House. You can use the sox utility in combination with netcat to pipe audio over LAN.

To install sox:
sudo apt-get install sox libsox-fmt-oss libsox-fmt-mp3

February 18, 2009, 11:40

Netcat is now part of the base system in FreeBSD.

There is no need to compile it from source (as you suggest) or install it via the ports.

February 18, 2009, 12:57

I couldn't get the chat thing to work. How about extending this tutorial with some trouble shooting tips?

leke@leke-desktop:~$ telnet 80
Connected to
Escape character is '^]'.
Connection closed by foreign host.
leke@leke-desktop:~$ nc 80
leke@leke-desktop:~$ nc -v 80
DNS fwd/rev mismatch: !=
DNS fwd/rev mismatch: !=
DNS fwd/rev mismatch: !=
DNS fwd/rev mismatch: != [] 80 (www) open

This looks pretty off too.

mourad Permalink
February 19, 2009, 12:01

Great post!
I was wondering is there any available free unix shells out there ? Say that I could connect to via netcat with total annonyma !?

Craig Hughes Permalink
February 19, 2009, 19:08

Netcat is a great, simple tool. But sometimes it's not quite enough for what you need to do, eg when you need to control some of the socket options on the connection you're creating (eg if you're talking to a serial device and need to set line speed or something). For Netcat on 'roids, check out socat. Socat has more options than the Chicago Board of Trade, but once you figure it out a little, it can be very helpful. 9 times out of 10, netcat does what you want, but for that extra 1/10 where you think to yourself "argh I wish netcat could just do XYZ too..." you'll want to know about socat.

Joeri Permalink
February 20, 2009, 17:40

Macs have their own standard /usr/bin/nc which is , as you have correctly noticed, doesn't accept -p, but the one you install with ports behaves the way you describe.

shah Permalink
March 03, 2009, 00:42

Great utility.

I want to know whether "netcat" can be used to print unix files to printer connected to windows pc?
OR any other technique?

Need your help!.

Thanks, shah

March 29, 2009, 12:10

there is re-writtend version if netcat called ncat
can be found on nmaps top sectools section

June 16, 2009, 00:35

Useful article
thanks a lot.

Xezlec Permalink
July 23, 2009, 20:48

There certainly can be good reasons not to uselessly use cat, and getting into the habit of doing so can be a bad thing, especially if your code is likely to be used as a bible by relatively uninformed users (as yours is).

I work at a place where relatively uninformed users routinely set up large, super-high-bandwidth pipes on compute clusters using cat, in which case cat may waste significant CPU (what's the block size that it's reading from disk, I wonder?). Furthermore, cat gives you a one-way stream as output, so downstream apps don't have the ability to get information about the original file (such as size) or to seek back and forth. In general, streams < files.

The end result is that my carefully written C code with all its carefully optimized seeking behavior ends up wasting hours burning through hundreds of terabytes of unneeded data just because it doesn't have a seekable input descriptor, and then the users complain that their code is slow and after debugging I find that they're doing this junk and remind them (again!) not to do this, and then two months later they copy some code off of yet another blog like this and yet again don't notice that the cat is not necessary and yet again complain that their code is slow...... etc.

So yeah, I guess I feel like if I wrote a blog claiming to be anything resembling a how-to, I'd try to write pretty good code, just to be nice and not give people bad ideas. But it's your blog of course, and your call.

Debty Permalink
July 26, 2009, 21:58

Ahaan... I will follow.

argv Permalink
July 30, 2009, 03:02

I don't understand why people like to use cat when it's not necessary. Maybe they don't understand what cat is doing. I must agree with Xezlec. A waste of resources.

I don't understand why for many simple jobs people use perl when they could use sed. In the event it's faster, it's likely this is only because the entire file is read into memory. Is that always necesary?

Maybe users just need a better understanding of what these tools do: not just the end result, but the process.

I'd like to see PK play around with DJ Bernstein's tools, e.g. tcpclient and the rest of that suite.

Also, there netpipes, socketpipe, etc.

It's much easier to use these tools if you understand how they work. Merely knowing what they do is, in my opinion, not enough. There is a lengthy, popular, and informal tutorial on UNIX socket programming if you search around. Might be helpful to get a grasp of the basics before one starts using socat.

July 31, 2009, 04:01

argv, thanks for your cool comments. I'll look into the djb's tools and see if I can write an article on them. I am well familiar with socket programming, shouldn't be a problem for me to understand them.

Xezlec and argv, I am just used to 'cat foo | prog' instead of 'prog < foo' or 'prog foo'. I am well aware of useless use of cat there. Also I like that after 'cat foo' I can forget about 'foo' altogether and only think of how 'prog' will operate on the input flow. Where as if I type 'prog < foo' or 'prog foo', I have to think about both 'foo' and how will 'prog' operate on 'foo' at the same time. It's like thinking from functional programmers point of view.

I'm neutral on the issue of useless use of cat. One day I may use it, the other I may not. And I will not get into live-or-die argument about it. It's like arguing is tabs betters than spaces. Or do you write 'char *foo' or 'char* foo' or 'char * foo'. All of them are acceptable, so just use any of them and create something cool, but be consistent.

argv Permalink
July 31, 2009, 22:12

Also check out "dog". It is another alternative to nc.

If you can filter through the complaints about *people* (personal squabbles between computer scientists, complaints about "arrogance", etc.), djb's site has some very clear thinking about some *things* that really need to "reconsidered". One of those things is DNS. Despite his many admirable tools, in my opinion the best page he has on this subject is one where he describes "vapourware". I hope you can read that one.

As to the useless cat issue, you won't see this habit on the grymoire site or the sites it references. When one is being paid to optimise and gain efficiency to reduce costs, eliminating these bad habits, e.g. senseless cat usage, is a part of the job. Your article on shell line editing and history features was a good example of optimising and gaining efficiency.

argv Permalink
August 05, 2009, 03:11

One more that I forgot, along the lines of nc, tcpclient, etc.:

zsh's ztcp module

On my OS the zsh executable is actually smaller than the bash executable, which piques my curiousity. The size differences between the two packages might be largely attributable to all the zsh modules and other zsh 'extras'.

I've tried bash's tcp functionality a few times, but never got hooked. Perhaps because it did not feel robust, or perhaps because there are so many other more 'reliable' tools. But maybe ztcp is worth a look.

August 05, 2009, 05:11

argv, I have played with bash's tcp functionality a little, it seemed ok for very simple tasks. But I agree that it's not very reliable.

I hadn't heard of zsh's ztcp and will definitely investigate it.

argv Permalink
August 10, 2009, 13:25

That page on djb's site I was hoping you'd look at (a different topic, but an important one)...

I realised the page is quite difficult to find intentionally on the djb site.

Anyway, if you do follow up on the subject of the Berkeley sockets, he also lists [some of] the other apps that tcpclient "competes" with. Socket, Netpipes, etc.

# On computer A with IP$ cat file | nc -l -p 6666# On computer B$ nc 6666 > file
I thought this was a great example of the power of nc. I could give two flying flux capacitors whether cat was a useless use. Seriously girls, don't chop your hand off when you break a fingernail. This piece is not about squeezing every cpu cycle out of your machine but demonstrating nc. And separating 'cat' with a pipe actually does make more clear exactly what is going on.
# On computer A with IP
$ cat file | nc -l -p 6666
# On computer B
$ nc 6666 > file

I thought this was a great example of the power of nc. I could give two flying flux capacitors whether cat was a useless use. Seriously girls, don't chop your hand off when you break a fingernail. This piece is not about squeezing every cpu cycle out of your machine but demonstrating nc. And separating 'cat' with a pipe actually does make more clear exactly what is going on.

February 28, 2010, 23:18

Great utility.

I want to know whether “netcat” can be used to print unix files to printer connected to windows pc?
OR any other technique?

Need your help!.

Thanks, shah

argv Permalink
March 26, 2010, 11:22

There are so many choices and it takes time to experiment with them all, but I've started to become preferential to Richard Stevens' sock program.

It might be interesting to do a comparison of all these network read/write programs in terms of flexibility and performance.

April 04, 2010, 23:58

thanks for this info

langagemachine Permalink
November 09, 2010, 16:48

The -e switch does not seem to work here (Ubuntu 10.4) ?

nc -l -p 12345 -e /bin/bash
nc: invalid option -- 'e'
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-P proxy_username] [-p source_port]
[-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol]
[-x proxy_address[:port]] [hostname] [port[s]]

alex Permalink
March 16, 2011, 14:32

It is a variant of NC. The '-e' can be considered a security issue so some vendors do not include it in their distro.

Jonatan Jönsson Permalink
May 11, 2016, 08:52

You can use nc -l 1337 | /bin/bash instead!

December 29, 2012, 15:07

You say:

> That's correct, because we did not set up a bidirectional pipe. If you add another pipe, you can get the data back on another port:
> $ nc -l -p 12345 | nc 80 | nc -l -p 12346

But that's not the whole truth. Actually, you *can* do bidirectional proxy with a little trick involving named pipes:

$ mkfifo ~/loop.pipe && cat ~/loop.pipe | nc -l -p 12345 | nc 80 > ~/loop.pipe

This way everything you send to port 12345 is redirected to, and everything sent back from will be redirected back to local port 12345.

August 05, 2013, 04:21

I have "Type()" at the command line for cat. It can type BMP files to the command-line. The command-line can show graphics.

August 05, 2013, 04:24

TempleOS has no networking. Linux was inspired by the usage model of a mainframe. TempleOS was inspired by the usage model of a C64/AppleII -- what you did with it.

null Permalink
August 05, 2013, 19:32

i find it rather interesting reading teh comments about the -p flag not being correct in some circumstances, had anyone properly researched this they would realize that they are probably using the netcat-openbsd release as opposed to netcat-traditional

null Permalink
August 05, 2013, 19:34

in reference to my previous comment the issue with the -e flag also pertains to distros being shipped with netcat-openbsd and not netcat-traditional

Jonatan Jönsson Permalink
May 11, 2016, 08:51

On the default nc on Mac "-e /bin/bash" does not work. You can use nc -l 1337 | /bin/bash instead!

Leave a new comment

(why do I need your e-mail?)

(Your twitter handle, if you have one.)

Type the word "computer_132": (just to make sure you're a human)

Please preview the comment before submitting to make sure it's OK.