Error is being raised when executing a sub-process

2019-09-09 03:09发布

问题:

I am trying to automate the process of executing a command. When I this command:

ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10

Into a termianl I get the response:

%CPU   PID USER     COMMAND
 5.7 25378 stackusr whttp
 4.8 25656 stackusr tcpproxy

But when I execute this section of code I get an error regarding the format specifier:

  if __name__ == '__main__':
        fullcmd = ['ps','-eo','pcpu,pid,user,args | sort -k 1 -r | head -10']
        print fullcmd
        sshcmd = subprocess.Popen(fullcmd,
                    shell= False,
                    stdout= subprocess.PIPE,
                    stderr= subprocess.STDOUT)
        out = sshcmd.communicate()[0].split('\n')
        #print 'here'
        for lin in out:
            print lin

This is the error showen:

ERROR: Unknown user-defined format specifier "|".
********* simple selection *********  ********* selection by list *********
-A all processes                      -C by command name
-N negate selection                   -G by real group ID (supports names)
-a all w/ tty except session leaders  -U by real user ID (supports names)
-d all except session leaders         -g by session OR by effective group name
-e all processes                      -p by process ID
T  all processes on this terminal     -s processes in the sessions given
a  all w/ tty, including other users  -t by tty
g  OBSOLETE -- DO NOT USE             -u by effective user ID (supports names)
r  only running processes             U  processes for specified users
x  processes w/o controlling ttys     t  by tty

I have tryed placing a \ before the | but this has not effect.

回答1:

You would need to use shell=True to use the pipe character, if you are going to go down that route then using check_output would be the simplest approach to get the output:

from subprocess import check_output

out = check_output("ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10",shell=True,stderr=STDOUT)

You can also simulate a pipe with Popen and shell=False, something like:

from subprocess import Popen, PIPE, STDOUT
sshcmd = Popen(['ps', '-eo', "pcpu,pid,user,args"],
               stdout=PIPE,
               stderr=STDOUT)
p2 = Popen(["sort", "-k", "1", "-r"], stdin=sshcmd.stdout, stdout=PIPE)
sshcmd.stdout.close()
p3 = Popen(["head", "-10"], stdin=p2.stdout, stdout=PIPE,stderr=STDOUT)
p2.stdout.close()
out, err = p3.communicate()