0

[EDIT] as asked here is what ps does for me :

   PID TTY          TIME CMD
  3796 pts/0    00:00:00 bash
  4811 pts/0    00:00:00 ps

I'm beginning with Graphviz and I would like to display the name of the running process. I got a script that display their number and I'm trying to add a label to each node.

The problem is that only the last write label is displayed to the root node, how can I manage to write a label to every node ?

#!/usr/bin/env python3

from subprocess import Popen, PIPE, call
import re

dot = open("psgraph.dot", "w")
dot.write("digraph G {\n")

p = Popen("ps -fe", shell=True, stdout=PIPE)
psre = re.compile(r"\w+\s+(\d+)\s+(\d+)")

p.stdout.readline() # ignore first line
for line in p.stdout:
    match = psre.search(line.decode("utf-8"))
    if match:
        if int(match.group(2)) in (0, 2):
            continue
        dot.write ("  {1} -> {0}\n".format(match.group(1), match.group(2)))

for line in p.stdout:
    match = psre.search(line.decode("utf-8"))
    if match:
        if int(match.group(2)) in (0, 2):
            continue
        dot.write ("""1 [label="loop"]\n""")

dot.write("""1 [label="laste write"]}\n""")
dot.close()

call("dot -Tpdf -O psgraph.dot", shell=True)
J.erome
  • 688
  • 7
  • 26
  • You can easily get rid of both of the `shell=True` instances; `Popen(['ps', '-fe'], stdout=PIPE)` and `call(['dot', '-Tpdf', '-O', 'psgraph.dot'])`. See also https://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess – tripleee Dec 04 '19 at 10:36
  • @tripleee check the edit for the sample and thanks for the link – J.erome Dec 04 '19 at 10:38
  • So your regex is extracting the PID and the TTY? And the second loop is supposed to extract something more from each line but you don't know how to create a regex for that? – tripleee Dec 04 '19 at 10:39
  • @tripleee yes I would like to display the `CMD` in the graphviz node instead of the `PID` – J.erome Dec 04 '19 at 10:42
  • And your question isn't actually related to how to do this in Graphviz at all, you just need help with the Python regex? – tripleee Dec 04 '19 at 10:42
  • It's also related to graphviz since I'm trying to display that in Graphviz – J.erome Dec 04 '19 at 10:48

1 Answers1

1

I guess something like this:

# Update RE to capture command, too
psre = re.compile(r"\w+\s+(\d+)\s+(\d+)\s+\d+:\d+:\d+\s(\w+)")

# Collect labels
cmds = []
p.stdout.readline() # ignore first line
for line in p.stdout:
    match = psre.search(line.decode("utf-8"))
    if match:
        if int(match.group(2)) in (0, 2):
            continue
        dot.write ("  {1} -> {0}\n".format(match.group(1), match.group(2)))
        cmds.append((match.group(2), match.group(3)),)

for cmd, label in cmds:
    dot.write ("""{0} [label="{1}"]\n""".format(cmd, label))

I'm obviously speculating about what exactly you want to write in the second loop, or indeed whether it's even necessary or useful to write all the nodes before all the labels. If you can update the question with what exactly you want here, I imagine it shouldn't be hard.

tripleee
  • 175,061
  • 34
  • 275
  • 318