[SOLVED] nc (netcat): script works when sourced but not if executed via its path
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
nc (netcat): script works when sourced but not if executed via its path
Hello everybody!
Right now I am completely puzzled because of the behaviour of nc in this script:
(nc version: OpenBSD netcat (Debian patchlevel 1.89-3ubuntu2) )
cat script_test:
Code:
#!/bin/bash
(nc -kl 192.168.2.100 2222) >> /tmp/myfifo & # /tmp/myfifo is a named pipe
( while true; do read in; if [ "$in" == "" ]; then continue; fi; echo "$in"; done ) < /tmp/myfifo &
If I source the script from PC1 by typing
Code:
. script_test
I can connect from PC2 with
Code:
nc 192.168.2.100 2222
and everything I am typing in the terminal of PC2 is displayed in the terminal of PC1. It is possible to terminate and reconnect to the server at will.
I am very well aware of the fact, that I could simply run
Code:
nc -lk 192.168.2.100 2222
to achieve the same effect, but I decided to reinvent the wheel to isolate the problem from a much longer and more complex script.
If I run the script directly with
Code:
./script_test
I can not connect to PC1. I wiresharked the connection. The first time I try to connect I see a three way handshake followed immediately by a tcp teardown initiated from PC1. Total length of the stream is 0 bytes. Every connection attempt after the first one is answered with TCP RESET.
The difference I noticed between sourcing and running the script is that sourcing will result in two new jobs while running the script results in a new bash instance. This made me think of interactive vs. non-interactive shells. Some research let me find this in ABS-Guide, but the "-i" option did no good to my script. I tried to run nc with "-q -1" and with "-d", but this did only break the sourcing too.
So right now I do not have any idea
1st: what causes nc to terminate immediately in the script
2nd: why it is not starting another listening attempt although -k is set
You are running 2 commands in the background and nothing else so your main script is exiting immediately and closing its subprocesses. You can fix this by doing one of:
Using the wait command at the end of the main script.
Using disown on each background command so that they are not terminated by the ending of their parent.
Thank you very much for your reply. I apologise for answering so very late, but I was ill for a few days and was unable to work on my project.
I am afraid, but the proposals you made did not solve my problem. The issue you pointed out is indeed likely to cause trouble, so I will keep it in mind when I continue to experiment. Due to your hints I got some hands on experience with wait and disown, so on the bright side I got some learning experience out of this.
I will paste the test scripts I wrote, so you can have a look at it and see if I did break anything. All scripts did establish a TCP connection just to tear it down at once the first time and responded to connection attempts ever after with a RESET.
no_bg_script:
Code:
#!/bin/bash
(nc -kl 192.168.2.100 2222) >> /tmp/myfifo & # /tmp/myfifo is a named pipe
( while true; do read in; if [ "$in" == "" ]; then continue; fi; echo "$in"; done ) < /tmp/myfifo
switched_no_bg_script:
Code:
#!/bin/bash
( while true; do read in; if [ "$in" == "" ]; then continue; fi; echo "$in"; done ) < /tmp/myfifo &
(nc -kl 192.168.2.100 2222) >> /tmp/myfifo & # /tmp/myfifo is a named pipe
disown_script:
Code:
#!/bin/bash
(nc -kl 192.168.2.100 2222) >> /tmp/myfifo & disown # /tmp/myfifo is a named pipe
( while true; do read in; if [ "$in" == "" ]; then continue; fi; echo "$in"; done ) < /tmp/myfifo & disown
wait_script:
Code:
#!/bin/bash
(nc -kl 192.168.2.100 2222) >> /tmp/myfifo & # /tmp/myfifo is a named pipe
( while true; do read in; if [ "$in" == "" ]; then continue; fi; echo "$in"; done ) < /tmp/myfifo &
# according to bash manpage wait without arguments waits for all child processes
wait
# the next line was never reached in my tests
echo "The End"
I think I was on the wrong track with previous answer. I tried running some of your scripts (with the IP changed to 127.0.0.1) and I'm getting completely bizarre behaviour: The first connection attempt with nc exits immediately, the second time it connects but then every other line is echoed locally instead of on the other end!? And several times I got nc or the script going into a loop taking 100% cpu while trying to quit.
I would like to know which distro you used to break this even further. My Linux Mint (still release number 10 on my testing-box) had no such problems. In fact, I started of testing with two console windows against localhost too, but switched to a network approach to be able to sniff the traffic with wireshark conveniently.
Well, I am still stuck. I think that maybe something regarding stdin is handled differently in the two situations, so at least the closing of the connection could be explained. But I still have no clue what that difference might be. I am thinking right now about reimplementing nc, to be able to test what the program is "seeing" in each situation. This might take a while, and I do not think this can be done soon, but I am still tempted to figure out what is going on there.
I would like to know which distro you used to break this even further. My Linux Mint (still release number 10 on my testing-box) had no such problems.
Debian testing "Wheezy", with netcat-openbsd package version 1.105-7 (the executable doesn't appear to have a version switch).
Quote:
I am thinking right now about reimplementing nc, to be able to test what the program is "seeing" in each situation. This might take a while, and I do not think this can be done soon, but I am still tempted to figure out what is going on there.
Yeah, I was thinking of trying that as well.
Last edited by ntubski; 10-31-2012 at 02:46 AM.
Reason: missing [quote] tag
Got the source code of bsd netcat. About 1000 lines for the main file does not sound too bad. As far as I have seen, it should not be to hard to add some print lines for debugging as the file is well structured and commented. Sadly I do not have that much time at present, so this might take some time.
On the bright side: As nc is reporting errors on stderr, it could be worth a try to have a closer look at what is logged. I will see into that when i find the time.
<edit>
This is the version I was looking into:
/* $OpenBSD: netcat.c,v 1.109 2012/07/07 15:33:02 haesbaert Exp $ */
</edit>
Last edited by Heraton; 10-31-2012 at 03:07 AM.
Reason: Current Version
I took the reimplement nc route and found that backgrounded processes don't get to keep stdin which causes nc to exit. Adding the -d option fixes this. On the other hand, you said -d didn't work for you, so maybe you have some other issues??
Code:
#!/bin/bash
# This worked for me
(nc -dkl 127.0.0.1 2222) >> /tmp/myfifo & # /tmp/myfifo is a named pipe
nc_pid=$!
( while true; do read in; if [ "$in" == "" ]; then continue; fi; echo "$in"; done) < /tmp/myfifo &
cat_fifo_pid=$!
trap 'kill $nc_pid $cat_fifo_pid' SIGTERM SIGINT
wait
Also I found the following has the exact same behaviour (including the symptoms described in your first post if -d is removed):
Code:
#!/bin/bash
nc -d -l 127.0.0.1 2222 &
wait
My nc implementation (doesn't support -d, -l implies -k):
Thank you very much for your assistance and all the effort you put into my problem. The script you posted worked for me too.
Interesting was, that the behavior of Linux Mint 10 and 12 is different. When I ran my old script on release 12, suddenly every connection attempt was behaving like the first one: three way handshake and tcp teardown.
I was able to get the old script working with the "-d" switch too, which was very surprising for me. The wait-issue seemingly was not the cause of the trouble. I do not have any explanation for the "-d" switch working right now except that I must have screwed up somehow the first time. I guess I will blame the flu
Although I do still not understand fully what happened here, I will let it be. It suffices to know that stdin is lost whenever a process is backgrounded and netcat needs to be run with "-d" in this case.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.