tar
Python 호출을 통해 명령을 호출하려고 합니다 subprocess
. 내가 직면한 문제는 많은 파일을 전달하여 tar
명령에서 오류가 발생한다는 것입니다.Argument list too long: '/bin/sh'
내가 실행중인 명령은 다음과 같습니다
subprocess.call(f"ulimit -s 999999999; tar -cz -f {output_file} {file_list}", cwd=source_dir, shell=True)
오류를 극복하기 위해 ulimit
도움이 되지 않는 것으로 보이는 이것을 추가했습니다.
이 문제를 해결하는 데 도움을 받을 수 있도록 해주세요.
답변1
거대한 문자열의 일부로 파일 이름을 전달하는 것은언제나이는 나쁜 생각입니다(단일 파일 이름에 공백이 하나 있으면 바로 깨집니다).
대신 인수 목록을 목록으로 제공할 수 있는 인터페이스를 사용하십시오. 이 옵션은 거의 모든 경우에 좋지 않은 생각입니다 shell=True
. 특히 여기서는 (에서 호출되는 파일이 있다고 가정하면 something; rm -rf ..
이 명령은 확실히 삭제하지 않는 항목을 삭제합니다) 삭제하고 싶어요...).
그러나 ~함에 따라카스 설명하다tar
, 텍스트 파일에서 파일 이름을 읽는 기능을 사용해야 합니다 .
tar
하지만 더 좋은 점은 외부에 전혀 전화하지 않는 것입니다. 그냥 사용파이썬tarfile
모듈, 예, Python에는 이 모듈이 함께 제공됩니다. 그러면 이런 문제는 없을 것입니다!
위 모듈 문서의 최소 예를 약간 수정했습니다.
import tarfile
…
tar = tarfile.open(output_file, "w:gz")
for filename in files_in_an_actual_list:
tar.add(filename)
tar.close()
답변2
GNU를 사용하는 경우 tar
tar 아카이브에 원하는 파일 목록을 텍스트 파일에 작성한 다음 GNU tar -T
(일명 --files-from
) 옵션을 사용할 수 있습니다.
에서 man tar
:
-T
,--files-from=FILE
FILE에서 추출하거나 생성할 이름을 가져옵니다.
달리 지정하지 않는 한, FILE에는 ASCII LF로 구분된 이름 목록(즉, 한 줄에 하나의 이름)이 포함되어야 합니다. 읽기 이름은 명령줄 인수와 동일한 방식으로 처리됩니다. 이러한 문자열은 제거되고 토큰화되며, a로 시작하는 모든 문자열은
-
tar 명령줄 옵션으로 처리됩니다.이 동작을 원하지 않으면 이
--verbatim-files-from
옵션을 사용하여 끌 수 있습니다.이
--null
옵션은 tar FILE의 이름이 LF 대신 ASCII NUL 문자로 구분되도록 지시합니다. 목록이 (1) 조건자에 의해 생성된 경우find
유용합니다-print0
.