如何在子进程python中使用linux命令

时间:2017-09-10 23:35:50

标签: python linux unix subprocess

我有如下命令的linux命令:

 find /data/*/hr/ -printf "%f: %p: %u: %g %m (%M) \n"

我如何在python子进程中使用check_output

我尝试过如下但不能正常工作

 file_name = "/data/*/%s/" % (filename)
 get_perm = check_output(["find", file_name, "-printf", '\"%f: %p: %u: %g %m (%M) \n\"'])

我收到错误:

find: ‘/data/*/hr/’: No such file or directory
Traceback (most recent call last):
  File "handover.py", line 90, in <module>
    get_perm = check_output(["find", file_name, "-printf", '\"%f: %p: %u: %g %m (%M) \n\"'])
  File "/usr/lib64/python2.7/subprocess.py", line 573, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['find', '/data/*/hr/', '-printf', '"%f: %p: %u: %g %m (%M) \n"']' returned non-zero exit status 1

3 个答案:

答案 0 :(得分:1)

最后,

我在下面找到了方法

cmd = "find /data/*/{}/* -printf \"%f:%p:%u:%g:%m\n\"".format(filename)
info = subprocess.Popen(cmd,stdout=subprocess.PIPE,shell=True)
print info.stdout.read()

这解决了我的问题

答案 1 :(得分:0)

您收到此错误,因为指定的文件不存在。如果直接在shell中运行命令,则会得到相同的响应。

例如,以下工作正常:

import subprocess
import os

file_name = os.path.join(os.getcwd(), 'test.txt')
with open(file_name, 'w') as f:
    f.write('hello world')

get_perm = subprocess.check_output([
    "find",
     file_name,
     "-printf",
    '"%f: %p: %u: %g %m (%M) \n"'
    ], shell=True)

print(get_perm)
os.remove(file_name)

根据docs

  

如果返回代码[来自subprocess.check_output]非零,则会引发CalledProcessError。 CalledProcessError对象将在returncode属性中包含返回代码,并在输出属性中包含任何输出。

我建议你在try..except中包装你的check_output调用,并捕获CalledProcessError。

或者,如果您真的不想处理异常,则可以执行命令:

x=$(find ~/data/*/hr/ -printf "%f: %p: %u: %g %m (%M) \n" 2>/dev/null || true) && echo $x

这将永远不会返回非零值,并且只有在文件存在时才会包含输出。

修改 正如迈克尔指出的那样,“*”并没有得到扩展。但是,如果您设置shell=True,它会。尝试按如下方式修改命令:

 file_name = "/data/*/%s/" % (filename)
 get_perm = check_output(["find", file_name, "-printf", '"%f: %p: %u: %g %m (%M) \n"'], shell=True)

答案 2 :(得分:0)

当您在命令行上调用时,您的shell将展开*中的/data/*/hr/。通过check_output直接调用函数会导致find在字面上查找目录/data/*/hr/。在传递给glob之前,您可以使用find模块展开路径:

import glob

file_name = "/data/*/%s/" % (filename)
get_perm = check_output(["find"] + glob.glob(file_name) + ["-printf", '\"%f: %p: %u: %g %m (%M) \n\"'])

glob.glob只是通过扩展任何*和其他一些特殊字符,生成一个与给定表达式匹配的路径名数组。