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 toif ! 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
Dos2Unix: Binary Symbol Found, Skipping Binary File
Setting Environment Variable with Leading Digit in Bash
Dynamic Listening Ports Inside Docker Container
Programmatically Disable Hardware Prefetching on Amd Systems
Linux Kernel Changing Default CPU Scheduler
How Linux Scheduler Schedules Processes on Multi-Core Processors
Convert Charset from a Entire Project to Utf-8
Upgrading PHPmyadmin (And Other Packages) on Debian Squeeze
Golang Os/Exec, Realtime Memory Usage
How to Send a Mail with a Message in Unix Script
Linux: Move 1 Million Files into Prefix-Based Created Folders
Using Multiple Layers of Quotes in Bash