Я только что столкнулся с той же проблемой, и я смог использовать решение, предложенное @AugustinAmenabar в разделе комментариев к принятому ответу. Моя установка была немного более сложной, поэтому я добавил флаг - recursive
, чтобы обновить все зависимости.
git submodule update src / repo --recursive
Обратите внимание, что ответ с использованием Archive::Tar
считывает архив в память. Используя модуль Python tarfile
, этого можно избежать. К сожалению, стримить с stdin
мне пока не удалось, так как extractfile
пытается искать.
#!/usr/bin/env python3
import tarfile
import sys
with tarfile.open(name=sys.argv[1], mode="r") as in_tar, \
tarfile.open(fileobj=sys.stdout.buffer, mode="w|") as out_tar:
for member in in_tar.getmembers():
member.uname = member.gname = "root"
if member.isfile():
with in_tar.extractfile(member) as file:
out_tar.addfile(member, file)
else:
out_tar.addfile(member)
Обновление:Следующая программа Go работает с потоками:
package main
import (
"archive/tar"
"io"
"log"
"os"
)
func main() {
tr := tar.NewReader(os.Stdin)
tw := tar.NewWriter(os.Stdout)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
hdr.Uname, hdr.Gname = "root", "root"
if err := tw.WriteHeader(hdr); err != nil {
log.Fatal(err)
}
if hdr.Typeflag == tar.TypeReg {
if _, err := io.Copy(tw, tr); err != nil {
log.Fatal(err)
}
}
}
if err := tw.Close(); err != nil {
log.Fatal(err)
}
}
Если вы используете macOS, ее версия tar имеет расширение «mtree», которое может это сделать. Полученный tar-файл можно распаковать в Linux (, т. е. он является переносимым ).
Из раздела ПРИМЕРЫ справочной страницы macOS tar:
$ cat input.mtree
#mtree
usr/bin uid=0 gid=0 mode=0755 type=dir
usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls
$ tar -cvf output.tar @input.mtree
Комментарий #mtree
в начале входного файла обязателен. Также имеются опции uname
и gname
(вместо uid
/gid
) для установки символических имен вместо числовых значений. См. man mtree 5
для списка всех ключевых слов.