Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Netcat TCP Programming with Bash

I'm attempting to do some basic TCP client communication by using strictly bash scripting. I have netcat at my disposal and so I've written this loop so far:

nc 10.0.0.104 4646 | while read line
do
   if [ "$line" == '{"cmd": 1}' ]
   then
      # Send text back to the TCP server
      echo '{"error": 0}'
   fi
done

The script can successfully connect to the server application I'm using but I'm having difficulties figuring out how to send text back to the netcat process.

like image 397
Ringo Avatar asked Dec 21 '14 15:12

Ringo


1 Answers

With Bash≥4 you can use coproc:

#!/bin/bash

coproc nc { nc 10.0.0.104 4646; }

while [[ $nc_PID ]] && IFS= read -r -u${nc[0]} line; do
    case $line in
        ('{"cmd": 1}')
            printf >&${nc[1]} '%s\n' '{"error": 0}'
            ;;
        (*)
            printf >&2 '%s\n' "Received line:" "$line"
            ;;
    esac
done

This avoids using temporary fifos. Without coproc, I guess the only option left is to use fifos explicitly. Here's an example:

#!/bin/bash

mkfifo fifo_in

while IFS= read -r line; do
    case $line in
        ('{"cmd": 1}')
            printf '%s\n' '{"error": 0}'
            ;;
        (*)
            printf >&2 '%s\n' "Received line:" "$line"
            ;;
    esac
done < <(nc 10.0.0.104 4646 < fifo_in) > fifo_in

For this, you'll have to manage the creation and deletion of the fifo: you'll need to create a temporary directory with mktemp, in there create the fifo, then trap your script so that on exit everything is cleaned.


/dev/tcp

If your Bash has been compiled with net redirections support, you can get rid of nc and of the fifos and coprocesses altogether:

#!/bin/bash

# open TCP connection, available on file descriptor 3
exec 3<> /dev/tcp/10.0.0.104/4646 || exit

while IFS= read -r -u3 line; do
    case $line in
        ('{"cmd": 1}')
            printf >&3 '%s\n' '{"error": 0}'
            ;;
        (*)
            printf >&2 '%s\n' "Received line:" "$line"
            ;;
    esac
done

This is very likely the sweetest solution!

like image 63
gniourf_gniourf Avatar answered Nov 18 '22 20:11

gniourf_gniourf