繁体   English   中英

带有cp的exec.Command以状态1退出

[英]exec.Command with cp exits with status 1

util.ExecuteCommandWithOuput(exec.Command("cp", "-r", "./*.json", artifact.dir))

func ExecuteCommandWithOuput(cmd *exec.Cmd) {
    output, err := cmd.Output()
    if err != nil {
        log.Print("Error executing ", cmd.Args, err)
    }
    fmt.Print(string(output))
}

产量

2017/01/16 13:26:35 Error executing [cp -r ./*.json myartifact] exit status 1

问题

  1. 如何获取有关cp命令失败的完整错误消息的详细信息? 我确实有err!= nill和Print err
  2. exec.Command是否不支持文件副本和目录的递归副本?
  3. 任何建议如何实现文件副本和目录的递归副本?

我刚刚开始采用Go,因此采用了Go。

您不能在exec.Command中使用exec.Command 我将遍历目录中的文件,并检查扩展名是否以.json结尾,然后复制该文件。

问题

解释:所谓的“通配符”由通常在其中执行命令行命令的外壳扩展。 也就是说,当您调用cp -r ./*.json dir/ ,shell会启动,自行扩展*.json cp -r ./*.json dir/ -生成与该模式匹配并位于当前目录中的文件的名称列表,并传递cp命令此类名称的列表

因此,如果您有10个匹配的文件,对cp的实际调用将最终看起来像

cp -r file1.json file2.json ... dir/

当您直接传递调用cp ... -在没有shell介入的情况下为您扩展*.json .json“ fileglob”时, cp命令将逐字接收文件“ * .json”的名称并尝试将其打开。 由于据称精确命名为“ * .json”的文件不存在,因此cp失败并退出。

解决方案

第一个(当然是la脚的)解决方案是“通过” shell将调用传递给cp 也就是说, cp的调用转换为shell脚本,然后将其传递给shell。

最简单的方法是使用类似

exec.Command(`/bin/sh -c 'cp -r ./*.json manifest'`)

这将调用shell /bin/sh并将脚本传递给它,以通过其-c命令行选项执行。

另一个解决方案是使用标准的Go库进行自我复制: path/filepath包的功能既支持扩展shell扩展的文件范围,又提供对给定目录的条目进行迭代的支持。 使用这两种方法之一,您都可以构建文件列表以对其进行复制和/或迭代。

然后,您可以使用函数os.OpenFile()打开源文件和目标文件,并使用io.Copy()在它们之间复制内容。

使用内部使用io,os软件包的https://github.com/juju/utils/blob/master/fs/copy.go

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM