Search code examples
goexectartar.gz

How to work with tar command using golang exec.Cmd


I have a tar.gz file and i need to unpack it using golang. I've tried libs like "archive/tar" but they gave me error: archive/tar: invalid tar header. Now my idea was to use exec to run tar command and unpack tarball, but it always exits with code 2.

My code:

func unpack(tarName string) error {
path, _ := os.Getwd()
//err := Untar(path+"/"+tarName, path+"/")
fmt.Printf(path + "/" + tarName)
cmd := exec.Command("tar", "-xfv", path+"/"+tarName)
cmd.Stdout = os.Stdout
err := cmd.Run()
return err
}

Solution

  • If you are trying to compress tar.gz file you need first to decompress gzip.

    
    import (
        "archive/tar"
        "compress/gzip"
        "fmt"
        "io"
        "log"
        "os"
    )
    
    func ExtractTarGz(gzipStream io.Reader) {
        uncompressedStream, err := gzip.NewReader(gzipStream)
        if err != nil {
            log.Fatal("ExtractTarGz: NewReader failed")
        }
    
        tarReader := tar.NewReader(uncompressedStream)
    
        for true {
            header, err := tarReader.Next()
    
            if err == io.EOF {
                break
            }
    
            if err != nil {
                log.Fatalf("ExtractTarGz: Next() failed: %s", err.Error())
            }
    
            switch header.Typeflag {
            case tar.TypeDir:
                if err := os.Mkdir(header.Name, 0755); err != nil {
                    log.Fatalf("ExtractTarGz: Mkdir() failed: %s", err.Error())
                }
            case tar.TypeReg:
                outFile, err := os.Create(header.Name)
                if err != nil {
                    log.Fatalf("ExtractTarGz: Create() failed: %s", err.Error())
                }
                if _, err := io.Copy(outFile, tarReader); err != nil {
                    log.Fatalf("ExtractTarGz: Copy() failed: %s", err.Error())
                }
                outFile.Close()
    
            default:
                log.Fatalf(
                    "ExtractTarGz: uknown type: %s in %s",
                    header.Typeflag,
                    header.Name)
            }
    
        }
    }
    func main() {
        r, err := os.Open("./file.tar.gz")
        if err != nil {
            fmt.Println("error")
        }
        ExtractTarGz(r)
    }