매개변수 목록이 너무 깁니다: '/bin/sh' [닫음]

매개변수 목록이 너무 깁니다: '/bin/sh' [닫음]

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를 사용하는 경우 tartar 아카이브에 원하는 파일 목록을 텍스트 파일에 작성한 다음 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 .

관련 정보