tarball에서 파일의 사용자 ID 및 그룹 ID 소유권을 변경하시겠습니까?

tarball에서 파일의 사용자 ID 및 그룹 ID 소유권을 변경하시겠습니까?

올바른 사용자 및 그룹 소유권이 없는 파일이 포함된 tarball이 있습니다. 파일은 소유되며 jenkins:jenkins, 나는 그 파일을 소유하기를 원합니다 naftuli:othergroup.

포함된 파일이 내가 소유하도록 타르볼을 편집할 수 있는 방법이 있습니까 naftuli:othergroup?

내가 직면한 문제는 tarball을 생성하는 동안 사용자에게 다른 사용자 및 그룹에 대한 권한이 jenkins없다는 것입니다 . chown추출 시 사용자가 언급한 파일을 생성할 수 있는 권한이 부여되므로 타르볼에서 사용자 ID와 그룹 ID를 편집해야 합니다.

답변1

아카이브::타르또는 유사한 소프트웨어가 이를 수행하는 한 가지 방법이 될 것입니다.

% touch foo  
% tar cvf x foo
foo
% tar tvf x          
-rw-rw-r--  1 jdoe12   jdoe12           0 May  6 20:36 foo
% perl -MArchive::Tar -e '$t=Archive::Tar->new;$t->read("x");$t->chown("foo","root");$t->write("y")'
% tar tvf y
-rw-rw-r--  1 root     jdoe12           0 May  6 20:36 foo
% 

답변2

추출에 대한 권한을 명시적으로 변경할 수는 없지만 tarball을 생성할 때 선호하는 ID를 tarball에 넣을 수 있습니다(tarball로 실행하지 않더라도 root).

tar cvf /tmp/tarball.tar --owner=naftuli --group othergroup files...

계정 세부 정보가 소스 시스템에 알려지지 않은 경우 --owner=naftuli:3000이름 뒤에 원하는 uid 및 gid(예: )를 추가할 수 있습니다.

또는 이미 타르볼이 있는 경우 Jenkins가 생성한 파일을 본인( naftuli:othergroup)으로 추출할 수 있으며, 본인이 아니므로 root해당 파일은 본인의 소유가 됩니다.

답변3

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)
        }
}

답변4

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도 있습니다 . 모든 키워드 목록은 참고자료를 참조하세요 .gnameuidgidman mtree 5

관련 정보