Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

breaking from infinite loop

Tags:

bash

loops

cat

I'm running this query in bash:

mkfifo resp
while true; do 
    sudo nc -l -p 80 < resp |
    (cat & echo -e "HTTP/1.1 200 OK\r\n\r\nhello :)" > resp) ||
    break; 
done

However when I Ctrl+C, nothing happens, and the terminal locks up.

Why? What am I doing wrong?

like image 436
Matt Joiner Avatar asked Nov 04 '22 02:11

Matt Joiner


1 Answers

I cannot recreate this in my environment (RHEL)--CTRL-C works fine for me on this. After your terminal locks up, I would open a new one and use strace -p to see at what's happening.

I think that there are some issues with the command setup in general, though.

First is that you're backgrounding cat in the subshell. Doing this makes the stdin of the cat command /dev/null, rather than the output of nc that you're piping into the subshell. You can see the difference by comparing the output of this:

#! /bin/bash
# doesn't print yay
while true; do
    echo yay |
    (cat & false) ||
    break
done

with this:

#! /bin/bash
# does print yay
while true; do
    echo yay |
    (cat ; false) ||
    break
done

Also, I'm not clear on if this is intentional or not, but the break condition of your loop in general is based on the exit code of the subshell, which in turn will be the exit code of echo, which will always succeed, so the loop in general is infinite. You can see this by replacing false in one of the above with an echo:

#! /bin/bash
while true; do
    echo yay |
    (cat & echo test) ||
    break
done

And, as @chepner pointed out, your usage of nc in general is also incorrect. Per its manpage:

-l      Used to specify that nc should listen for an incoming connection rather than initiate a connection to a remote host.  It is an error to use this option in conjunction with the -p, -s, or -z options.

This is actually causing your nc command to do nothing at all (no output, just sit there). You can see this by running mkfifo resp ; nc -l -p 80 < resp in one shell as root and then running echo -e "HTTP/1.1 200 OK\r\n\r\nhello :)" > resp in another shell as root.

Hope this helps.

like image 154
Christopher Neylan Avatar answered Nov 11 '22 21:11

Christopher Neylan