I don't understand why IPython does not assign the result of some system command to python variables. This seems to constantly happen to me to the ack
and ag
executables
For example, the following command produces output:
In [1]: !ack --nocolor foo
bar
1:foo
However, whenever I save that result to a variable, I get an empty output
In [2]: out=!ack --nocolor foo
In [3]: out
Out[3]: []
I get this problem even when I try all sorts of hacks:
In [4]: out=!ack --nocolor foo > tmp; sleep 1; cat tmp
In [5]: out
Out[5]: []
In fact, tmp
is empty in the last case, which suggests that the output capture messes up with these commands.
Does anyone how if this is a problem with IPython or ack/ag, or simply my misunderstanding of how IPython should behave here?
I've deduced that
out = !cmd
uses%sx
. This is different from how!cmd
is run (see docs for%sw
and%system
).%sx
goes through several layers of functions, and ends up callingIts code is similar to the
subprocess
call that @Elliott Frisch uses in his deleted answer:I abstracted the
process_handler
code in:This works:
But if I uncomment the
stdin
line, it fails:So it's the
parameter that causes the
ack
call to fail. It doesn't cause problems with other common shell commands likels
orgrep
.ack
help has:Adding
--nofilter
to my commands (--nocolor
isn't needed with this redirection):So that's the key - force
ack
to ignore the piped input (though I don't fully understand the details).