How do I run “dot” as a command from Python?

耗尽温柔 提交于 2019-12-12 11:05:01

问题


I am using Python on Mac OSX Leopard.

I am trying to run the program 'dot' (part of Graphviz) from Python:

# -*- coding: utf-8 -*-
import os

print os.environ['PATH']
print os.system("ls >> a.txt")
print os.system("dot -o9.png -Tpng ./6.dot")

The command "ls" is there just to make sure that python is in the correct directory. It is. The result that I get is:

/usr/bin:/bin:/usr/sbin:/sbin 0 32512

My understanding is that 32512 error means that python could not find the file, and since the file 6.dot is there (If I run "dot -o9.png -Tpng ./6.dot" from the terminal I receive no error, and 9.png gets produced), I assume Python can't find the dot file.

I probably need to add the dot file to the path. But I don't know where is it. If I run:

whereis dot

I receive no answer.

How can I find the dot executable?
Alternatively, can I run the dot program as a command from inside Python?


回答1:


You should change the PATH line so it includes the directory which contains dot. That directory is /usr/local/bin, without /dot.




回答2:


whereis locates man pages, which locates binaries. So try which dot.




回答3:


You need to add the path to the 'dot' executable in Python's environment. You can do this by modifying the PATH variable in os.environ




回答4:


Try this:

# -*- coding: utf-8 -*-
import os
import sys

print os.environ['PATH']

os.environ['PATH'] += ":"+"/usr/local/bin"
print os.environ['PATH']

print os.getcwd()

from subprocess import check_call
print check_call(["dot", "-o9.png", "-Tpng", "./6.dot"])

Taken from the question to try and maintain some sort of sanity here.




回答5:


Troubleshooting tips:

A. add

print os.getcwd()

on the line before os.system("dot etc.

Just to make sure that the current directory is the one with the 6.dot file.

B. Make sure that the dot program is in your path.

which dot

C. Use the full path to the dot program in your os.system command, see what happens then.




回答6:


If you also generate your Dot files in Python, pydot does what you want in a more Pythonic way:

import pydot
dot = pydot.Dot()
n1, n2 = pydot.Node("a"), pydot.Node("b")
dot.add_node(n1)
dot.add_node(n2)
dot.add_edge(pydot.Edge(n1,n2))
dot.write_png("graph.png", prog='neato')



回答7:


Often the solution is in front of us,

print os.system("/usr/local/bin/dot -o9.png -Tpng 6.dot")

Also you can try for all the dots in a specified folder

import glob
for filedot in glob.glob('*.dot')
    print os.system("/usr/local/bin/dot -o9.png -Tpng %(filedot)s"%locals())
    #print os.system("/usr/local/bin/dot -o9.png -Tpng %s"%filedot)

Edit:

I cannot recall btw if it is

/usr/local/bin/dot -o9.png -Tpng fdot.dot

or

/usr/local/bin/dot -o 9.png -Tpng fdot.dot



回答8:


Two suggestions

  1. Don't use PATH, instead use "which" to just find the executable instead
  2. You don't use ";" (semi-colon) to separate paths, but ":" (colon). Once you change this it should be able to find your dot program.

Change this

os.environ['PATH'] += ";"+"/usr/local/bin/dot"

to this

os.environ['PATH'] += ":"+"/usr/local/bin"

Then your good.

EDIT: Note that I forgot to remove the /dot from the PATH variable myself (oops) - PATH is a colon delimited list of directories.




回答9:


Instead of:

print os.system("dot -o9.png -Tpng ./6.dot")

try this:

from subprocess import check_call
print check_call("dot -o9.png -Tpng ./6.dot")

If exit status of dot program is 0, the status is printed. If dot returns non-zero status, it raises CalledProcessError (and shows returned status). If dot doesn't exist in current path, OSError is raised on Linux or WindowsErroor on Windows (I don't know which exception is raised under Mac OS, but I assume OSError).

EDIT: Code above will give you the hint if you have no dot executable or 6.dot file in current path settings.




回答10:


check_call does not use the same syntax as os.system, so you should try changing the corresponding line this way:

print check_call(["dot", "-o9.png", "-Tpng", "./6.dot"])

The executable name is the first item in the array, and each parameter must be in another item of the array. Otherwise you will always get a "No such file" error because there is no executable named "dot -o9.png ..." in your PATH.




回答11:


One problem is in this line:

os.environ['PATH'] += ":"+"/usr/local/bin/dot"

You don't put the name of the executable in the path, but the directory containing the executable. So that should be:

os.environ['PATH'] += ":"+"/usr/local/bin"

And as pointed out in another comment, the arguments to check_call are not the same as os.system.




回答12:


If you are using a GUI such as Spyder then you can simply add the correct bin path into the PYTHONPATH manager options menu.

Search for the script location by doing this in the terminal:

which programname

then take that location (wherever it is), subtract the programname, for example:

/home/username/seiscomp3/bin/scart
#this is the section of the path that you use
/home/username/seiscomp3/bin

Then go into the PYTHONPATH manager options menu and add this path. Then restart Spyder and it'll work.



来源:https://stackoverflow.com/questions/955504/how-do-i-run-dot-as-a-command-from-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!