Why do you want to do that? It's inherently racy (and inefficient - and least add -n to netstat and a more selective grep). The way to do it is to try and open a port in whatever mode you need, and try another one if it's not available.
–
MatNov 16 '12 at 16:04

@Mat I'm trying to automatically find an open port to use with ssh -D as a SOCKS server.
–
mybuddymichaelNov 16 '12 at 16:08

4 Answers
4

The script in your answer has a race condition, the only way to avoid it is to atomically check if it is open by trying to open it. If the port is in use, the program should quit with a failure to open the port.

This races badly when multiple applications employ this trick. Mark's answer is much better as it is randomized.
–
LekensteynNov 2 '14 at 22:29

1

@Lekensteyn: Where do you see a race condition here?
–
Chris DownNov 2 '14 at 23:23

This port tries to use the first port available. When you have two concurrent processes, then the port which just got checked might be reused. Re-reading your answer, it seems that you suggest to retry binding on an available port until all ports are exhausted. Assuming that the program in question can distinguish between "port in use" and other errors, it should be fine (though randomization would still make it better for unpredictability).
–
LekensteynNov 2 '14 at 23:44

1

@Lekensteyn Successful port binding results in the kernel returning EADDRINUSE if you try and use it again, it's not possible that "the port which just got checked might be reused".
–
Chris DownNov 3 '14 at 0:56

Yes, I wrongly assumed that you would exit the loop and use $port in the actual program as in while ...; done; program --port $port.
–
LekensteynNov 3 '14 at 9:11

To find the first free port above 1080. Note that ss -D would bind on the loopback interface, so in theory you could reuse port 1080 if a socket has it bound on another address. Another way would be to actually try and bind it: