Re: Slinging OS commands arround like Perl.

Steven D. Majewski (sdm7g@elvis.med.virginia.edu)
Mon, 28 Feb 1994 11:35:43 -0500

On Feb 26, 21:10, David Williams wrote:
>
> Is there anyway to sling OS commands around in Python like you can with the
> following constructs under Perl:
>
> open(FINGER,"finger dwwillia@cyclops|");
>
> and
>
> print `finger dwwillia@cyclops`;
>

To add to Tim's reply: a more Perl-ish open is easy to define in
Python. This is useful when you want to support the typical unix
convention of '-' meaning stdin ( or stdout, depending on context),
as well as allowing a "|" prefix/suffix to mean pipe to/from command.

Just "from myopen import *" ( or "from myopen import open" )
to cause this version of open to override __builtin__.open()

----------------------myopen.py---------

#!/usr/local/bin/python
#
import posix
import __builtin__
import sys

#
# arg 'f' is :
# "|cmd" : open output pipe to command
# "cmd|" : imput pipe from command
# "-" : stdin or stdout, depending on mode
# filename:filename
#
# mode is required for pipes, even though it can be inferred.
#
def open( f, mode ):
if f[0] == '|' :
return posix.popen( f[1:], mode )
elif f[-1] == '|' :
return posix.popen( f[:-1], mode )
elif f == '-' :
if mode == 'r' :
return sys.stdin
if mode == 'w' :
return sys.stdout
else:
return __builtin__.open( f, mode )

if __name__ == '__main__' :
for arg in sys.argv[1:]:
for line in open( arg, 'r' ).readlines():
print repr(arg)+':', line,

If executed as a command ( then modules __name__ == "__main__" ):

% ./myopen.py myopen.py - 'finger|' >out.tmp
a line or two typed in
from stdin.
^D

it produces this output:

'myopen.py': #!/usr/local/bin/python
'myopen.py': #
'myopen.py': import posix
'myopen.py': import __builtin__
'myopen.py': import sys
'myopen.py':
'myopen.py': #
[ ... cut ... ]
'myopen.py':
'myopen.py': if __name__ == '__main__' :
'myopen.py': for arg in sys.argv[1:]:
'myopen.py': for line in open( arg, 'r' ).readlines():
'myopen.py': print repr(arg)+':', line,
'myopen.py':
'-': a line or two typed in
'-': from stdin.
'finger|': Login Name TTY Idle When Site Info
'finger|': sdm7g Steven D. Majewski h0 1:07 Mon 10:01
'finger|': aps2n Dr. Andrew P. Somlyo p0 1:18 Mon 09:50
'finger|': aps2n Dr. Andrew P. Somlyo p1 39 Mon 10:05
'finger|': jwc7q John Chapman p3 1:22 Mon 09:13

[ Exercise suggested by trying the above:
How do you redefine file.readlines() method into a
file.prompt-if-file-is-stdin-readlines() method ?
( & can you do the same thing in Perl ? ) ]

>
> I saw the posix module pipe and system commands, but even after looking
> at my man pages, it wasn't clear to me how this can be done. Also, I
> hope that it is as easy to do as it is in Perl.
>

There is also 'pipes' module that does some neat stuff with building
templates for complicated pre/post processing pipes. ('Lib/pipes.py')
I have looked at it but haven't tried it.

- Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU>
- UVA Department of Molecular Physiology and Biological Physics