Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Linux shell to python

169 views
Skip to first unread message

Chris Angelico

unread,
Jul 30, 2012, 3:40:04 AM7/30/12
to pytho...@python.org
On Mon, Jul 30, 2012 at 5:05 PM, Vikas Kumar Choudhary
<vikas.c...@yahoo.co.in> wrote:
>
> I was trying porting from bash shell to python.
>
> let me know if someone has tried to implement (grep and PIPE) shell commands in python `lspci | grep Q | grep "$isp_str1" | grep "$isp_str2" | cut -c1-7'

Welcome!

While it's technically possible to do exactly that in Python (using
subprocess as you describe), there's usually a more efficient and
cleaner method of achieving the same goal. With a port such as you
describe, it's probably best to go right back to the conceptual level
and work out what exactly you're trying to do, and then look at
implementing that in Python. You'll end up with much cleaner code at
the end of it.

For an initial guess, I would say that you'll use subprocess to invoke
lspci, but then everything else will be done in Python directly.

ChrisA

Philipp Hagemeister

unread,
Jul 30, 2012, 6:35:38 AM7/30/12
to Vikas Kumar Choudhary, pytho...@python.org
On 07/30/2012 09:05 AM, Vikas Kumar Choudhary wrote:
> `lspci | grep Q | grep "$isp_str1" | grep "$isp_str2" | cut -c1-7'

The rough Python equivalent would be

import subprocess
[ l.partition(' ')[0] # or l[:7], if you want to copy it verbatim
for l in subprocess.check_output(['lspci']).splitlines()
if 'Q' in l and isp_str1 in l and isp_str2 in l
]

You can also just paste the whole pipeline with the shell=True
parameter. That's not recommended though, and it's hard to correctly
quote strings.

- Philipp

signature.asc

张少华

unread,
Jul 30, 2012, 7:09:50 AM7/30/12
to
you can use commands.getstatusoutput(command), the shell command special charactor (like "$ and so on )should be escaped!


在 2012年7月30日星期一UTC+8下午3时40分04秒,Chris Angelico写道:

Jürgen A.

unread,
Jul 30, 2012, 7:31:30 AM7/30/12
to pytho...@python.org
On Mon, Jul 30, 2012 at 12:35:38PM +0200, Philipp Hagemeister wrote:
> On 07/30/2012 09:05 AM, Vikas Kumar Choudhary wrote:
> > `lspci | grep Q | grep "$isp_str1" | grep "$isp_str2" | cut -c1-7'
>
> The rough Python equivalent would be
>
> import subprocess
> [ l.partition(' ')[0] # or l[:7], if you want to copy it verbatim
> for l in subprocess.check_output(['lspci']).splitlines()
> if 'Q' in l and isp_str1 in l and isp_str2 in l
> ]

Ouch. A list comprehension spanning more than one line is bad code
pretty much every time.

But you did qualify it as "rough" :D

Grits, J

Peter Otten

unread,
Jul 30, 2012, 7:58:56 AM7/30/12
to pytho...@python.org
Vikas Kumar Choudhary wrote:


> let me know if someone has tried to implement (grep and PIPE) shell
> commands in python `lspci | grep Q | grep "$isp_str1" | grep "$isp_str2"
> | cut -c1-7'
>
> I tried to use python subprocess and OS.Popen modules.

subprocess is the way to go.

> I was trying porting from bash shell to python.

Here's an example showing how to translate a shell pipe:

http://docs.python.org/library/subprocess.html#replacing-shell-pipeline

But even if you can port the shell script literally I recommend a more
structured approach:

import subprocess
import itertools

def parse_data(lines):
for not_empty, group in itertools.groupby(lines, key=bool):
if not_empty:
triples = (line.partition(":") for line in group)
pairs = ((left, right.strip()) for left, sep, right in triples)
yield dict(pairs)

if __name__ == "__main__":
def get(field):
return entry.get(field, "").lower()
output = subprocess.Popen(["lspci", "-vmm"],
stdout=subprocess.PIPE).communicate()[0]
for entry in parse_data(output.splitlines()):
if "nvidia" in get("Vendor") and "usb" in get("Device"):
print entry["Slot"]
print entry["Device"]
print

Philipp Hagemeister

unread,
Jul 30, 2012, 7:59:15 AM7/30/12
to "Jürgen A. Erhard", pytho...@python.org
I didn't want to introduce a separate function, but as requested, here's
the function version:

def pciIds(searchWords=['Q', isp_str1, isp_str2]):
for l in subprocess.check_output(['lspci']).splitlines():
if all(sw in l for sw in searchWords):
yield l.partition(' ')[0]

You could also separate the processing, like this:

lines = subprocess.check_output(['lspci']).splitlines()
lines = [l for l in lines if 'Q' in l and isp_str1 in l and isp_str2 in l]
# Or:
lines = filter(lambda l: 'Q' in l and isp_str1 in l and isp_str2 in l,
lines)


[l.partition(' ')[0] for l in lines]
# Or:
map(lambda l: l.partition(' ')[0], lines)

But personally, I have no problem with three-line list comprehensions.
Can you elaborate why the list comprehension version is bad code?

Or more to the point, how would *you* write it?

- Philipp


signature.asc

Emile van Sebille

unread,
Jul 30, 2012, 7:14:25 PM7/30/12
to pytho...@python.org
On 7/30/2012 3:56 PM Dan Stromberg said...
>
> On Mon, Jul 30, 2012 at 9:26 PM, Barry Scott <ba...@barrys-emacs.org

> And of course you can write list comprehensions on as many lines as
> it take to make the code maintainable.
>
> Sigh, and I'm also not keen on multi-line list comprehensions,
> specifically because I think they tend to make less readable code. It
> also becomes a mess when you need to insert print statements to get some
> visibility into what's going on.

I tend to write long one-liners then convert them to loops the first
time I need to see what's going on.

Premature optimization otherwise. :)

