【问题标题】:Large command in Python using subprocessPython中使用子进程的大型命令
【发布时间】:2014-03-01 15:05:50
【问题描述】:

如何使用 subprocess 模块运行此代码?

commands.getoutput('sudo blkid | grep 'uuid' | cut -d " " -f 1 | tr -d ":"')

我已经试过了,但它根本不起作用

out_1 = subprocess.Popen(('sudo', 'blkid'), stdout=subprocess.PIPE)
out_2 = subprocess.Popen(('grep', 'uuid'), stdin=out_1.stdout, stdout=subprocess.PIPE)
out_3 = subprocess.Popen(('cut', '-d', '" "', '-f', '1'), stdin=out_2.stdout, stdout=subprocess.PIPE)
main_command = subprocess.check_output(('tr', '-d', '":"'), stdin=out_3.stdout)

main_command

错误:剪切:分隔符必须是单个字符

【问题讨论】:

  • 它有什么作用 - 你有错误信息要发布
  • 错误:剪切:分隔符必须是单个字符
  • 你知道grep 'uuid' | cut -d " " -f 1 | tr -d ":"可以用一个命令代替吗:awk '/uuid/{print gsub(":", "", $1)}'
  • 我试过了,但输出完全不同:虽然 grep 显示 /dev/sda1,但 awk 只执行 1

标签: python command subprocess


【解决方案1】:
from subprocess import check_output, STDOUT

shell_command = '''sudo blkid | grep 'uuid' | cut -d " " -f 1 | tr -d ":"'''
output = check_output(shell_command, shell=True, stderr=STDOUT,
                      universal_newlines=True).rstrip('\n')

顺便说一句,除非使用grep -i,否则它不会在我的系统上返回任何内容。在后一种情况下,它返回设备。如果这是您的意图,那么您可以使用不同的命令:

from subprocess import check_output

devices = check_output(['sudo', 'blkid', '-odevice']).split()

我正在尝试不使用 shell=True

如果您控制命令,即如果您不使用用户输入来构造命令,则可以使用shell=True。将 shell 命令视为一种允许您简洁地表达您的意图的特殊语言(例如用于字符串处理的正则表达式)。比不使用 shell 的几行代码更具可读性:

from subprocess import Popen, PIPE

blkid = Popen(['sudo', 'blkid'], stdout=PIPE)
grep = Popen(['grep', 'uuid'], stdin=blkid.stdout, stdout=PIPE)
blkid.stdout.close() # allow blkid to receive SIGPIPE if grep exits
cut = Popen(['cut', '-d', ' ', '-f', '1'], stdin=grep.stdout, stdout=PIPE)
grep.stdout.close()
tr = Popen(['tr', '-d', ':'], stdin=cut.stdout, stdout=PIPE,
           universal_newlines=True)
cut.stdout.close()
output = tr.communicate()[0].rstrip('\n')
pipestatus = [cmd.wait() for cmd in [blkid, grep, cut, tr]]

注意:这里的引号内没有引号(没有'" "''":"')。也不同于前面的命令和commands.getoutput(),它不捕获标准错误。

plumbum 提供了一些语法糖:

from plumbum.cmd import sudo, grep, cut, tr

pipeline = sudo['blkid'] | grep['uuid'] | cut['-d', ' ', '-f', '1'] | tr['-d', ':']
output = pipeline().rstrip('\n') # execute

How do I use subprocess.Popen to connect multiple processes by pipes?

【讨论】:

    【解决方案2】:

    将您的命令作为一个字符串传递,如下所示:

    main_command = subprocess.check_output('tr -d ":"', stdin=out_3.stdout)
    

    如果您有多个命令,并且要一个一个执行,请将它们作为列表传递:

    main_command = subprocess.check_output([comand1, command2, etc..], shell=True)
    

    【讨论】:

    • 我试图不使用 shell=True
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 2020-07-25
    • 2018-05-08
    • 2016-03-12
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多