You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Go程序调用Graphviz执行Dot脚本生成图片?

Fixing Exit Code 3 When Calling dot from Go

Hey there! Let's break down why you're getting exit code 3 from the dot command and how to fix it.

First off, exit code 3 from Graphviz's dot typically means it's receiving invalid arguments—and that's exactly what's happening here. The problem is how you're trying to handle output redirection with > in your exec.Command call.

Why Your Current Code Fails

Go's os/exec package runs commands directly, not through a shell. That means when you pass ">", "/path/to/hello.png" as arguments to dot, it doesn't interpret the > as a redirection instruction—it treats it as a literal filename. dot can't find a file named > and throws an error, hence exit code 3.

The cleanest and safest way to capture the output is to use Go's built-in cmd.Stdout to pipe the command's output directly to a file. Here's the adjusted code:

package main

import (
	"fmt"
	"os"
	"os/exec"
)

func main() {
	path, err := exec.LookPath("dot")
	if err != nil {
		fmt.Printf("Couldn't locate the dot command: %v\n", err)
		return
	}

	// Create the output file we want to write to
	outputFile, err := os.Create("/Users/arafat/Desktop/dev/go/src/github.com/Arafatk/dataviz/hello.png")
	if err != nil {
		fmt.Printf("Failed to create output file: %v\n", err)
		return
	}
	defer outputFile.Close() // Make sure we close the file when done

	// Set up the dot command without any redirection arguments
	cmd := exec.Command(path, "-Tpng", "/Users/arafat/Desktop/dev/go/src/github.com/Arafatk/dataviz/DotExamples/arraylist.dot")
	cmd.Stdout = outputFile // Redirect the command's stdout to our file

	err = cmd.Run()
	fmt.Println("Path to dot:", path)
	if err != nil {
		fmt.Printf("Command execution failed: %v\n", err)
		return
	}

	fmt.Println("Success! PNG image generated.")
}

This approach avoids shell overhead, is more secure (no risk of shell injection if paths ever come from user input), and gives you more control over the I/O flow.

Solution 2: Run via Shell (If You Prefer)

If you really want to use shell-style redirection, you can execute the entire command through a shell like bash using the -c flag. Just make sure to properly quote your paths to avoid issues with spaces:

package main

import (
	"fmt"
	"os/exec"
)

func main() {
	dotInputPath := "/Users/arafat/Desktop/dev/go/src/github.com/Arafatk/dataviz/DotExamples/arraylist.dot"
	pngOutputPath := "/Users/arafat/Desktop/dev/go/src/github.com/Arafatk/dataviz/hello.png"

	// Build the full shell command with quoted paths
	shellCmd := fmt.Sprintf("dot -Tpng %q > %q", dotInputPath, pngOutputPath)

	// Run the command through bash
	cmd := exec.Command("bash", "-c", shellCmd)
	err := cmd.Run()
	if err != nil {
		fmt.Printf("Command failed: %v\n", err)
		return
	}

	fmt.Println("PNG image generated successfully!")
}

Give either of these a try, and your dot command should run without exit code 3.

内容的提问来源于stack exchange,提问作者ArafatK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:33:24