4

At the beginning, I created a small server with netcat and it worked well:

#!/bin/bash

PORT="1234";

startServer(){
    fifo="fifo/$1";
    mkfifo "$fifo";

    connected="0";

    netcat -q 0 -l -p "$PORT" < "$fifo" | while read -r line; do
        if [ "$connected" == "0" ];then
            #listen for a new connection
            startServer $(($1+1))&
            connected="1";
        fi

        #server logic goes here

    done > "$fifo";

    rm "$fifo";
}

mkdir fifo;
startServer 0;

It uses fifos to redirect the main loop output back to netcat.

Every call to startServer increases the value of $1 and creates a fifo file fifo/$1.

But I want to use bash's automatic file descriptor creation to get rid of fifo files and the parameter of startServer.

After multiple attempts, here is my current attempt at modifying the startServer function. I can receive lines from the client but unfortunately it does not receive anything back. I am confused about what is wrong.

startServer(){
    connected="0";

    #create file descriptor and read output from main loop
    exec {fd}> >( netcat -q 0 -l -p "$PORT" | while read -r line; do
        if [ "$connected" == "0" ];then
            #listen for a new connection
            startServer&
            connected="1";
        fi

        #server logic goes here

    done ) >&$fd;

    #close file descriptor
    exec {fd}<&-;
    exec {fd}>&-;
}

Also, I cannot use netcat's "-e" option since it is not available in the netcat-openbsd package.

  • Allocating a file descriptor doesn't allocate a buffer for it to refer to. – chepner Nov 18 '17 at 18:42
  • @chepner The redirection >( ... ) or <( ... ) should allocate a buffer. – nd97 Nov 18 '17 at 22:28
  • 1
    That's not a redirection; it's a process substitution, which is effectively just special syntax for a fifo. – chepner Nov 18 '17 at 22:40
3

You cannot set and use fd in the same command; you are effectively doing exec {fd}> ... >&$fd. What can work is creating the bash fifo/pipe first, using some simple command like :. Eg:

startServer(){
    local connected=0 fd
    exec {fd}<> <(:)
    nc -q 0 -l -p "$PORT" <&$fd | 
    while read -r line
    do  if [ "$connected" == "0" ]
        then startServer $(($1+1)) &
             connected="1"
        fi
        echo server $1 logic goes here
    done >&$fd
    exec {fd}<&-
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.