Go调用exec执行tar获取解压进度报unknown checkpoint action问题咨询
问题原因
错误核心是exec.Command的参数传递规则和shell解析逻辑存在差异:
- 在bash中执行命令时,
--checkpoint-action参数外层的单引号属于shell语法,作用是告知shell单引号内的内容是完整的单个参数、不会被拆分,执行时shell会自动把单引号去掉再传递给tar程序。 - Go的
exec.Command不会经过shell解析参数,你传入的每个字符串切片元素会被原封不动直接传递给tar,因此代码里写的单引号会被当成参数内容的一部分,tar实际收到的动作规则是带单引号的'ttyout=progress %u\r',自然识别不了这个未知动作。
修复方案
直接去掉--checkpoint-action参数外层的单引号即可,修改后的代码如下:
func test() { // 仅修改--checkpoint-action的参数,移除外层单引号 cmd := exec.Command("tar", "zxvf", "backup.tar.gz", "--blocking-factor=94170", "--checkpoint=1", "--checkpoint-action=ttyout=progress %u\r") var stdout bytes.Buffer var stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr if err := cmd.Run(); err != nil { log.Logger().Info("failed: ", err) log.Logger().Info(stderr.String()) } log.Logger().Info(stdout.String()) }
补充说明
- 后续使用
exec.Command传递包含空格、特殊符号的参数时,直接写完整字符串即可,不需要加任何shell层面的引号包裹。 - 如果你需要实时读取tar的进度输出,不要用
bytes.Buffer缓存全部输出,建议直接把cmd.Stdout绑定到os.Stdout,或者用流式读取的方式处理输出,避免缓冲导致进度更新不及时。
内容的提问来源于stack exchange,提问作者rockcode
相关产品推荐
相关产品推荐

