Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #33299 > unrolled thread

Subprocess puzzle and two questions

Started bywrw@mac.com
First post2012-11-13 22:34 -0500
Last post2012-11-13 23:17 -0800
Articles 19 — 10 participants

Back to article view | Back to comp.lang.python


Contents

  Subprocess puzzle and two questions wrw@mac.com - 2012-11-13 22:34 -0500
    Re: Subprocess puzzle and two questions Roy Smith <roy@panix.com> - 2012-11-13 23:41 -0500
      Re: Subprocess puzzle and two questions William Ray Wing <wrw@mac.com> - 2012-11-14 00:03 -0500
        Re: Subprocess puzzle and two questions Roy Smith <roy@panix.com> - 2012-11-14 09:22 -0500
          Re: Subprocess puzzle and two questions Chris Angelico <rosuav@gmail.com> - 2012-11-15 01:40 +1100
            Re: Subprocess puzzle and two questions roy@panix.com (Roy Smith) - 2012-11-14 11:20 -0500
              Re: Subprocess puzzle and two questions Chris Angelico <rosuav@gmail.com> - 2012-11-15 08:54 +1100
                Re: Subprocess puzzle and two questions Roy Smith <roy@panix.com> - 2012-11-14 20:49 -0500
                  Re: Subprocess puzzle and two questions Chris Angelico <rosuav@gmail.com> - 2012-11-15 13:04 +1100
                    Re: Subprocess puzzle and two questions Roy Smith <roy@panix.com> - 2012-11-14 21:10 -0500
                      Re: Subprocess puzzle and two questions Chris Angelico <rosuav@gmail.com> - 2012-11-15 13:21 +1100
                      Re: Subprocess puzzle and two questions Dave Angel <d@davea.name> - 2012-11-14 21:55 -0500
                  Re: Subprocess puzzle and two questions Kushal Kumaran <kushal.kumaran+python@gmail.com> - 2012-11-15 10:23 +0530
                  Re: Subprocess puzzle and two questions Nobody <nobody@nowhere.com> - 2012-11-15 22:54 +0000
                    Re: Subprocess puzzle and two questions Roy Smith <roy@panix.com> - 2012-11-15 20:07 -0500
                      Re: Subprocess puzzle and two questions Nobody <nobody@nowhere.com> - 2012-11-17 00:17 +0000
                DNS from Python (was Re: Subprocess puzzle and two questions) aahz@pythoncraft.com (Aahz) - 2012-11-14 21:42 -0800
          Re: Subprocess puzzle and two questions wrw@mac.com - 2012-11-14 09:37 -0500
    Re: Subprocess puzzle and two questions Tim Roberts <timr@probo.com> - 2012-11-13 23:17 -0800

#33299 — Subprocess puzzle and two questions

Fromwrw@mac.com
Date2012-11-13 22:34 -0500
SubjectSubprocess puzzle and two questions
Message-ID<mailman.3664.1352867713.27098.python-list@python.org>
I need to time the operation of a command-line utility (specifically nslookup) from within a python program I'm writing.  I don't want to use python's timeit function because I'd like to avoid python's subprocess creation overhead.  That leads me to the standard UNIX time function.  So for example, in my bash shell, if I enter:

	$ time nslookup www.es.net 8.8.4.4

I get:

	Server:	 	8.8.4.4
	Address:	8.8.4.4#53

	Non-authoritative answer:
	www.es.net	canonical name = www3.es.net.
	Name:	www3.es.net
	Address: 128.55.22.201

	 real	0m0.069s
	 user	0m0.006s
	 sys	0m0.004s 

