python中的Bash命令

python中的Bash命令,python,subprocess,Python,Subprocess,我正在用python运行一段代码,该代码计算目录中存在的文件数` hadoop fs -count /user/a909983/sample_data/ | awk '{print $2}' 这将在linux命令行中成功返回0,因为目录是空的。但是,当我在python脚本中运行它时,它将返回1。python中的代码行是: directoryEmptyStatusCommand = subprocess.call( ["hadoop", "fs", "-count", "/user/a90998

我正在用python运行一段代码,该代码计算目录中存在的文件数`

hadoop fs -count /user/a909983/sample_data/ | awk '{print $2}'
这将在linux命令行中成功返回0,因为目录是空的。但是,当我在python脚本中运行它时,它将返回1。python中的代码行是:

directoryEmptyStatusCommand = subprocess.call(
["hadoop", "fs", "-count", "/user/a909983/sample_data/", "|", "awk '{print $2}'"])

我怎样才能纠正这个问题?或者我错过了什么?。我也尝试过使用Popen,但结果是一样的。

使用
子流程。Popen
并且不要使用管道
|
,因为它需要
shell=True
这一安全风险。因此,使用
子流程管道
,并将其与
子流程一起使用。检查不带管道的输出
,这是正确的方法

因此,您可以尝试以下方法:

command = subprocess.Popen(("hadoop", "fs", "-count", "/user/a909983/sample_data/") , stdout=subprocess.PIPE)
output = subprocess.check_output(("awk '{print $2}'"), stdin=command.stdout)
如果您想通过启用
Shell=True
来尝试Shell命令:

cmd = "hadoop fs -count /user/a909983/sample_data/ | awk '{print $2}'"
command = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = command.communicate()[0]
print(output)

如果要使用shell的管道函数
|
,则需要将
shell=True
作为选项运行。在这种情况下,应该使用字符串,而不是命令列表。但是,最好将此命令分为两个子进程,分别用于
hadoop
awk
,然后通过Python管道传输数据。@tarun,请查看下面给出的答案,如果它有助于您接受作为答案,这样就可以将其从未接受的ans队列中删除。@pygo如果您只是删除您的答案会更好,因为它是重复的。如果文件名来自变量(可能是这样!),仅仅设置<代码> shell=true < /C>不是一个伟大的实践,如果不将内容从带解析的内容中移出作为代码。请考虑<代码>子进程。Popen([’'HADOOP FS -计数”$ 1”{ AWK“{打印2美元}”,“``,‘用户/A9099 83/SAMPLE数据DAT//’,shell=TRUE)< /代码>,保持您的数据-文件名-从代码中带出。@ CharlesDuffy,同意
shell=True
确实不推荐使用,因为它会打开一个安全漏洞,使程序容易受到shell注入的攻击,作为安全专家,您更了解它;-)好吧——我想说的是,如果作为
cmd
的第一个元素传递的字符串是一个由人仔细审核的常量,并且所有可能发生变化的元素都被排除在带外(并且没有对环境变量进行任何干预),那么就可以安全地使用
shell=True
。但是,是的,完全避免它确实是最好的方法