Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 运行包含管道的命令行并向标准输出显示结果_Python_Command Line_Pipe - Fatal编程技术网

Python 运行包含管道的命令行并向标准输出显示结果

Python 运行包含管道的命令行并向标准输出显示结果,python,command-line,pipe,Python,Command Line,Pipe,如何从包含管道的Python调用shell命令并捕获输出 假设命令类似于: cat file.log | tail -1 my $string = `cat file.log | tail -1`; 我正在尝试的Perl等价物如下所示: cat file.log | tail -1 my $string = `cat file.log | tail -1`; 这: 或者这应该有效: import os result = os.system("cat file.log | tail -1

如何从包含管道的Python调用shell命令并捕获输出

假设命令类似于:

cat file.log | tail -1
my $string = `cat file.log | tail -1`;
我正在尝试的Perl等价物如下所示:

cat file.log | tail -1
my $string = `cat file.log | tail -1`;
这:


或者这应该有效:

import os
result = os.system("cat file.log | tail -1")

使用subprocess.PIPE,如subprocess docs部分所述:

或者,使用,管道变为:

请注意,这不会捕获stderr。如果还想捕获stderr,则需要使用
task.communicate()
;如果stderr的缓冲区已满,则调用
task.stdout.read()
然后调用
task.stderr.read()
会导致死锁。如果希望将它们组合在一起,则应该能够在shell命令中使用
2>&1

但考虑到你的情况

task = subprocess.Popen(['tail', '-1', 'file.log'], stdout=subprocess.PIPE)
data = task.stdout.read()
assert task.wait() == 0

完全不需要管道。

另一种类似于Popen的方法是:

command=r"""cat file.log | tail -1 """
output=subprocess.check_output(command, shell=True)

这是来自@chown的叉子,有一些改进:

  • 导入子流程
    的别名使设置参数更容易
  • 如果只需要输出,则在调用
    Popen
  • 为了更好地格式化,建议对输出进行解码
  • shell=True
    是必要的,以便为命令行调用解释器



使用多个管道运行shell命令的简单函数

使用

res, err = eval_shell_cmd('pacman -Qii | grep MODIFIED | grep -v UN | cut -f 2')
功能

import subprocess


def eval_shell_cmd(command, debug=False):
    """
    Eval shell command with pipes and return result
    :param command: Shell command
    :param debug: Debug flag
    :return: Result string
    """
    processes = command.split(' | ')

    if debug:
        print('Processes:', processes)

    for index, value in enumerate(processes):
        args = value.split(' ')

        if debug:
            print(index, args)

        if index == 0:
            p = subprocess.Popen(args, stdout=subprocess.PIPE)
        else:
            p = subprocess.Popen(args, stdin=p.stdout, stdout=subprocess.PIPE)

        if index == len(processes) - 1:
            result, error = p.communicate()
            return result.decode('utf-8'), error

我可以找到第二个解决方案。尝试Python2.6.7的第一个解决方案时,我在Popen行上遇到了一个错误,打印的错误是“OSError:[Errno 2]没有这样的文件或目录”。不清楚发生这种情况的原因。请尝试使用
file.log
的绝对路径。或者,尝试
shell=True
shell=False
应该是
shell=True
设置shell=True修复了它。谢谢!我需要写一些类似subprocess.Popen(“ps aux | grep php | wc-l”,shell=True,stdout=subprocess.PIPE)的东西来解决我的问题。谢谢。比Perl的方式简洁得多。
#!/usr/bin/python3

import subprocess as sp

p = sp.Popen("cat app.log | grep guido", shell=True, stdout=sp.PIPE)

output = p.stdout.read()
print(output.decode('utf-8'))
$ cat app.log 
2017-10-14 22:34:12, User Removed [albert.wesker]
2017-10-26 18:14:02, User Removed [alexei.ivanovich] 
2017-10-28 12:14:56, User Created [ivan.leon]
2017-11-14 09:22:07, User Created [guido.rossum]

$ python3 subproc.py 
2017-11-14 09:22:07, User Created [guido.rossum]
res, err = eval_shell_cmd('pacman -Qii | grep MODIFIED | grep -v UN | cut -f 2')
import subprocess


def eval_shell_cmd(command, debug=False):
    """
    Eval shell command with pipes and return result
    :param command: Shell command
    :param debug: Debug flag
    :return: Result string
    """
    processes = command.split(' | ')

    if debug:
        print('Processes:', processes)

    for index, value in enumerate(processes):
        args = value.split(' ')

        if debug:
            print(index, args)

        if index == 0:
            p = subprocess.Popen(args, stdout=subprocess.PIPE)
        else:
            p = subprocess.Popen(args, stdin=p.stdout, stdout=subprocess.PIPE)

        if index == len(processes) - 1:
            result, error = p.communicate()
            return result.decode('utf-8'), error