Netcat, often invoked with the nc
command, can be thought of as a little bit like a network version of the cat utility. Its basic purpose is to open TCP/IP connections and pass stuff along them. It can:
- Listen for a network connection on a given port, and echo anything it receives to stdout.
- Connect to a given host and port, and send anything it receives on stdin.
...and much more, but these features are all we need to wire up commands in the shell on a desktop computer to a running instance of raspipe.py on a Raspberry Pi elsewhere on the network.
Let's start with a simple example of connecting two netcat
instances and sending some text between them. Here are two terminals running on my laptop:
In the first terminal, I tell netcat
to listen on port 1234 by saying:
netcat -l 1234
In the second terminal, I tell netcat to connect to localhost (which is, as you might suspect, a special hostname that should resolve to the machine we're on right now), port 1234:
netcat localhost 1234
Now, in either window, I can type some text and hit enter, and it'll show up in the other window. Once I'm done typing, I can hit Ctrl-D, a conventional shortcut for end-of-file, and the connection will close.
You can try this on your Raspberry Pi. If you're running the desktop, just start a couple instances of LXTerm. If you're on the console, try pressing Alt and the right arrow key until you see a new login prompt. You can use Alt+arrows to navigate back and forth between these virtual consoles.
Now take a look at listener_pitft.sh
:
nano listener_pitft.sh
#!/usr/bin/env bash echo "Listening on port 5280" netcat -l 5280 -k | ./raspipe_pitft.sh
This script just invokes netcat, listening on port 5280, with -k
, which says to listen for a new connection once the current one closes. (Normally, the program will exit as soon as one connection finishes.)
It then pipes the output of this netcat instance to raspipe_pitft.sh
.
In order to test this, you'll need an installed PiTFT display and a working network connection on your Pi. You can check your current network address with ifconfig
, like so:
pi@pi2 ~/Adafruit-RasPipe $ ifconfig eth0 Link encap:Ethernet HWaddr b8:27:eb:73:15:91 inet addr:192.168.1.4 Bcast:192.168.1.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:148486 errors:0 dropped:0 overruns:0 frame:0 TX packets:18536 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:27686012 (26.4 MiB) TX bytes:3096689 (2.9 MiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:2821 errors:0 dropped:0 overruns:0 frame:0 TX packets:2821 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:381840 (372.8 KiB) TX bytes:381840 (372.8 KiB)
I looked for the inet addr:192.168.1.4
entry in the eth0
section. Yours might be under wlan0
, if you're using a wireless adapter instead of an ethernet cable. Once you know your address, start the listener like so:
./listener_pitft.sh
Now, from a terminal elsewhere on your network, try sending some traffic to your Pi:
echo "hello\nworld\ni\nam\na\pi" | netcat 192.168.1.4 5280
If netcat
isn't available, try typing nc
instead. You should see something like the following:
You can experiment with other input - just about anything should work.
This all works fine if your desktop/laptop is a Linux or OS X machine, but what about Windows users?
Not to worry: The authors of the Nmap network scanning tool provide Ncat, "much-improved reimplementation of the venerable Netcat", for Windows. To run, just visit the Ncat page and find the zip file containing the standalone executable. I opened this and dragged a copy of ncat
to my desktop:
...then just ran cmd.exe
, followed by:
cd Desktop ncat 192.168.1.4 5280
Ok, so my original goal for this project was to make a pipeline viewer that would let me drop a command into the middle of other shell one-liners and have output displayed on the Raspberry Pi.
Using a feature of Bash called process substitution, this turns out to be pretty easy.
nano raspipe_tee
#!/usr/bin/env bash RASPIPE_ADDY=192.168.1.4 cat /dev/stdin | tee >(netcat $RASPIPE_ADDY 5280)
We use cat /dev/stdin
to spit out the contents of standard input for this script, and pipe it to tee
, which serves to redirect input to a file while also echoing it back to standard output.
In tee >(netcat $RASPIPE_ADDY 5280)
, the >(...)
section creates a special temporary file of sorts, which tee
writes to as if it were any other file. The difference is that when it writes to this file, it's actually writing to the stdin of netcat
. Crazy, right?
So now we can say something like:
fortune | ./raspipe_tee
...and have the same output echoed on the PiTFT.
What's more, we can issue a command that uses the output of raspipe_tee
and still see the output of fortune
echoed on the PiTFT.
fortune | ./raspipe_tee | wc -w
In order to test this, you can either ssh to your Pi and run raspipe_tee
there, or copy it to another machine and replace the value of RASPIPE_ADDY
with the address of your Pi.
Text editor powered by tinymce.