パラメータリストが長すぎます: '/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

巨大な文字列の一部としてファイル名を渡すことはいつもこれは悪い考えです(単一のファイル名にスペースが1つあればすぐに壊れます)。

代わりに、引数リストをリストとして提供できるインターフェースを使用してください。このオプションはほとんどすべての場合には悪い考えですshell=True。特にここでは(で呼び出されるファイルがあると仮定すると、something; rm -rf ..このコマンドは確かに削除しない項目を削除します)削除したいです...)。

しかし〜に応じてカス 説明するtar、テキストファイルからファイル名を読み取る機能を使用する必要があります。

tarしかし、より良い点は、外部にまったく電話しないことです。ただ使用Pythontarfileモジュール、はい、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で区切られた名前のリスト(つまり1行に1つの名前)を含める必要があります。読み取り名は、コマンドライン引数と同じ方法で処理されます。これらの文字列は削除され、トークン化され、aで始まるすべての文字列は-tarコマンドラインオプションとして扱われます。

この動作を望まない場合は、この--verbatim-files-fromオプションを使用してオフにできます。

この--nullオプションは、tar FILE の名前を LF ではなく ASCII NUL 文字で区切るように指示します。リストが(1)述語によって生成された場合にfind便利です-print0

関連情報