getting properly one subprocess output

Discussion in 'Python' started by Jean-Michel Pichavant, Nov 18, 2009.

  1. Hi python fellows,

    I'm currently inspecting my Linux process list, trying to parse it in
    order to get one particular process (and kill it).
    I ran into an annoying issue:
    The stdout display is somehow truncated (maybe a terminal length issue,
    I don't know), breaking my parsing.

    import subprocess
    commandLine = ['ps', '-eo "%p %U %P %y %t %C %c %a"']
    process = subprocess.Popen(commandLine, stdout=subprocess.PIPE,
    stderr=subprocess.PIPE)
    processList, stderrdata = process.communicate()

    Here is a sample of what I get in processList.split('\n'):

    ' "25487 1122 4344 ? 7-17:48:32 2.5 firefox-bin
    /usr/lib/iceweasel/firefox-"',
    ' "25492 1122 4892 pts/6 00:08 57.2 ipython
    /usr/bin/python /usr/bin/ip"',


    As you can see, to complete process command line is truncated.
    Any clue on how to get the full version ?

    JM

    (python 2.5)
    Jean-Michel Pichavant, Nov 18, 2009
    #1
    1. Advertising

  2. Jean-Michel Pichavant

    Jon Clements Guest

    On Nov 18, 11:25 am, Jean-Michel Pichavant <>
    wrote:
    > Hi python fellows,
    >
    > I'm currently inspecting my Linux process list, trying to parse it in
    > order to get one particular process (and kill it).
    > I ran into an annoying issue:
    > The stdout display is somehow truncated (maybe a terminal length issue,
    > I don't know), breaking my parsing.
    >
    > import subprocess
    > commandLine = ['ps', '-eo "%p %U %P %y %t %C %c %a"']
    > process = subprocess.Popen(commandLine, stdout=subprocess.PIPE,
    > stderr=subprocess.PIPE)
    > processList, stderrdata = process.communicate()
    >
    > Here is a sample of what I get in processList.split('\n'):
    >
    >  ' "25487 1122      4344 ?         7-17:48:32  2.5 firefox-bin    
    > /usr/lib/iceweasel/firefox-"',
    >  ' "25492 1122      4892 pts/6          00:08 57.2 ipython        
    > /usr/bin/python /usr/bin/ip"',
    >
    > As you can see, to complete process command line is truncated.
    > Any clue on how to get the full version ?
    >
    > JM
    >
    > (python 2.5)


    What about "ps -eo pid,tty,cmd" ?

    Sample:
    12680 ? geany /usr/share/gramps/ReportBase/
    _CommandLineReport.py
    12682 ? gnome-pty-helper
    12683 pts/0 /bin/bash
    13038 ? gnome-terminal
    13039 ? gnome-pty-helper
    13040 pts/1 bash
    13755 pts/1 ps -eo pid,tty,cmd

    ....etc...


    hth,

    Jon.
    Jon Clements, Nov 18, 2009
    #2
    1. Advertising

  3. Jean-Michel Pichavant

    Jon Clements Guest

    On Nov 18, 4:14 pm, Jon Clements <> wrote:
    > On Nov 18, 11:25 am, Jean-Michel Pichavant <>
    > wrote:
    >
    >
    >
    > > Hi python fellows,

    >
    > > I'm currently inspecting my Linux process list, trying to parse it in
    > > order to get one particular process (and kill it).
    > > I ran into an annoying issue:
    > > The stdout display is somehow truncated (maybe a terminal length issue,
    > > I don't know), breaking my parsing.

    >
    > > import subprocess
    > > commandLine = ['ps', '-eo "%p %U %P %y %t %C %c %a"']
    > > process = subprocess.Popen(commandLine, stdout=subprocess.PIPE,
    > > stderr=subprocess.PIPE)
    > > processList, stderrdata = process.communicate()

    >
    > > Here is a sample of what I get in processList.split('\n'):

    >
    > >  ' "25487 1122      4344 ?         7-17:48:32  2.5 firefox-bin    
    > > /usr/lib/iceweasel/firefox-"',
    > >  ' "25492 1122      4892 pts/6          00:08 57.2 ipython        
    > > /usr/bin/python /usr/bin/ip"',

    >
    > > As you can see, to complete process command line is truncated.
    > > Any clue on how to get the full version ?

    >
    > > JM

    >
    > > (python 2.5)

    >
    > What about "ps -eo pid,tty,cmd" ?
    >
    > Sample:
    > 12680 ?        geany /usr/share/gramps/ReportBase/
    > _CommandLineReport.py
    > 12682 ?        gnome-pty-helper
    > 12683 pts/0    /bin/bash
    > 13038 ?        gnome-terminal
    > 13039 ?        gnome-pty-helper
    > 13040 pts/1    bash
    > 13755 pts/1    ps -eo pid,tty,cmd
    >
    > ...etc...
    >
    > hth,
    >
    > Jon.


    Another thought: if you're only wanting to find and kill a process,
    what about pkill? Saves you having to filter the list in Python and
    then issue a kill command.

    Jon.
    Jon Clements, Nov 18, 2009
    #3
  4. Jean-Michel Pichavant

    Nobody Guest

    On Wed, 18 Nov 2009 12:25:14 +0100, Jean-Michel Pichavant wrote:

    > I'm currently inspecting my Linux process list, trying to parse it in
    > order to get one particular process (and kill it).
    > I ran into an annoying issue:
    > The stdout display is somehow truncated (maybe a terminal length issue,
    > I don't know), breaking my parsing.


    > As you can see, to complete process command line is truncated.
    > Any clue on how to get the full version ?


    If you only need it to work on Linux, you can just enumerate
    /proc/[1-9]*/exe or /proc/[1-9]*/cmdline.

    Or you can add -ww to "ps" to avoid truncating the output.

    Note that the /proc/*/exe report the actual executable. The command line
    reported by "ps" (from /proc/*/cmdline) can be modified by the program, so
    it doesn't necessarily reflect the program being run.
    Nobody, Nov 18, 2009
    #4
  5. Nobody wrote:
    > On Wed, 18 Nov 2009 12:25:14 +0100, Jean-Michel Pichavant wrote:
    >
    >
    >> I'm currently inspecting my Linux process list, trying to parse it in
    >> order to get one particular process (and kill it).
    >> I ran into an annoying issue:
    >> The stdout display is somehow truncated (maybe a terminal length issue,
    >> I don't know), breaking my parsing.
    >>

    >
    >
    >> As you can see, to complete process command line is truncated.
    >> Any clue on how to get the full version ?
    >>

    >
    > If you only need it to work on Linux, you can just enumerate
    > /proc/[1-9]*/exe or /proc/[1-9]*/cmdline.
    >
    > Or you can add -ww to "ps" to avoid truncating the output.
    >
    > Note that the /proc/*/exe report the actual executable. The command line
    > reported by "ps" (from /proc/*/cmdline) can be modified by the program, so
    > it doesn't necessarily reflect the program being run.
    >
    >
    >

    That is what I was searching for. It's in ps man page, I don't know why
    I missed it in the first place.
    Thanks.

    JM
    Jean-Michel Pichavant, Nov 19, 2009
    #5
  6. Jean-Michel Pichavant

    Bas Guest

    On Nov 18, 12:25 pm, Jean-Michel Pichavant <>
    wrote:
    > Hi python fellows,
    >
    > I'm currently inspecting my Linux process list, trying to parse it in
    > order to get one particular process (and kill it).
    > I ran into an annoying issue:
    > The stdout display is somehow truncated (maybe a terminal length issue,
    > I don't know), breaking my parsing.


    Below is the script I use to automatically kill firefox if it is not
    behaving, maybe you are looking for something similar.

    HTH,
    Bas


    #!/usr/bin/env python

    import commands, os
    lines = os.popen('ps ax|grep firefox').readlines()
    lines = [line for line in lines if 'grep' not in line]
    print lines[0]
    pid = int(lines[0][:5])
    print 'Found pid: %d' %pid
    os.system('kill -9 %d' %pid)
    Bas, Nov 19, 2009
    #6
  7. Jean-Michel Pichavant

    Paul Rudin Guest

    Jean-Michel Pichavant <> writes:

    > Hi python fellows,
    >
    > I'm currently inspecting my Linux process list, trying to parse it in
    > order to get one particular process (and kill it).
    > I ran into an annoying issue:
    > The stdout display is somehow truncated (maybe a terminal length
    > issue, I don't know), breaking my parsing.
    >
    > import subprocess
    > commandLine = ['ps', '-eo "%p %U %P %y %t %C %c %a"']
    > process = subprocess.Popen(commandLine, stdout=subprocess.PIPE,
    > stderr=subprocess.PIPE)
    > processList, stderrdata = process.communicate()
    >
    > Here is a sample of what I get in processList.split('\n'):
    >
    > ' "25487 1122 4344 ? 7-17:48:32 2.5 firefox-bin
    > /usr/lib/iceweasel/firefox-"',
    > ' "25492 1122 4892 pts/6 00:08 57.2 ipython
    > /usr/bin/python /usr/bin/ip"',
    >
    >
    > As you can see, to complete process command line is truncated.
    > Any clue on how to get the full version ?
    >


    You need to pass -ww to ps, otherwise it tries to guess the width of
    your terminal and adjust output line lengths accordingly.
    Paul Rudin, Nov 19, 2009
    #7
  8. Jean-Michel Pichavant

    Nobody Guest

    On Thu, 19 Nov 2009 06:21:09 -0800, Bas wrote:

    > Below is the script I use to automatically kill firefox if it is not
    > behaving, maybe you are looking for something similar.


    > lines = os.popen('ps ax|grep firefox').readlines()


    This isn't robust. It will kill any process with "firefox" anywhere in its
    command line, which isn't limited to processes which are actually running
    the firefox web browser.

    > lines = [line for line in lines if 'grep' not in line]


    This line excludes one such process, but there may be others.

    A more robust approach would be to check for the string in the command
    name (i.e. argv[0]) rather than the complete command-line, by using e.g.
    "ps ... -o pid,comm":

    lines = os.popen('ps axheo pid,comm').readlines()
    lines = [line.strip().split(' ', 1) for line in lines]
    lines = [(int(pid), cmd) for pid, cmd in lines if 'firefox' in cmd]

    Better still would be to check that "firefox" is a complete word, not part
    of one, e.g. with the regular expression r"\bfirefox\b". This would match
    "firefox", "/usr/bin/firefox", "firefox-bin", etc, but not e.g.
    "kill_firefox", e.g.:

    lines = [(int(pid), cmd) for pid, cmd in lines if re.search(r'\bfirefox\b', cmd)]

    That's about as good as you can get without using non-portable mechanisms
    such as /proc/*/exe.
    Nobody, Nov 19, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Joe Flynt
    Replies:
    5
    Views:
    695
    Dennis Lee Bieber
    Nov 9, 2003
  2. David
    Replies:
    0
    Views:
    975
    David
    Apr 15, 2008
  3. Nick Stinemates
    Replies:
    0
    Views:
    399
    Nick Stinemates
    Apr 18, 2008
  4. hiral
    Replies:
    2
    Views:
    583
    Jean-Michel Pichavant
    May 5, 2010
  5. Hunt Jon
    Replies:
    2
    Views:
    98
    Phlip
    Dec 18, 2008
Loading...

Share This Page