Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm quite new to strace / netstat / etc. I'm using this command to get a trace of the apache process handling my request (telnet), is there a way to simplify it a bit?

sudo strace -o /tmp/strace -f -s4096 -r -p $(netstat -antlp | \ 
    grep $(lsof -p `pidof telnet` | grep TCP | \
    perl -n -e'/localhost:(\d+)/ && print $1') | grep apache2 | \ 
    perl -n -e'/ESTABLISHED (\d+)/ && print $1')

Thanks!

share|improve this question
    
Are you running this before or after you start the telnet process? –  deltaray Jun 22 '12 at 11:53
    
after it's started, you have to wait a few seconds for it to connect to apache, then you can run strace –  Andrei Serdeliuc Jun 22 '12 at 13:57
1  
If your command works, don't bother simplifying it. –  Tom O'Connor Jul 3 '12 at 17:10
add comment

4 Answers

up vote 1 down vote accepted
+50

I can improve on Mark Henderson's a little, with $() instead of `` and removing the grep with a better sed:

sudo strace -o /tmp/strace -f -s4096 -r -p $(netstat -antlp | \
   sed -e "/telnet/s/^.*ESTABLISHED\ \|\/.*$//g")

Personally I think the backticks make it difficult to read; furthermore, they don't nest, unlike the $() syntax

share|improve this answer
    
+1, superior Script Fu and good learning example for some shell features. –  Jeff Ferland Jul 5 '12 at 14:53
    
This script straces into the telnet, not into the Apache process that's serving it. –  BMDan Jul 13 '12 at 15:04
add comment

strace -p $(ss -npt|sed -n "/:$(ss -npt|sed -n '/telnet/s/^.*\?:\([0-9]\+\).*/\1/p') \+u/s/.*,\(.*\),.*/\1/p")

As long as you only have one telnet running, this will strace the corresponding server if any.

If there isn't one (eg you telneted to an external server last), strace will fail with strace: option requires an argument -- 'p'

share|improve this answer
add comment
strace -p $(netstat -tnp|awk -F'[ /]+' "/:$(netstat -tnp|awk -F'[ :]+' 
"/\/telnet/{print \$5}") /&&/apache2/{print \$7}")

Or, formatted for easier reading, and with the OP's strace flags intact:

sudo strace -o /tmp/strace -f -s4096 -r -p $(netstat -tnp | \
awk -F'[ /]+' "/:$(netstat -tnp | awk -F'[ :]+' "/\/telnet/ \
{print \$5}") / && /apache2/ {print \$7}")

Breakdown, innermost first:

netstat -tnp | awk -F'[ :]+' "/\/telnet/ {print \$5}"

Show me, in without resolving IP addresses to DNS names, all active TCP connections. Pipe that to awk, which prints the fifth field on any line ending in /telnet, where fields are separated by one or more spaces and colons. This field will be the source port.

To improve: Could be made much more robust by adding a | head -n 1 to the end or a ;exit inside the action portion of the awk, but your original version lacked an equivalent, so I didn't want to make this one longer.

netstat -tnp | awk -F'[ /]+' "/:**** / && /apache2/ {print \$7}")

The **** here is the portion I've already explained, above. Here, I'm looking for any line in netstat -tnp that has the same port as the source port I discovered above, and is owned by Apache; when I find it, I print the seventh field (delimited by one or more spaces or slashes). This is the PID of the Apache child.

To improve: Besides only returning one PID (via the same methods as above), the biggest thing I can imagine is being more discriminative when it comes to actually matching the dport as opposed to something else that just so happens to fit the pattern. This would have been easy to do by adding colons to the FS (-F), but the problem occurs in mixed IPv4 vs. IPv6 situations, where there might be colons in the address itself, and as such could get nasty rather quickly. This seemed pretty damn robust, especially with the trailing space.

sudo strace -o /tmp/strace -f -s4096 -r -p

This is a direct copy from your original question; I didn't modify it in the least.

If you'll permit me a few extra characters, the version I'd run might be:

sudo strace -o /tmp/strace -f -s4096 -r -p $(netstat -tnp | \
awk -F'[ /]+' "/:$(netstat -tnp | awk -F'[ :]+' "/\/telnet/ \
{print \$5;exit}") / && /apache2/ {print \$7;exit}")
share|improve this answer
add comment

Try this, hope it helps:

sudo strace -o /tmp/strace -f -s4096 -r -p `netstat -antlp | \
  grep telnet | sed -e "s/^.*ESTABLISHED\ \|\/.*$//g"`
share|improve this answer
    
Answer would look nicer if you didn't have to scroll to the right to see it all. –  djangofan Jul 2 '12 at 18:06
    
This straces into the telnet, not Apache. –  Pierre Carrier Jul 3 '12 at 17:06
add comment

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.