2014-09-04 67 views
1

为什么在执行此命令时获取文件列表?Python,subprocess.check_call()和管道重定向

subprocess.check_call("time ls &>/dev/null", shell=True) 

如果我将粘贴

time ls &>/dev/null 

到控制台,我将刚才得到的时机。 操作系统是Linux的Ubuntu。

+1

您是否试过[this](http://stackoverflow.com/a/21003633/1189040)? – Himal 2014-09-04 01:39:23

+0

为什么你在这里首先使用'shell = True'? – abarnert 2014-09-04 01:47:36

+0

Himal - 添加“executable ='/ bin/bash'”修复了我的问题,谢谢:) – gumol 2014-09-04 17:38:57

回答

0

在类似debian的系统上,默认shell是dash,而不是bashDash不支持&>快捷方式。为了得到只有子返回代码,请尝试:

subprocess.check_call("time ls >/dev/null 2>&1", shell=True) 

要获得子返回代码和定时信息,但不能目录列表,使用:

subprocess.check_call("time ls >/dev/null", shell=True) 

负,当然,子进程返回码,这与您在dash命令提示符中看到的行为相同。

0

Python版本正在sh下运行,但控制台版本在任何默认外壳程序中运行,可能是bashdash。 (您sh实际上可能是在POSIX兼容的模式不同的shell中运行,但这并没有什么差别。)

两个bashdash已经内置time功能,但sh没有,所以你得到/usr/bin/time,这是一个正常的程序。这个最重要的区别是time内建函数没有作为一个具有独立stdout和stderr的子进程运行。

而且,shbashdash都具有不同的重定向语法。


但是,你想要做的似乎是错误的,首先,你只是在控制台上运气好,因为两个错误都取消了。

你想摆脱ls的stdout,但保持time的stderr,但这不是你要求的。你正试图重定向stdout和stderr:这就是在任何实际支持它的shell上的意思。

那么为什么你仍然得到time stderr? (a)您的默认shell不支持>&,或者(b)您使用的是内置代替程序,并且您没有重定向shell本身的stderr,或者(c)上述两者。


如果你真的想这样做同样的事情在Python,具有完全相同的错误在完全相同的方式抵消,你可以手动运行,而不是使用shell=True默认的shell。根据这个原因,这是工作,这将是这两种:

subprocess.check_call([os.environ['SHELL'], '-c', 'time ls &> /dev/null']) 

或本:

subprocess.check_call('{} -c time ls &> /dev/null'.format(os.environ(SHELL), shell=True) 

不过说真的,你为什么都这样做呢?如果你想将stdout,而不是标准错误,写:

subprocess.check_call('time ls > /dev/null', shell=True) 

或者,更好的,干嘛还要用贝壳摆在首位?

subprocess.check_call(['time', 'ls'], stdout=subprocess.devnull) 
+0

ls只是一个例子,我正在计算一个应用程序,在stdout和stderr上产生负载输出,有时我想看stderr,但通常不是。很显然,我希望看到时机,这就是现在正在发生的事情。基本上我的命令看起来像“time taskset mpirun ./app”,我想放弃./app的输出(无论如何,taskset和mpirun都很沉默)。无论如何,感谢让我意识到时间不在身边,我会明天尝试你的解决方案。 – gumol 2014-09-04 04:39:18