Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 使用exec.Command运行sqlite3.backup_Go_Sqlite - Fatal编程技术网

Go 使用exec.Command运行sqlite3.backup

Go 使用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

我正试图使用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/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)
。我将接受您的答案,因为您费心发布了答案,并且您的推理是正确的。我不确定如果文件路径包含空格,是否需要使用内部单引号,但它们肯定会给我的案例带来问题。如果您同意,请相应地更改示例。谢谢!它也应该适用于单引号文件名周围的引号,请参见