cpio를 사용하여 하나 이상의 경로에 공백이 포함될 수 있는 파일을 추출합니다.

cpio를 사용하여 하나 이상의 경로에 공백이 포함될 수 있는 파일을 추출합니다.

아카이브에 포함될 절대 경로 목록이 포함된 파일을 생성하여 생성된 cpio 아카이브가 있습니다. (일반 텍스트 파일의 한 줄에 하나의 절대 경로) 아카이브를 생성하는 명령은 기본적으로 다음과 같습니다.

cat list-of-files | cpio -ocvB > preserved.cpio

나중에 이 아카이브에서 파일을 추출해야 합니다. 이번에도 추출할 파일 목록이 포함된 파일을 사용하려고 합니다(아카이브에 있는 모든 파일의 일부 하위 집합, 다시 한 줄에 하나의 절대 경로가 있는 일반 텍스트 파일 형식).

cpio -icuBdmv `cat files-to-extract` < preserved.cpio

이 방법은 경로 중 하나에 공백이 포함되어 있지 않으면 제대로 작동합니다. 아카이브를 생성하는 것은 좋지만 파일을 추출할 때 이름에 공백이 있는 파일은 자동으로 건너뜁니다. 다른 모든 경로는 files-to-extract성공적으로 추출되었습니다.

이 문제를 해결할 수 있는 방법을 찾기 위해 콘솔에서 게임을 해봤지만 아무 소용이 없었습니다. 이름에 공백이 있는 단일 파일을 지정하고 따옴표로 묶으면 파일이 성공적으로 추출됩니다.

# This extracts the file successfully
cpio -icuBdmv "/foo/bar/some file.txt" < preserved.cpio

따라서 files-to-extract루프에서 읽고 각 파일을 한 번에 하나씩 추출할 수 있지만 이러한 아카이브는 용량이 커서(수 GB) 매우 느릴 수 있습니다.

파일 경로에서 공백을 이스케이프하거나 각 경로 값을 인용하기 위해 몇 가지 시도를 했지만 아무 것도 작동하지 않았습니다.

# Still skips the file with spaces:
cpio -icuBdmv `cat files-to-extract | sed 's/ /\\ /'` < preserved.cpio
# Extracts no files, even the ones without spaces:
cpio -icuBdmv `cat files-to-extract | sed 's/\(.*\)/"\1"/'` < preserved.cpio

한 번에 하나의 파일을 반복해서 추출하는 대신 단일 cpio 실행으로 이 추출을 수행할 수 있다면 좋을 것입니다. 나는 이것이 cpio에 이러한 값을 제공하는 방법에 문제가 있을 뿐이라고 확신하지만 평생 동안 그 이유를 알 수 없습니다.

관련성이 없을 수도 있지만 완전성을 위해서입니다. 이는 CentOS 7.2에서 GNU cpio 2.11을 사용하는 것입니다.

답변1

cpio명령줄에 파일 이름을 제공하는 대신(또는 동시에) 파일에서 파일 이름 목록을 읽을 수 있는 -E( ) 옵션이 있습니다 . --pattern-file예를 들어:

cpio -icuBdmv -E files-to-extract < preserved.cpio

cpio-F(stdin/stdout을 사용하는 대신) 아카이브 이름 도 지정해야 합니다 . -I와 유사 -O하지만 각각 stdin 또는 stdout 대신 작동합니다.

예를 들어, 아카이브를 지정 -F하고 표준 입력에 파일 목록을 제공할 수 있습니다.

cpio -icuBdmv -F preserved.cpio < files-to-extract 

또는 둘 다 사용 -E하고-F

cpio -icuBdmv -E files-to-extract -F preserved.cpio

그건 그렇고, 많은 GNU 프로그램(GNU 포함 cpio)의 경우 매뉴얼 페이지는 거의 쓸모가 없지만 .info 파일에 잘 문서화되어 있습니다. 일부 Linux 배포판에서 정보 문서는 일반적으로 별도의 패키지(예: debian ) cpio-doc이므로 정보 리더(예: GNU info또는pinfo

cpio어쨌든, 정보 페이지에서 발췌한 관련 내용은 다음과 같습니다 .

-E FILE,--pattern-file=FILE

FILE에서 추출하거나 나열할 파일 이름을 지정하는 다른 패턴을 읽습니다. FILE 행은 cpio에 대한 옵션이 아닌 매개변수로 처리됩니다. 이 옵션은 복사 모드에서 사용됩니다.

그리고

-F ARCHIVE,--file=ARCHIVE

표준 입력 또는 출력 대신 사용할 아카이브 파일의 이름입니다. 다른 컴퓨터의 테이프 드라이브를 아카이브로 사용하려면 HOSTNAME 으로 시작하는 파일 이름을 사용하십시오 HOSTNAME:. 여기서 HOSTNAME은 컴퓨터의 이름 또는 IP 주소입니다. @권한(일반적으로 해당 사용자 파일의 항목)이 있는 경우 ~/.rhosts호스트 이름 앞에 사용자 이름과 해당 사용자로 원격 테이프 드라이브에 액세스하는 데 사용되는 사용자 이름이 올 수 있습니다.

답변2

파일 이름의 공백은 까다로울 수 있지만 이것이 도움이 될 것이라고 생각했습니다.

cat추출할 파일을 추출하는 대신 xargsEOL을 NULL 문자로 바꿔서 제공해 보세요.

그것은 마치

tr '\n' '\0' < list-of-files | xargs -0 -I{} sh -c 'cpio -icuBdmv "{}" < preserved.cpio'

그러면 문제가 해결될 것입니다.

관련 정보