Go 使用exec.Command运行sqlite3.backup
我正试图使用sqlite3Go 使用exec.Command运行sqlite3.backup,go,sqlite,Go,Sqlite,我正试图使用sqlite3.backup命令从Go备份一个db,备份方式如下所示 以下操作始终在命令行中起作用: sqlite3/home/pi/pgclogs/smartlog.db.backup'/home/pi/pgcdata/smartlog.db.bak' 我将其编码为Go,如下所示: func DbBackup() (err error) { dbpath := "/home/pi/pgclogs/smartlog.db" bakpath := "/home/pi/p
.backup
命令从Go备份一个db,备份方式如下所示
以下操作始终在命令行中起作用:
sqlite3/home/pi/pgclogs/smartlog.db.backup'/home/pi/pgcdata/smartlog.db.bak'
我将其编码为Go,如下所示:
func DbBackup() (err error) {
dbpath := "/home/pi/pgclogs/smartlog.db"
bakpath := "/home/pi/pgcdata/smartlog.db.bak"
cmd := exec.Command("sqlite3", dbpath, fmt.Sprintf("\".backup '%s'\"", bakpath))
out, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("dbBackup failed : %s : %v", string(out), err)
}
return
}
我有一个调用它的测试文件,如下所示:
func TestDbBackup(t *testing.T) {
var err error
err = DbBackup()
if err != nil {
t.Errorf("backup failed : %v", err)
}
}
测试报告来自sqlite3的语法错误
--- FAIL: TestDbBackup (0.01s)
db_backup_test.go:22: backup failed : dbBackup failed : Error: near "".backup '/home/pi/pgcdata/smartlog.db.bak'"": syntax error
: exit status 1
我怀疑问题在于cmd.CombinedOutput
将参数传递给shell的方式,而问题在于fmt.Sprintf
调用中的引用。我试着把它改成
fmt.Sprintf(`".backup '%s'"`, bakpath)
但结果是一样的。我还尝试将echo
放在命令前面,即exec.command(“echo”、“sqlite3”、dbpath等”)并打印输出。输出看起来绝对正确
sqlite3 /home/pi/pgclogs/smartlog.db ".backup '/home/pi/pgcdata/smartlog.db.bak'"
粘贴到命令行时,它可以正确运行。我肯定我忽略了一些简单的东西,但我已经花了一个多小时,仍然没有看到它。您根本不需要额外的引号,因此应该这样做:
exec.Command("sqlite3", dbpath, fmt.Sprintf(".backup '%s'", bakpath))
引号由shell解析,以便将.backup'somefile'
作为单个参数传递给sqlite3
。使用exec.Command
时,不涉及shell,这也是将命令分为多个参数传递的原因。这几乎有效,但不完全有效。就在发现之前您的答案我(终于!)在没有任何内部引号的情况下运行,fmt.Sprintf(“.backup%s”,bakpath)
。我将接受您的答案,因为您费心发布了答案,并且您的推理是正确的。我不确定如果文件路径包含空格,是否需要使用内部单引号,但它们肯定会给我的案例带来问题。如果您同意,请相应地更改示例。谢谢!它也应该适用于单引号文件名周围的引号,请参见