Check whether socket is closed in bash?
I've got a file descriptor that points to a socket (example code below).
exec 3<>/dev/tcp/localhost/9999
echo -e "Some Command\n" >&3
Sometimes that socket closes and needs to be re-opened (a restart of the server).
How can I test if the socket (fd #3 in this case) is writable?
The ec开发者_如何学Pythonho will always succeed, regardless of whether the socket has been closed already or not.
Solution is the feedback from the server.
When you send a request to the server, it needs to answer to it.
exec 3<>/dev/tcp/localhost/9999
echo -e "Some Command\n" >&3
sleep 5 # example max time given to server to respond
cat <&3 #receive an answer
check is correct, restart server otherwise
EDIT: using netcat to determine is the port is open
netcat -w 3 -z www.google.com 80
if[ $? -eq 0 ]
then
echo port open
else
echo port closed
fi
It has been awhile since op posted this so they might not see this but it might help someone else.
Anyway I was looking into this very issue and I found the following.
The open fd's (file descriptors) of a process are listed under /proc//fd.
exec 3<>/dev/tcp/localhost/9999
#check if still connected
if [ $(ls /proc/$$/fd | grep -w "3") == 3 ]; then
#send data
echo -e "Some Command\n" >&3
else
#perform reconnect
exec 3<>/dev/tcp/localhost/9999
fi
This wasn't tested but should be mostly ok. Might be some improvements as well. Also there is a window where the fd goes away between your check and the writing to fd. However that goes for all solutions so far.
I will add my own final solution (in terse psudo-code):
{ while true;
read file;
write to STDOUT } |
{ while true;
netcat command;
write STDIN to buffer when/if netcat exits;
loop to restart netcat & first process buffered data if exists; }
This separates the output of data (the reading of a file) and the processing of the data (sending it to a socket or buffering to a file when no socket is available). It uses the pipe to provide a temporary buffer when network issues occur.
The STDIN of the second code block buffers the output from the first codeblock. If netcat is unable to process data on stdin it will opt to write that out to a buffer file and try to re-start netcat. This way you don't have any period of time between checking that socket is open (something that's still tricky) and the actual write (which might still fail after checking that it's open).
You can use the netstat
command, grep
for the port/address you want, and then cut
just the state field. Please note that a socket may appear as "ESTABLISHED" for some time after the connection is lost, specially if you aren't sending any data to it.
Try writing to the fd:
if ! echo some text >&3; then echo The port is closed >&2 fi
Note that I'm not suggesting writing superfluous data to test if the file descriptor is still valid, but am suggesting that you simply try to write whatever data you want and then check that it worked. If the write failed, reopen the socket and write again.
精彩评论