Output from subprocess.Popen

后端 未结 3 415
耶瑟儿~
耶瑟儿~ 2021-01-18 23:46

I\'ve been writing some python code and in my code I was using \"command\"

The code was working as I intended but then I noticed in the Python docs that command has

相关标签:
3条回答
  • 2021-01-19 00:31

    The variable output does not contain a string, it is a container for the subprocess.Popen() function. You don't need to print it. The code,

    import subprocess
    output = subprocess.Popen("ls -al", shell=True)
    

    works perfectly, but without the ugly : <subprocess.Popen object at 0xb734b26c> being printed.

    0 讨论(0)
  • 2021-01-19 00:38

    The "ugly string" is what it should be printing. Python is correctly printing out the repr(subprocess.Popen(...)), just like what it would print if you said print(open('myfile.txt')).

    Furthermore, python has no knowledge of what is being output to stdout. The output you are seeing is not from python, but from the process's stdout and stderr being redirected to your terminal as spam, that is not even going through the python process. It's like you ran a program someprogram & without redirecting its stdout and stderr to /dev/null, and then tried to run another command, but you'd occasionally see spam from the program. To repeat and clarify:

    <subprocess.Popen object at 0xb734b26c>  <-- output of python program
    brettg@underworld:~/dev$ total 52                     <-- spam from your shell, not from python
    drwxr-xr-x  3 brettg brettg 4096 2011-05-27 12:38 .   <-- spam from your shell, not from python
    drwxr-xr-x 21 brettg brettg 4096 2011-05-24 17:40 ..  <-- spam from your shell, not from python
    ...
    

    In order to capture stdout, you must use the .communicate() function, like so:

    #!/usr/bin/python
    import subprocess
    output = subprocess.Popen(["ls", "-a", "-l"], stdout=subprocess.PIPE).communicate()[0]
    print output
    

    Furthermore, you never want to use shell=True, as it is a security hole (a major security hole with unsanitized inputs, a minor one with no input because it allows local attacks by modifying the shell environment). For security reasons and also to avoid bugs, you generally want to pass in a list rather than a string. If you're lazy you can do "ls -al".split(), which is frowned upon, but it would be a security hole to do something like ("ls -l %s"%unsanitizedInput).split().

    0 讨论(0)
  • 2021-01-19 00:51

    See the subprocess module documentation for more information.

    Here is how to get stdout and stderr from a program using the subprocess module:

    from subprocess import Popen, PIPE, STDOUT
    
    cmd = 'echo Hello World'
    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
    output = p.stdout.read()
    print output
    

    results:

    b'Hello\r\n'
    

    you can run commands with PowerShell and see results:

    from subprocess import Popen, PIPE, STDOUT
    cmd = 'powershell.exe ls'
    p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
    output = p.stdout.read()
    

    useful link

    0 讨论(0)
提交回复
热议问题