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
- exec.Command不支持文件复制和目录递归复制吗?
1.有什么建议我如何实现文件复制和目录递归复制?
我刚刚开始学习围棋,因此是一个围棋新手。
4条答案
按热度按时间3hvapo4f1#
你不能在
exec.Command
中使用通配符。我会遍历目录中的文件,检查扩展名是否以.json
结尾,然后复制该文件。ac1kyiln2#
问题
解释一下:所谓的“通配符”是由shell扩展的,在shell中通常执行命令行命令。也就是说,当你调用
cp -r ./*.json dir/
时,shell会启动,通过它自己生成一个与该模式匹配的文件名列表并位于当前目录中,然后传递cp
命令 * 一个这样的名称列表 *。因此,假设有10个匹配的文件,对
cp
的实际调用将如下所示当您直接传递调用
cp ...
时(没有shell为您打开并展开*.json
“fileglob”),cp
命令会逐字接收文件名“.json”并尝试打开它。由于确切命名为“.json”的文件应该不存在,cp
会失败并退出。解决方案
第一种解决方案(公认的蹩脚)是“通过”shell传递对
cp
的调用,也就是说,将对cp
的调用转换为shell脚本并将其传递给shell。最简单的方法是使用类似于
这将调用一个shell
/bin/sh
,并通过其-c
命令行选项向其传递要执行的脚本。另一个解决方案是使用标准的Go语言库进行滚动复制:
path/filepath
包的函数支持像shell那样扩展fileglobs和迭代给定目录的条目。使用这两种方法中的任何一种,你都可以建立要复制和/或迭代的文件列表。然后,您可以使用函数
os.OpenFile()
打开源文件和目标文件,并使用io.Copy()
在它们之间复制内容。hpxqektj3#
使用内部使用io、os软件包的https://github.com/juju/utils/blob/master/fs/copy.go
twh00eeo4#
我发现bash的参数需要拆分为单独的参数,但cp命令及其参数需要放入
exec.Command
的单个参数中,如下所示: