Go语言 exec,带有cp的命令退出,状态为1

hec6srdp  于 2022-12-07  发布在  Go
关注(0)|答案(4)|浏览(284)
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

  1. exec.Command不支持文件复制和目录递归复制吗?
    1.有什么建议我如何实现文件复制和目录递归复制?
    我刚刚开始学习围棋,因此是一个围棋新手。
3hvapo4f

3hvapo4f1#

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

ac1kyiln

ac1kyiln2#

问题

解释一下:所谓的“通配符”是由shell扩展的,在shell中通常执行命令行命令。也就是说,当你调用cp -r ./*.json dir/时,shell会启动,通过它自己生成一个与该模式匹配的文件名列表并位于当前目录中,然后传递cp命令 * 一个这样的名称列表 *。
因此,假设有10个匹配的文件,对cp的实际调用将如下所示

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

当您直接传递调用cp ...时(没有shell为您打开并展开*.json“fileglob”),cp命令会逐字接收文件名“.json”并尝试打开它。由于确切命名为“.json”的文件应该不存在,cp会失败并退出。

解决方案

第一种解决方案(公认的蹩脚)是“通过”shell传递对cp的调用,也就是说,将对cp的调用转换为shell脚本并将其传递给shell。
最简单的方法是使用类似于

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

这将调用一个shell /bin/sh,并通过其-c命令行选项向其传递要执行的脚本。
另一个解决方案是使用标准的Go语言库进行滚动复制:path/filepath包的函数支持像shell那样扩展fileglobs和迭代给定目录的条目。使用这两种方法中的任何一种,你都可以建立要复制和/或迭代的文件列表。
然后,您可以使用函数os.OpenFile()打开源文件和目标文件,并使用io.Copy()在它们之间复制内容。

twh00eeo

twh00eeo4#

我发现bash的参数需要拆分为单独的参数,但cp命令及其参数需要放入exec.Command的单个参数中,如下所示:

out, err := exec.Command("/bin/bash", "-c", "cp -r ./*.json manifest").CombinedOutput()

相关问题