The first lines are the result of an nslookup of the IP address of "www.es.net" using the server at 8.8.4.4 (Google's public DNS server b).
The last three lines are what I'm after: the real elapsed wall-clock time, the time spent in user space and the time spent in kernel space.

However, if I try the same operation in the python interpreter using subprocess.Popen like so:

>>> import subprocess
>>> result = subprocess.Popen(['time', 'nslookup', 'www.es.net', '8.8.4.4'], shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
>>> print result
('Server:\t\t8.8.4.4\nAddress:\t8.8.4.4#53\n\nNon-authoritative answer:\nwww.es.net\tcanonical name = www3.es.net.\nName:\twww3.es.net\nAddress: 128.55.22.201\n\n', '        0.06 real         0.00 user         0.00 sys\n')

And the timing information I'm after has been truncated to two digits after the decimal.  It appears that Popen is applying a default format. If I do explicit formatting:

>>> time = result[1].lstrip().split(' ')[0]
>>> formatted_time = '{: >7.3f}'.format(float(time))
>>> print formatted_time
  0.060

I get three digits, BUT that third digit isn't real, the format operation has simply appended a zero.  So:

1) how can I recover that third digit from the subprocess?
2) is there a more pythonic way to do what I'm trying to do?

python 2.7, OS-X 10.8.2

Thanks in advance -
Bill Wing

[toc] | [next] | [standalone]


#33300

FromRoy Smith <roy@panix.com>
Date2012-11-13 23:41 -0500
Message-ID<roy-9D599D.23412413112012@news.panix.com>
In reply to#33299
In article <mailman.3664.1352867713.27098.python-list@python.org>,
 wrw@mac.com wrote:

> I need to time the operation of a command-line utility (specifically 
> nslookup) from within a python program I'm writing.

Ugh.  Why are you doing this?  Shelling out to nslookup is an incredibly 
slow and clumsy way of doing name translation.  What you really want to 
be doing is calling getaddrinfo() directly.

See http://docs.python.org/2/library/socket.html#socket.getaddrinfo for 
details.

[toc] | [prev] | [next] | [standalone]


#33303

FromWilliam Ray Wing <wrw@mac.com>
Date2012-11-14 00:03 -0500
Message-ID<mailman.3666.1352873042.27098.python-list@python.org>
In reply to#33300
On Nov 13, 2012, at 11:41 PM, Roy Smith <roy@panix.com> wrote:

> In article <mailman.3664.1352867713.27098.python-list@python.org>,
> wrw@mac.com wrote:
> 
>> I need to time the operation of a command-line utility (specifically 
>> nslookup) from within a python program I'm writing.
> 
> Ugh.  Why are you doing this?  Shelling out to nslookup is an incredibly 
> slow and clumsy way of doing name translation.  What you really want to 
> be doing is calling getaddrinfo() directly.
> 
> See http://docs.python.org/2/library/socket.html#socket.getaddrinfo for 
> details.
> -- 
Because, unless I'm badly mistaken (very possible), getaddrinfo doesn't let me specify the server from which the name is returned. I'm really not after the name, what I'm REALLY after is the fact that a path exists to the name server I specify (and how long it takes to respond). In the "good old days" I would just have ping'd it, but these days more and more DNS boxes (and servers of all sorts) are shutting off their ping response.

Thanks, Bill

[toc] | [prev] | [next] | [standalone]


#33337

FromRoy Smith <roy@panix.com>
Date2012-11-14 09:22 -0500
Message-ID<roy-F5C640.09225714112012@news.panix.com>
In reply to#33303
In article <mailman.3666.1352873042.27098.python-list@python.org>,
 William Ray Wing <wrw@mac.com> wrote:

> On Nov 13, 2012, at 11:41 PM, Roy Smith <roy@panix.com> wrote:
> 
> > In article <mailman.3664.1352867713.27098.python-list@python.org>,
> > wrw@mac.com wrote:
> > 
> >> I need to time the operation of a command-line utility (specifically 
> >> nslookup) from within a python program I'm writing.
> > 
> > Ugh.  Why are you doing this?  Shelling out to nslookup is an incredibly 
> > slow and clumsy way of doing name translation.  What you really want to 
> > be doing is calling getaddrinfo() directly.
> > 
> > See http://docs.python.org/2/library/socket.html#socket.getaddrinfo for 
> > details.
> > -- 
> Because, unless I'm badly mistaken (very possible), getaddrinfo doesn't let 
> me specify the server from which the name is returned. I'm really not after 
> the name, what I'm REALLY after is the fact that a path exists to the name 
> server I specify (and how long it takes to respond). In the "good old days" I 
> would just have ping'd it, but these days more and more DNS boxes (and 
> servers of all sorts) are shutting off their ping response.
> 
> Thanks, Bill

Oh, my.  You're using DNS as a replacement for ping?  Fair enough.  In 
that case, all you really care about is that you can connect to port 53 
on the server...

import socket
import time
s = socket.socket()
t0 = time.time()
s.connect(('8.8.8.8', 53))
t1 = time.time()
print "it took %f seconds to connect" % (t1 - t0)

[toc] | [prev] | [next] | [standalone]


#33338

FromChris Angelico <rosuav@gmail.com>
Date2012-11-15 01:40 +1100
Message-ID<mailman.3684.1352904008.27098.python-list@python.org>
In reply to#33337
On Thu, Nov 15, 2012 at 1:22 AM, Roy Smith <roy@panix.com> wrote:
> Oh, my.  You're using DNS as a replacement for ping?  Fair enough.  In
> that case, all you really care about is that you can connect to port 53
> on the server...
>
> import socket
> import time
> s = socket.socket()
> t0 = time.time()
> s.connect(('8.8.8.8', 53))
> t1 = time.time()
> print "it took %f seconds to connect" % (t1 - t0)

That assumes that (a) the remote server supports TCP for DNS (since
UDP is by far the more often used, some name servers don't bother
supporting TCP), and (b) that connection time for TCP is comparable to
ping or an actual DNS lookup. But in terms of approximating your
connection times, that's gotta be way better than shelling out to
several other processes.

ChrisA

[toc] | [prev] | [next] | [standalone]


#33346

Fromroy@panix.com (Roy Smith)
Date2012-11-14 11:20 -0500
Message-ID<k80gd6$t0q$1@panix2.panix.com>
In reply to#33338
I wrote:
>> Oh, my.  You're using DNS as a replacement for ping?  Fair enough.  In
>> that case, all you really care about is that you can connect to port 53
>> on the server...
>>
>> s = socket.socket()
>> s.connect(('8.8.8.8', 53))

In article <mailman.3684.1352904008.27098.python-list@python.org>,
Chris Angelico  <rosuav@gmail.com> wrote:
>That assumes that (a) the remote server supports TCP for DNS

This is true.  I honestly don't know what percentage of DNS servers
out there only support UDP.  The two I tried (Google's 8.8.8.8, and my
Apple TimeCapsule) both supported TCP, but that's hardly a
representitive sample.

> and (b) that connection time for TCP is comparable to
> ping or an actual DNS lookup.

My first thought to solve both of these is that it shouldn't be too
hard to hand-craft a minimal DNS query and send it over UDP.  Then, I
hunted around a bit and found that somebody had already done that, in
spades.  Take a look at http://www.dnspython.org; it might be exactly
what's needed here.

[toc] | [prev] | [next] | [standalone]


#33356

FromChris Angelico <rosuav@gmail.com>
Date2012-11-15 08:54 +1100
Message-ID<mailman.3700.1352930072.27098.python-list@python.org>
In reply to#33346
On Thu, Nov 15, 2012 at 3:20 AM, Roy Smith <roy@panix.com> wrote:
> I wrote:
>>> Oh, my.  You're using DNS as a replacement for ping?  Fair enough.  In
>>> that case, all you really care about is that you can connect to port 53
>>> on the server...
>>>
>>> s = socket.socket()
>>> s.connect(('8.8.8.8', 53))
>
> In article <mailman.3684.1352904008.27098.python-list@python.org>,
> Chris Angelico  <rosuav@gmail.com> wrote:
>>That assumes that (a) the remote server supports TCP for DNS
>
> This is true.  I honestly don't know what percentage of DNS servers
> out there only support UDP.  The two I tried (Google's 8.8.8.8, and my
> Apple TimeCapsule) both supported TCP, but that's hardly a
> representitive sample.

I don't know either, all I know is that DNSReport recommends
supporting TCP, and none of my DNS servers ever fail that check.

>> and (b) that connection time for TCP is comparable to
>> ping or an actual DNS lookup.
>
> My first thought to solve both of these is that it shouldn't be too
> hard to hand-craft a minimal DNS query and send it over UDP.  Then, I
> hunted around a bit and found that somebody had already done that, in
> spades.  Take a look at http://www.dnspython.org; it might be exactly
> what's needed here.

Yeah, that sounds like a good option. I'm slightly surprised that
there's no way with the Python stdlib to point a DNS query at a
specific server, but dnspython might be the solution. On the flip
side, dnspython is dauntingly large; it looks like a full
implementation of DNS, but I don't see a simple entrypoint that wraps
it all up into a simple function that can be bracketed with
time.time() calls (granted, I only skimmed the docs VERY quickly). So
it may be simpler to hand-craft an outgoing UDP packet once, save it
as a string literal, send that, and just wait for any response. That
eliminates all DNS protocolling and just times the round trip.

ChrisA

[toc] | [prev] | [next] | [standalone]


#33364

FromRoy Smith <roy@panix.com>
Date2012-11-14 20:49 -0500
Message-ID<roy-BF8F05.20491814112012@news.panix.com>
In reply to#33356
In article <mailman.3700.1352930072.27098.python-list@python.org>,
 Chris Angelico <rosuav@gmail.com> wrote:

> I'm slightly surprised that there's no way with the Python stdlib to 
> point a DNS query at a specific server

Me too, including the "only slightly" part.  The normal high-level C 
resolver routines (getaddrinfo/getnameinfo, or even the old 
gethostbyname series), don't expose any way to do that.  You have to dig 
quite far down in the resolver library stack to get to the point where 
you can do that.  The concept of not knowing or caring which specific 
server has the data you need is quite deeply baked into the basic DNS 
architecture.

[toc] | [prev] | [next] | [standalone]


#33366

FromChris Angelico <rosuav@gmail.com>
Date2012-11-15 13:04 +1100
Message-ID<mailman.3707.1352945064.27098.python-list@python.org>
In reply to#33364
On Thu, Nov 15, 2012 at 12:49 PM, Roy Smith <roy@panix.com> wrote:
> In article <mailman.3700.1352930072.27098.python-list@python.org>,
>  Chris Angelico <rosuav@gmail.com> wrote:
>
>> I'm slightly surprised that there's no way with the Python stdlib to
>> point a DNS query at a specific server
>
> Me too, including the "only slightly" part.  The normal high-level C
> resolver routines (getaddrinfo/getnameinfo, or even the old
> gethostbyname series), don't expose any way to do that.  You have to dig
> quite far down in the resolver library stack to get to the point where
> you can do that.  The concept of not knowing or caring which specific
> server has the data you need is quite deeply baked into the basic DNS
> architecture.

Indeed. But Python boasts that the batteries are included, and given
the wealth of other networking facilities that are available, it is a
bit of a hole that you can't run DNS queries in this way.

Mind you, if Python's managed to get this far without it being a major
stumbling-block, that probably means that it's not a serious lack. And
I don't think many people write DNS *servers* in Python. (Most people
don't write DNS servers at all, since BIND exists. But I did exactly
that this week, since it would be easier than most other options.)

ChrisA

[toc] | [prev] | [next] | [standalone]


#33367

FromRoy Smith <roy@panix.com>
Date2012-11-14 21:10 -0500
Message-ID<roy-7E5CC6.21102914112012@news.panix.com>
In reply to#33366
In article <mailman.3707.1352945064.27098.python-list@python.org>,
 Chris Angelico <rosuav@gmail.com> wrote:

> Indeed. But Python boasts that the batteries are included, and given
> the wealth of other networking facilities that are available, it is a
> bit of a hole that you can't run DNS queries in this way.

Think of the socket and struct modules as a pile of carbon rods and gobs 
of zinc paste, from which you can assemble your own batteries, and make 
them in exactly the shape and size you need.

[toc] | [prev] | [next] | [standalone]


#33368

FromChris Angelico <rosuav@gmail.com>
Date2012-11-15 13:21 +1100
Message-ID<mailman.3708.1352946069.27098.python-list@python.org>
In reply to#33367
On Thu, Nov 15, 2012 at 1:10 PM, Roy Smith <roy@panix.com> wrote:
> In article <mailman.3707.1352945064.27098.python-list@python.org>,
>  Chris Angelico <rosuav@gmail.com> wrote:
>
>> Indeed. But Python boasts that the batteries are included, and given
>> the wealth of other networking facilities that are available, it is a
>> bit of a hole that you can't run DNS queries in this way.
>
> Think of the socket and struct modules as a pile of carbon rods and gobs
> of zinc paste, from which you can assemble your own batteries, and make
> them in exactly the shape and size you need.

Then assembly language is a pile of protons, neutrons, and electrons...

:)

ChrisA

[toc] | [prev] | [next] | [standalone]


#33369

FromDave Angel <d@davea.name>
Date2012-11-14 21:55 -0500
Message-ID<mailman.3709.1352948147.27098.python-list@python.org>
In reply to#33367
On 11/14/2012 09:21 PM, Chris Angelico wrote:
> On Thu, Nov 15, 2012 at 1:10 PM, Roy Smith <roy@panix.com> wrote:
>> In article <mailman.3707.1352945064.27098.python-list@python.org>,
>>  Chris Angelico <rosuav@gmail.com> wrote:
>>
>>> Indeed. But Python boasts that the batteries are included, and given
>>> the wealth of other networking facilities that are available, it is a
>>> bit of a hole that you can't run DNS queries in this way.
>> Think of the socket and struct modules as a pile of carbon rods and gobs
>> of zinc paste, from which you can assemble your own batteries, and make
>> them in exactly the shape and size you need.
> Then assembly language is a pile of protons, neutrons, and electrons...

And real machine language (microcode) is a pile of quarks;  fermions
versus bosons.  But in recent years, you pretty much have to work at
Intel to see that part of the processor.



-- 

DaveA

[toc] | [prev] | [next] | [standalone]


#33370

FromKushal Kumaran <kushal.kumaran+python@gmail.com>
Date2012-11-15 10:23 +0530
Message-ID<mailman.3710.1352955207.27098.python-list@python.org>
In reply to#33364
Chris Angelico <rosuav@gmail.com> writes:

> On Thu, Nov 15, 2012 at 12:49 PM, Roy Smith <roy@panix.com> wrote:
>> In article <mailman.3700.1352930072.27098.python-list@python.org>,
>>  Chris Angelico <rosuav@gmail.com> wrote:
>>
>>> I'm slightly surprised that there's no way with the Python stdlib to
>>> point a DNS query at a specific server
>>
>> Me too, including the "only slightly" part.  The normal high-level C
>> resolver routines (getaddrinfo/getnameinfo, or even the old
>> gethostbyname series), don't expose any way to do that.  You have to dig
>> quite far down in the resolver library stack to get to the point where
>> you can do that.  The concept of not knowing or caring which specific
>> server has the data you need is quite deeply baked into the basic DNS
>> architecture.
>
> Indeed. But Python boasts that the batteries are included, and given
> the wealth of other networking facilities that are available, it is a
> bit of a hole that you can't run DNS queries in this way.
>
> Mind you, if Python's managed to get this far without it being a major
> stumbling-block, that probably means that it's not a serious lack. And
> I don't think many people write DNS *servers* in Python. (Most people
> don't write DNS servers at all, since BIND exists. But I did exactly
> that this week, since it would be easier than most other options.)
>

Indeed.  Most people would prefer if random applications didn't make
their own decisions about using specific DNS servers.  That way, the
users can make their own configuration choices (gai.conf, nsswitch.conf)
according to their site preferences.

If your application needs that level of control (if you're writing a
nslookup replacement for some reason, perhaps), dnspython
(www.dnspython.org) seems to have it.

-- 
regards,
kushal

[toc] | [prev] | [next] | [standalone]


#33404

FromNobody <nobody@nowhere.com>
Date2012-11-15 22:54 +0000
Message-ID<pan.2012.11.15.22.54.09.449000@nowhere.com>
In reply to#33364
On Wed, 14 Nov 2012 20:49:19 -0500, Roy Smith wrote:

>> I'm slightly surprised that there's no way with the Python stdlib to 
>> point a DNS query at a specific server
> 
> Me too, including the "only slightly" part.  The normal high-level C 
> resolver routines (getaddrinfo/getnameinfo, or even the old 
> gethostbyname series), don't expose any way to do that.

That's because the high-level routines aren't tied to DNS.

