Is there any way, using basic Unix commands, to find the next unused port number, starting at port 4444 and going upwards?开发者_运维问答 I'm ssh'ed (via openssh) into a Windows XP machine, running Cygwin tools and using a bash shell.
Thanks, - Dave
Try this:
for port in $(seq 4444 65000); do echo -ne "\035" | telnet 127.0.0.1 $port > /dev/null 2>&1; [ $? -eq 1 ] && echo "unused $port" && break; done
where
seq 4444 65000 - port range for check
echo -ne "\035" - escape character to force close telnet session (^])
if telnet finishes with exit code 1 that mean connection refused:
$ telnet 127.0.0.1 4444
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
$ echo $?
1
else we decided that connection was success with exit code 0.
EDIT:
Special for cygwin: You need to install additional package inetutils
that is contain telnet port and use the script as follows:
for port in $(seq 4444 65000); do echo -ne "\035" | /usr/bin/telnet 127.0.0.1 $port > /dev/null 2>&1; [ $? -eq 1 ] && echo "unused $port" && break; done
Same as above, but written as a function
function get_unused_port() {
for port in $(seq 4444 65000);
do
echo -ne "\035" | telnet 127.0.0.1 $port > /dev/null 2>&1;
[ $? -eq 1 ] && echo "$port" && break;
done
}
FREE_PORT="$(get_unused_port)"
echo $FREE_PORT
The following function doesn't depend on telnet/netcat as it generates a random port in the local port range and compares it with a list of ports currently used by running applications.
Should work on any *nix that supports proc filesystem. Generates a free ephemeral port to be used by your application.
function EPHEMERAL_PORT(){
while true; do
LISTENING_PORTS=$(cat /proc/net/tcp | awk 'NR >1 {print $2}' | awk -F':' '{print $2}');
LISTENING_PORTS=$(for PORT in ${LISTENING_PORTS}; do echo $((16#${PORT})); done|sort -g);
# echo "32768 60999" | read LPORT UPORT
read LPORT UPORT < /proc/sys/net/ipv4/ip_local_port_range
MPORT=$[$LPORT + ($RANDOM % $UPORT)];
if (echo "${LISTENING_PORTS[@]}" | grep -xqv $MPORT); then
echo $MPORT;
break;
fi
done
}
Apparently TCP connections can be used as file descriptors on linux. The following function uses that technique and should be faster than the previous one.
function EPHYMERAL_PORT(){
LPORT=32768;
UPORT=60999;
while true; do
MPORT=$[$LPORT + ($RANDOM % $UPORT)];
(echo "" >/dev/tcp/127.0.0.1/${MPORT}) >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo $MPORT;
return 0;
fi
done
}
This is a cross platform function that uses osquery to get a list of listening ports. Should also work on Windows.
function EPHYMERAL_PORT(){
while true; do
echo "32768 60999" | read LPORT UPORT
MPORT=$[$LPORT + ($RANDOM % $UPORT)];
LISTENING_PORTS=$(osqueryi --header=false --list "select port from listening_ports order by port");
if (echo "${LISTENING_PORTS[@]}" | grep -xqv $MPORT); then
echo $MPORT;
break;
fi
done
}
Usage instructions. Bind the output to a variable and use in scripts. Tested on Ubuntu 16.04
root@ubuntu:~> EPHYMERAL_PORT
59453
root@ubuntu:~> PORT=$(EPHYMERAL_PORT)
精彩评论