为什么我在执行此命令时会获得文件列表?
subprocess.check_call("time ls &>/dev/null", shell=True)
如果我要粘贴
time ls &>/dev/null
进入控制台,我会得到时间。
操作系统是Linux Ubuntu。
答案 0 :(得分:0)
在类似debian的系统上,默认shell为dash
,而不是bash
。 Dash
不支持&>
快捷方式。要仅获取子进程返回代码,请尝试:
subprocess.check_call("time ls >/dev/null 2>&1", shell=True)
要获取子流程返回代码和时间信息而不是目录列表,请使用:
subprocess.check_call("time ls >/dev/null", shell=True)
当然,减去子进程返回代码,这与您在dash
命令提示符下看到的行为相同。
答案 1 :(得分:0)
Python版本在sh
下运行,但控制台版本在您的默认shell中运行,可能是bash
或dash
。 (您的sh
实际上可能是在POSIX兼容模式下运行的不同shell,但这并没有任何区别。)
bash
和dash
都有内置time
个功能,但sh
没有,所以你得到/usr/bin/time
,这是一个正常的程序。最重要的区别是time
内置函数不是作为具有自己的独立stdout和stderr的子进程运行。
此外,sh
,bash
和dash
都有不同的重定向语法。
但是你首先想要做的事情似乎是错误的,而且你在控制台上获得了幸运,因为两个错误正在取消。
你想摆脱ls
的标准输出但是保持time
的标准,但那不是你要求的。您正在尝试重定向stdout和stderr:>&
在实际支持它的任何shell上的含义。
那你为什么还得到time
stderr? (a)您的默认shell不支持>&
,或者(b)您使用内置而不是程序,并且您没有重定向shell本身的stderr ,或者(c)以上两者。
如果你真的想在Python中做同样的事情,完全相同的错误以完全相同的方式取消,你可以手动运行你的默认shell而不是shell=True
。根据它的工作原因,可能是:
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而不是stderr,请写下:
subprocess.check_call('time ls > /dev/null', shell=True)
或者,更好的是,你为什么甚至首先使用shell?
subprocess.check_call(['time', 'ls'], stdout=subprocess.devnull)