python中的Bash命令
我正在用python运行一段代码,该代码计算目录中存在的文件数`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
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
。但是,是的,完全避免它确实是最好的方法