Linux Script with Netcat Stops Working After X Hours

linux script with netcat stops working after x hours

If none of your commands including netcat reads input from stdin you can completely make it run independent of the terminal. Sometimes background process that are still dependent on the terminal pauses (S) when they try to read input from it on a background. Actually since you're running a daemon, you should make sure that none of your commands reads input from it (terminal).

#!/bin/bash

set +o monitor # Make sure job control is disabled.

(
: # Make sure the shell runs a subshell.
exec netcat -lk -p 12345 | while read line ## Use exec to overwrite the subshell.
do
match=$(echo $line | grep -c 'Keep-Alive')
if [ $match -eq 1 ]; then
[start a command]
fi
done
) <&- >&- 2>&- </dev/null &>/dev/null &

TASKPID=$!
sleep 1s ## Let the task initialize a bit before we disown it.
disown "$TASKPID"

And I think we could try the logging thing again:

set +o monitor

(
echo "[$(date "+%F %T")] Starting loop with PID $BASHPID."

for (( ;; ))
do
echo "[$(date "+%F %T")] Starting netcat."

netcat -vv -lk -p 12345 | while read line
do
match=$(echo "$line" | grep -c 'Keep-Alive')
if [ "$match" -eq 1 ]; then
[start a command]
fi
done

echo "[$(date "+%F %T")] Netcat has stopped or crashed."

sleep 4s
done
) <&- >&- 2>&- </dev/null >> "/var/log/something.log" 2>&1 &

TASKPID=$!
sleep 1s
disown "$TASKPID"

Issue with netcat timeout

You need to redirect to /dev/null, not pipe to it. Try the following:

nc -v -z -w 3 127.0.0.1 5050 &> /dev/null && echo "Online" || echo "Offline"

On my machine, port 5050 isn't open, and I get the following:

$ nc -v -z -w 3 localhost 5050 &> /dev/null && echo "Online" || echo "Offline"
Offline

How to wait for an open port with netcat?

You can't set netcat to wait until some port is open, so you have to add part for waiting before next check is made. Try this:

#!/bin/bash

echo "Waiting jenkins to launch on 8080..."

while ! nc -z localhost 8080; do
sleep 0.1 # wait for 1/10 of the second before check again
done

echo "Jenkins launched"

Netcat not Working

You are using NC wrong. nc -l $1 is listening for an external connection on that port. So you could run something like this:

host 1:

nc -l <port> | /home/matt/testprogram

host 2:

cat files | nc <host1> <port>

But the usage that you are doing makes no sense.

Make netcat discard all bytes after disconnect

well, as a workaround and if you can do that, instead of running ncat using the keep-open option, just respawn it between each connection in a while loop:

while true; do
#what you want to do with: ncat -l 3000
done

Then each time the process will respawn, it will discard all stdin, and then you start over with the next i/o for the following process.

Of course, if respawning your bash script isn't convenient, then it might mean you're not using the right tool for the job. (you might be able to workaround that playing with fifos or using temporary fds, but that'd be overengineering to avoid writing a script in a language that'd be a better fit for the job).


If you're not already doing it, did you try running your script from netcat and not the other way around?

ncat -kl 3000 -c ./script.sh

it will spawn the script for each connection, on which it will redirect stdin/stdout. Then when the client will disconnect, the script will get killed and should release your input fd.

Actually, if you're serving files as an http server, you might to look up:

ncat -lk 3000 --lua-exec httpd.lua

with the httpd.lua offered with the ncat distribution


If you want a simple run anywhere script to do something on your system, you can write a small python script.

It is installed per default on ubuntu (and many other systems), and you have a minimalist web server implementation provided, for example to serve files you just do:

python -m SimpleHTTPServer <port>
  • cf SimpleHTTPServer for py2
  • or http.server in py3

it is rather easy to customize, to fit your unique needs, and will offer you a full control over your sockets and file descriptors.

How to make script in bash aware that a server is still busy installing/configuring and wait for reboot?

As noted in the comments under the question:

  • The server may already be rebooted by the time ping -c5 -i30 $HWNODEIP finishes. The command sends 5 packets (-c flag), waiting 30 seconds between each packet (-i interval flag). So thats's 5*30 = 150 seconds, which is a bit more than 2 minutes. A server could reboot just fine within 2 minutes, especially if there's SSD in use. So try lowering the total time it would take this command to complete.

  • [ $? -eq 68 ] is probably unnecessary. $HWNODEIP is just ip address, and exit code 68 is for domain name not being resolved, which doesn't apply to IP addresses.

  • The if statement could be simplified to

    if ! ping -c5 -i30 "$HWNODEIP"  

These are minor suggestions,probably not bulletproof. As confirmed by OP in the comments, lowering interval helps. There's other small improvements that could be done (like quoting variables), but that's outside the scope of the question, so I'll leave it for now.



Related Topics



Leave a reply



Submit