IPython的不会捕获一些命令的输出(例如,ACK)(IPython won't capt

2019-10-29 01:34发布

我不明白为什么IPython的不分配一些系统命令蟒蛇变量的结果。 这似乎不断地发生在我身上的ackag的可执行文件

例如,下面的命令产生输出:

In [1]: !ack --nocolor foo
bar
1:foo

但是,每当我该结果保存到变量中,我得到一个空输出

In [2]: out=!ack --nocolor foo

In [3]: out
Out[3]: []

甚至当我尝试了各种黑客攻击,我得到这个问题:

In [4]: out=!ack --nocolor foo > tmp; sleep 1; cat tmp

In [5]: out
Out[5]: []

事实上, tmp是后一种情况,这表明输出捕获这些命令的食堂了空。

有谁如何,如果这是与IPython中或ACK / AG的一个问题,或者只是我的IPython中应该如何表现这里的误解?

Answer 1:

我推断out = !cmd使用%sx 。 这是多么不同的!cmd运行(见文档%sw%system )。

%sx经过的功能的若干层,并且结束调用

# import IPython
IPython.utils._process_common.process_handler

它的代码是类似于subprocess是@Elliott弗里施用在他删除应答呼叫:

p = subprocess.Popen("ack --nocolor foo", stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()

我抽象出process_handler代码:

def cmd1(astr='ack --nocolor 15 *.txt'):
    callback = lambda p: p.communicate()
    stderr = subprocess.PIPE
    stderr = subprocess.STDOUT
    shell = True
    close_fds = True
    executable = None
    p = subprocess.Popen(astr, 
                         shell=shell,
                         executable=executable,
                         #stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=stderr,
                         close_fds=close_fds,
                         )
    out = callback(p)
    return out, p.returncode

这工作:

In [40]: cmd1()
Out[40]: 
((b'stack53269737.txt:2:11 12 13 14 15 16\ntest.txt:3:11\t12 13 14 15\ntest1.txt:5:  0.054181,  0.506962,  0.315159,  0.653104\n',
  None),
 0)

但是,如果我去掉了stdin线,它失败:

In [42]: cmd1()
Out[42]: ((b'', None), 1)

因此,它的

stdin=subprocess.PIPE,

参数引起ack调用失败。 它不会导致像其他常见的shell命令的问题lsgrep


ack帮助有:

 --[no]filter               Force ack to treat standard input as a pipe
                            (--filter) or tty (--nofilter)

添加--nofilter我的命令( --nocolor不需要用这种重定向):

In [50]: cmd1('ack --nofilter 15 *.txt')
Out[50]: 
((b'stack53269737.txt:2:11 12 13 14 15 16\ntest.txt:3:11\t12 13 14 15\ntest1.txt:5:  0.054181,  0.506962,  0.315159,  0.653104\n',
  None),
 0)

In [51]: out = !ack --nofilter 15 *.txt
In [52]: out
Out[52]: 
['stack53269737.txt:2:11 12 13 14 15 16',
 'test1.txt:5:  0.054181,  0.506962,  0.315159,  0.653104',
 'test.txt:3:11\t12 13 14 15']

所以这是关键的-力ack忽略管道输入(虽然我不完全了解细节)。



文章来源: IPython won't capture some command outputs (e.g., ack)
标签: shell ipython