gethostbyname() and getaddrinfo() use the NSS (name-service switch)
mechanism, which is configured via /etc/nsswitch.conf. Depending upon
configuration, hostnames can be looked up via a plain text file
(/etc/hosts), Berkeley DB files, DNS, NIS, NIS+, LDAP, WINS, etc. DNS is
just one particular back-end, which may or may not be used on any given
system.

If you specifically want to perform DNS queries, you have to use a
DNS-specific interface (e.g. the res_* functions described in the
resolver(3) manpage), or raw sockets, rather than a high-level interface
such as gethostbyname() or getaddrinfo().

[toc] | [prev] | [next] | [standalone]


#33407

FromRoy Smith <roy@panix.com>
Date2012-11-15 20:07 -0500
Message-ID<roy-17407F.20073815112012@news.panix.com>
In reply to#33404
In article <pan.2012.11.15.22.54.09.449000@nowhere.com>,
 Nobody <nobody@nowhere.com> wrote:

> That's because the high-level routines aren't tied to DNS.

This is true.

>> gethostbyname() and getaddrinfo() use the NSS (name-service switch)
> mechanism, which is configured via /etc/nsswitch.conf. Depending upon
> configuration, hostnames can be looked up via a plain text file
> (/etc/hosts), Berkeley DB files, DNS, NIS, NIS+, LDAP, WINS, etc.

Gethostbyname() long predates NSS.  For that matter, I think it even 
predates DNS (i.e. back to the days when /etc/hosts was the *only* way 
to look up a hostname).

But, that's a nit.

[toc] | [prev] | [next] | [standalone]


#33459

FromNobody <nobody@nowhere.com>
Date2012-11-17 00:17 +0000
Message-ID<pan.2012.11.17.00.17.25.286000@nowhere.com>
In reply to#33407
On Thu, 15 Nov 2012 20:07:38 -0500, Roy Smith wrote:

>>> gethostbyname() and getaddrinfo() use the NSS (name-service switch)
>> mechanism, which is configured via /etc/nsswitch.conf. Depending upon
>> configuration, hostnames can be looked up via a plain text file
>> (/etc/hosts), Berkeley DB files, DNS, NIS, NIS+, LDAP, WINS, etc.
> 
> Gethostbyname() long predates NSS.

Before NSS there was host.conf, which provided similar functionality
except that the set of mechanisms was fixed (they were built into libc
rather than being dynamically-loaded libraries) and it only applied to
hostnames (NSS is also used for getpwent(), getprotoent(), etc).

> For that matter, I think it even predates DNS (i.e. back to the days
> when /etc/hosts was the *only* way to look up a hostname).
> 
> But, that's a nit.

Indeed; the main point is that gethostbyname() has never been specific to
DNS.

[toc] | [prev] | [next] | [standalone]


#33372 — DNS from Python (was Re: Subprocess puzzle and two questions)

Fromaahz@pythoncraft.com (Aahz)
Date2012-11-14 21:42 -0800
SubjectDNS from Python (was Re: Subprocess puzzle and two questions)
Message-ID<k81vd2$aoi$1@panix5.panix.com>
In reply to#33356
In article <mailman.3700.1352930072.27098.python-list@python.org>,
Chris Angelico  <rosuav@gmail.com> wrote:
>On Thu, Nov 15, 2012 at 3:20 AM, Roy Smith <roy@panix.com> wrote:
>> 
>> My first thought to solve both of these is that it shouldn't be too
>> hard to hand-craft a minimal DNS query and send it over UDP.  Then, I
>> hunted around a bit and found that somebody had already done that, in
>> spades.  Take a look at http://www.dnspython.org; it might be exactly
>> what's needed here.
>
>Yeah, that sounds like a good option. I'm slightly surprised that
>there's no way with the Python stdlib to point a DNS query at a
>specific server, but dnspython might be the solution. On the flip
>side, dnspython is dauntingly large; it looks like a full
>implementation of DNS, but I don't see a simple entrypoint that wraps
>it all up into a simple function that can be bracketed with
>time.time() calls (granted, I only skimmed the docs VERY quickly). So
>it may be simpler to hand-craft an outgoing UDP packet once, save it
>as a string literal, send that, and just wait for any response. That
>eliminates all DNS protocolling and just times the round trip.

