Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Currently I'm using netstat for this:

if netstat -an | grep ESTABLISHED | grep $address:$port > /dev/null; then
    # command
fi  

Is there a more elegant solution?

share|improve this question
2  
You can use grep -q instead of sending stdout to /dev/null. –  Chris Down Sep 19 '11 at 16:05
    
Comment you've marked as approved answer is flawed — grep and IP-addresses are pitfall, since usual notation for IP-addresses has dots inside. See my comments: unix.stackexchange.com/questions/21020/… P. S. I'd mark as answer this one: unix.stackexchange.com/a/36354/6622 –  poige Apr 14 '12 at 16:33
    
I don't agree that there is such flaw (see comments). But JodieC's answer does look better, just as Gilles' one. –  rozcietrzewiacz Apr 15 '12 at 4:04

5 Answers 5

up vote 3 down vote accepted

As far as elegance is concerned, I'd modify two things in your command:

  • As mentioned in comment by Chris, you can use -q instead of output redirection.
  • Use one grep instead of two:

    if netstat -an | grep -q " $address:$port .* ESTABLISHED"; then
    
share|improve this answer
    
I advice not using grep, when there's no need in regexps fgrep fits better. –  poige Apr 13 '12 at 4:48
1  
@poige But here you do have a regexp. And using fgrep (or rather grep -F, since fgrep is deprecated) in this case is useless also due to negligible potential speed benefit in a single invocation. It would take far more time to type a (longer) working filter with fgrep - and it would need to use pipe, just as in the OP's example. –  rozcietrzewiacz Apr 13 '12 at 6:40
    
My bad, I've overlooked it. Regarding fgrep: 1) GNU's man can call it deprecated (whatever), but neither does BSD's or Solaris'. So I don't care typing extra -f to grep, neither advice doing that to anyone. :) –  poige Apr 14 '12 at 16:27
1  
2) Lots of people tend blindly use grep and spending theirs time in escaping its spec. symbols, or what's a way worse, getting wrong results having forgotten to escape such symbs.. Look, $address you've used in your grep actually has that spec. symbs. — dots. That's a flaw, actually. –  poige Apr 14 '12 at 16:27
    
3) Fgrep is noticable faster on huge files, like log files, for e. g.. So, once again my advice is: use fgrep as much as possible instead of grep — get used to using it. –  poige Apr 14 '12 at 16:27

lsof should do the job. Ask it to give you machine-parseable output with the -F option.

lsof -n -i @${hostname}:${port} -F nT | grep '^TST=ESTABLISHED$'

If you need more information:

lsof -n -i -F nT | awk '
    function host_port(s, a) {
        match(s, /:[^:]*$/);
        a["host"] = substr(s, 1, RSTART-1);
        a["port"] = substr(s, RSTART+1);
    }
    sub(/^p/,"") {pid = $0}
    sub(/^n/,"") {
        split($0, endpoints, "->");
        host_port(endpoints[1], from);
        host_port(endpoints[2], to);
    }
    /^TST=ESTABLISHED$/ {
        print "Established from", from["host"] ":" from["port"],
              "to", to["host"] ":" to["port"]
    }
'
share|improve this answer

with ss:

if ss -n -o state established '( dport = $hostname:$portnumber )'|awk 'NR==2{exit 0}END{exit 1}';then 
share|improve this answer

That works well enough for now, for Linux.

On other UNIX systems (the ones I have my hands on are Mac OS X and Solaris) the port is separated by . instead of :.

And this will most likely fail for any IPv6 connection. netstat truncates IPv6 addresses, so make sure to use --wide. But again, that's not a portable option.

share|improve this answer

You can use lsof instead of netstat: something like this: sudo /usr/sbin/lsof -i tcp@1.2.3.4:80, but lsof is only available for root user and often not installed by default, so it's additional external dependency.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.