Emile



Message has been deleted

Mark Lawrence

unread,
Jul 31, 2012, 3:15:32 AM7/31/12
to pytho...@python.org
On 31/07/2012 02:20, Dennis Lee Bieber wrote:
> On Mon, 30 Jul 2012 22:56:48 +0000, Dan Stromberg <drsa...@gmail.com>
> declaimed the following in gmane.comp.python.general:
>
>
>> Sigh, and I'm also not keen on multi-line list comprehensions, specifically
>> because I think they tend to make less readable code. It also becomes a
>> mess when you need to insert print statements to get some visibility into
>> what's going on.
>
> Cleanly splitting the list-comp by
>
> [ result-computation
> for-item-selection-clause
> if-filter-clause ]
>
> isn't that unreadable... But anyone doing
>
> [ result-
> -computation for-item-
> -selection-clause if-
> -filter-
> -clause ]
>
> should be pecked to death by a dead parrot.
>

Any particular species?

--
Cheers.

Mark Lawrence.

Chris Angelico

unread,
Jul 31, 2012, 4:05:49 AM7/31/12
to pytho...@python.org
I'm sure that, if you're in Norway, you could find an appropriate
bird. But for those of us for whom that's not an option, I'd be
content to nail the programmer's feet to the cage and then return him
whence he came as a faulty model. Unfortunately local law enforcement
would want in on that deal.

ChrisA

Alister

unread,
Jul 31, 2012, 6:53:41 AM7/31/12
to
as has already been hinted - Norwegian Blue



--
Question: Is it better to abide by the rules until they're changed or
help speed the change by breaking them?
Message has been deleted

88888 Dihedral

unread,
Jul 31, 2012, 3:01:38 PM7/31/12
to pytho...@python.org
Mark Lawrence於 2012年7月31日星期二UTC+8下午3時15分32秒寫道:
For each item in the known list that passes the required conditional test,
then use the item to perform the tasks desired as instructed.

It is not necessary that a new list has to be constructed in the tasks.

A method which can produce a new object always involves some memory management.
Therefore, some error handling part should not be missing.


88888 Dihedral

unread,
Jul 31, 2012, 3:01:38 PM7/31/12
to comp.lan...@googlegroups.com, pytho...@python.org
Mark Lawrence於 2012年7月31日星期二UTC+8下午3時15分32秒寫道:
0 new messages