Golang中处理错误:无法识别的token ".read"

Golang中处理错误:无法识别的token “.read”

你使用的Go版本是什么(go version)?

$ go version
go version go1.13.3 windows/amd64

这个问题在最新版本中是否重现?

你使用的操作系统和处理器架构是什么(go env)?

Windows

`go env` 输出
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\ma\AppData\Local\go-build
set GOENV=C:\Users\ma\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=F:\wp\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Users\ma\soft\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Users\ma\soft\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\ma\AppData\Local\Temp\go-build601014506=/tmp/go-build -gno-record-gcc-switches

你做了什么?

    newDbName = "C:\\Users\\ma\\Desktop\\sqlite3\\malformed\\root\\test.db"
    path = "C:\\Users\\ma\\Desktop\\sqlite3\\malformed\\root"
    dmt := fmt.Sprintf("/c %s&cd %s&sqlite3.exe %s \".read tmp.sql\"", path[0:2], path, newDbName)
    cmd := exec.Command("cmd.exe", dmt)
    out1, err := cmd.CombinedOutput()
    if err != nil{
    	fmt.Println(err)
    }

你期望看到什么?

创建一个新的数据库文件, C:\Users\ma\Desktop\sqlite3\malformed\root\test.db

你实际看到了什么?

错误:无法识别的标记:“.read”


更多关于Golang中处理错误:无法识别的token ".read"的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

打印 dmt 内容。显示如下:

/c C:&cd C:\Users\ma\Desktop\sqlite3\malformed\root&sqlite3.exe C:\Users\ma\Desktop\sqlite3\malformed\root\test.db ".read tmp.sql"

更多关于Golang中处理错误:无法识别的token ".read"的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中执行外部命令时,参数传递方式不正确导致SQLite无法识别.read命令。问题出在将整个命令字符串作为单个参数传递,而实际上需要将参数分开传递。

以下是修正后的代码:

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    newDbName := "C:\\Users\\ma\\Desktop\\sqlite3\\malformed\\root\\test.db"
    path := "C:\\Users\\ma\\Desktop\\sqlite3\\malformed\\root"
    
    // 正确的方式:将参数分开传递
    cmd := exec.Command("cmd.exe", "/c", "cd", path, "&&", "sqlite3.exe", newDbName, ".read", "tmp.sql")
    
    out1, err := cmd.CombinedOutput()
    if err != nil {
        fmt.Printf("命令执行错误: %v\n", err)
    }
    
    fmt.Printf("输出: %s\n", out1)
}

或者,如果你需要保持当前目录不变,可以使用以下方式:

cmd := exec.Command("sqlite3.exe", newDbName, ".read", "tmp.sql")
cmd.Dir = path  // 设置工作目录

out1, err := cmd.CombinedOutput()
if err != nil {
    fmt.Printf("命令执行错误: %v\n", err)
}

如果你需要更复杂的命令组合,可以使用多个命令:

// 创建数据库文件(如果不存在)
createCmd := exec.Command("sqlite3.exe", newDbName, ".databases")
createCmd.Dir = path
createOut, _ := createCmd.CombinedOutput()
fmt.Printf("创建数据库输出: %s\n", createOut)

// 执行SQL文件
readCmd := exec.Command("sqlite3.exe", newDbName, ".read", "tmp.sql")
readCmd.Dir = path
readOut, err := readCmd.CombinedOutput()
if err != nil {
    fmt.Printf("执行SQL错误: %v\n", err)
}
fmt.Printf("SQL执行输出: %s\n", readOut)

关键点是:

  1. 每个参数都应该作为独立的字符串传递给exec.Command
  2. 使用cmd.Dir设置工作目录,而不是通过cd命令
  3. SQLite的.read命令需要作为单独的参数传递

这样修改后,SQLite就能正确识别.read命令并执行tmp.sql文件中的SQL语句了。

回到顶部