From one of my scripts lying around:

    domain = MAILTO.split('@',1)[1]
    server = str(dns.resolver.query(domain, 'MX')[0].exchange)

You'll need to play around a bit to find out what that does, but it
should point you in the right direction.
-- 
Aahz (aahz@pythoncraft.com)           <*>         http://www.pythoncraft.com/

"LL YR VWL R BLNG T S"  -- www.nancybuttons.com

[toc] | [prev] | [next] | [standalone]


#33341

Fromwrw@mac.com
Date2012-11-14 09:37 -0500
Message-ID<mailman.3687.1352907443.27098.python-list@python.org>
In reply to#33337
On Nov 14, 2012, at 9:22 AM, Roy Smith <roy@panix.com> wrote:

> In article <mailman.3666.1352873042.27098.python-list@python.org>,
> William Ray Wing <wrw@mac.com> wrote:
> 
>> On Nov 13, 2012, at 11:41 PM, Roy Smith <roy@panix.com> wrote:
>> 
>>> In article <mailman.3664.1352867713.27098.python-list@python.org>,
>>> wrw@mac.com wrote:
>>> 
>>>> I need to time the operation of a command-line utility (specifically 
>>>> nslookup) from within a python program I'm writing.
>>> 
>>> Ugh.  Why are you doing this?  Shelling out to nslookup is an incredibly 
>>> slow and clumsy way of doing name translation.  What you really want to 
>>> be doing is calling getaddrinfo() directly.
>>> 
>>> See http://docs.python.org/2/library/socket.html#socket.getaddrinfo for 
>>> details.
>>> -- 
>> Because, unless I'm badly mistaken (very possible), getaddrinfo doesn't let 
>> me specify the server from which the name is returned. I'm really not after 
>> the name, what I'm REALLY after is the fact that a path exists to the name 
>> server I specify (and how long it takes to respond). In the "good old days" I 
>> would just have ping'd it, but these days more and more DNS boxes (and 
>> servers of all sorts) are shutting off their ping response.
>> 
>> Thanks, Bill
> 
> Oh, my.  You're using DNS as a replacement for ping?  Fair enough.  In 
> that case, all you really care about is that you can connect to port 53 
> on the server...
> 
> import socket
> import time
> s = socket.socket()
> t0 = time.time()
> s.connect(('8.8.8.8', 53))
> t1 = time.time()
> print "it took %f seconds to connect" % (t1 - t0)
> -- 
> http://mail.python.org/mailman/listinfo/python-list

Now THAT looks better.  Simpler, cleaner, (longer, taller, stronger, faster, cheaper…  :-)

Thanks,
Bill

[toc] | [prev] | [next] | [standalone]


#33309

FromTim Roberts <timr@probo.com>
Date2012-11-13 23:17 -0800
Message-ID<s0h6a89a5pem8sd0u78adu6of2bb04j4e6@4ax.com>
In reply to#33299
wrw@mac.com wrote:
>...
>However, if I try the same operation in the python interpreter using subprocess.Popen like so:
>
>>>> import subprocess
>>>> result = subprocess.Popen(['time', 'nslookup', 'www.es.net', '8.8.4.4'], shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
>>>> print result
>('Server:\t\t8.8.4.4\nAddress:\t8.8.4.4#53\n\nNon-authoritative answer:\nwww.es.net\tcanonical name = www3.es.net.\nName:\twww3.es.net\nAddress: 128.55.22.201\n\n', '        0.06 real         0.00 user         0.00 sys\n')
>
>And the timing information I'm after has been truncated to two digits after the decimal.  It appears that Popen is applying a default format. 

No, that's silly.  A few minutes thought should have told you that.  In
your standalone test, you are getting the "time" command that is built in
to bash.  In the subprocess example, you've specified "shell = False", so
you are using the external "time" command (/usr/bin/time in my system), and
that command has a different output format.  The csh "time" command is
different yet again.

>1) how can I recover that third digit from the subprocess?

Do you actually believe that the third decimal place has any meaning at
all?  It doesn't.
-- 
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web