Redirect process stdin and stdout to netcat
Asked Answered
R

4

11

I have an embedded linux application with a simple interactive command line interface.

I'd like to access the command line from telnet (or network, in general).

However, the process should be started when the board turns on, and in a unique instance. So, the following netcat command is not an option:

nc -l -p 4000 -e myapp

I can do

nc -l -p 4000 | myapp

to send remote commands to myapp, but this way I can't see myapp output.

Is there any way to redirect both stdin and stdout to netcat?

Thanks.

Riband answered 30/3, 2016 at 14:6 Comment(0)
R
9

I found that by using bash v. >= 4.0 I can use coproc:

#!/bin/bash

coproc myapp
nc -kl -p 4000 <&"${COPROC[0]}" >&"${COPROC[1]}"

EDIT

I eventually incorporated a telnet server in my cli library. You can find the result on GitHub: https://github.com/daniele77/cli

Riband answered 31/3, 2016 at 7:57 Comment(1)
Nice idea. <&"${COPROC[0]}" >&"${COPROC[1]}" part looks unnecessary since bash does that for you. It should be just 2>&1 to redirect stderr into stdout.Evesham
E
12

Is there a way to redirect both stdin and stdout to netcat

There is socat, which is a more advanced netcat. You can redirect both stdin and stdout with it. E.g.:

socat TCP4-LISTEN:5556,reuseaddr,fork EXEC:"cat - /etc/redhat-release"

In the above cat reads stdin and /etc/redhat-release and outputs them into stdout.

And then try using that:

$ echo "hello" | nc 127.0.0.1 5556
hello
Fedora release 22 (Twenty Two)

$ echo "hello 2" | nc 127.0.0.1 5556
hello 2
Fedora release 22 (Twenty Two)
Evesham answered 30/3, 2016 at 14:54 Comment(6)
With the command you suggest, my application is started only when a client connects (like nc -e does). I want to be able to launch my process without any connection.Riband
@DanielePallastrelli Then your application must be a TCP server. You cannot redirect (at least easily) open file descriptors of a running process.Evesham
Well... when I launch my application, I can redirect straightway stdin/out to socat, which in turn, acts as a server. The connection can arrive later on.Riband
It's not necessary redirect open file descriptors of a running process: the file descriptors could be redirected (to e.g. socat) from the very beginning. Then the connections can arrive later on.Riband
far better solution than other. Worked for me. 10x :]Sihunn
Cool, I can get the client udp port with server-side command: socat UDP4-LISTEN:5353,reuseaddr,fork EXEC:"bash -c (ss -tuwanp|grep 5353|grep ESTAB|awk '{print \$6}')" and client-side command: nc -p 15443 -u server_ip 5353Bandylegged
R
9

I found that by using bash v. >= 4.0 I can use coproc:

#!/bin/bash

coproc myapp
nc -kl -p 4000 <&"${COPROC[0]}" >&"${COPROC[1]}"

EDIT

I eventually incorporated a telnet server in my cli library. You can find the result on GitHub: https://github.com/daniele77/cli

Riband answered 31/3, 2016 at 7:57 Comment(1)
Nice idea. <&"${COPROC[0]}" >&"${COPROC[1]}" part looks unnecessary since bash does that for you. It should be just 2>&1 to redirect stderr into stdout.Evesham
B
3

You can use ncat (from nmap package: apt install nmap) for that as well as follow:

ncat -lnvp 443 -e myapp

don't forget to fflush(stdout); after each printf("%s",str); in your app

Bullroarer answered 3/5, 2018 at 21:24 Comment(1)
The verbose option --verbose or -v is what captures stderr in the command above (-lnvp). nmap.org/ncat/guide/ncat-output.htmlSwirsky
P
3

Just found this trick reading man nc. One could redirect both stdin and stdout to the same app using named pipes.

Example:

# create named pipe
rm -f /tmp/f; mkfifo /tmp/f

# launch interactive 'sh' session redirected to/from listening nc
cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

From another terminal:

nc localhost 1234 # connect to the listening nc
$
$
$ ls -lah
total 16K
drwxrwxr-x  43 ky   ky    12K Jun 17 01:31 .
drwxr-xr-x 123 ky   ky    12K Jun 17 01:35 ..

Oh my, it really works. And if you don't mind keeping all the sent data in a file then this approach could also be using a file instead of a named pipe. Like this:

# create an empty file
echo -n '' > /tmp/session

# launch interactive 'sh' session redirected to/from listening nc
tail -f /tmp/session | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/session
Pinchbeck answered 16/6, 2022 at 22:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.