In xonsh how can I receive from a pipe to a python expression?
Question:
In the xonsh
shell how can I receive from a pipe to a python expression? Example with a find
command as pipe provider:
find $WORKON_HOME -name pyvenv.cfg -print | for p in <stdin>: $(ls -dl @(p))
The for p in <stdin>:
is obviously pseudo code. What do I have to replace it with?
Note: In bash I would use a construct like this:
... | while read p; do ... done
Answers:
The easiest way to pipe input into a Python expression is to use a function that is a callable alias, which happens to accept a stdin file-like object. For example,
def func(args, stdin=None):
for line in stdin:
ls -dl @(line.strip())
find $WORKON_HOME -name pyvenv.cfg -print | @(func)
Of course you could skip the @(func)
by putting func in aliases
,
aliases['myls'] = func
find $WORKON_HOME -name pyvenv.cfg -print | myls
Or if all you wanted to do was iterate over the output of find
, you don’t even need to pipe.
for line in !(find $WORKON_HOME -name pyvenv.cfg -print):
ls -dl @(line.strip())
Drawing on the answer from Anthony Scopatz you can do this on one line with a callable alias as a lambda. The function takes the third form, def mycmd2(args, stdin=None)
. I discarded args
with _
because I don’t need it and shortened stdin
to s
for convenience. Here is a command to hash a file:
type image.qcow2 | @(lambda _,s: hashlib.sha256(s.read()).hexdigest())
In the xonsh
shell how can I receive from a pipe to a python expression? Example with a find
command as pipe provider:
find $WORKON_HOME -name pyvenv.cfg -print | for p in <stdin>: $(ls -dl @(p))
The for p in <stdin>:
is obviously pseudo code. What do I have to replace it with?
Note: In bash I would use a construct like this:
... | while read p; do ... done
The easiest way to pipe input into a Python expression is to use a function that is a callable alias, which happens to accept a stdin file-like object. For example,
def func(args, stdin=None):
for line in stdin:
ls -dl @(line.strip())
find $WORKON_HOME -name pyvenv.cfg -print | @(func)
Of course you could skip the @(func)
by putting func in aliases
,
aliases['myls'] = func
find $WORKON_HOME -name pyvenv.cfg -print | myls
Or if all you wanted to do was iterate over the output of find
, you don’t even need to pipe.
for line in !(find $WORKON_HOME -name pyvenv.cfg -print):
ls -dl @(line.strip())
Drawing on the answer from Anthony Scopatz you can do this on one line with a callable alias as a lambda. The function takes the third form, def mycmd2(args, stdin=None)
. I discarded args
with _
because I don’t need it and shortened stdin
to s
for convenience. Here is a command to hash a file:
type image.qcow2 | @(lambda _,s: hashlib.sha256(s.read()).hexdigest())