web-dev-qa-db-ja.com

python)のコマンドライン引数に関数の引数をパイプします

私はpythonコード(cmd.py)コマンドライン引数としてファイルを受け入れ、parse_argsを使用して処理します。別のコードからファイルを渡したい(files.py)からcmd.py、関数の引数を渡すのと同じです。
これはcmd.pyを変更せずに実行できますか?

3
Akhitha

はい、できます。

cmd.py `files.py`

次に、最初のfiles.pyが実行され、出力(例: "file1.txt file2.txt")がcmd.pyの入力になります。

例:

cat `ls`

これは、作業ディレクトリでlsによって検出されたすべてのファイルを「cats」します。

3
Tobias

ここで実行できることがいくつかあります。 1つ目は、単純なコマンド置換です。

cmd.py $(files.py)

ここでの1つの問題は、ファイル名にスペース、タブ、または改行がある場合、これらのファイル名は単一の引数として渡されず、代わりにこれらの文字が出現する別の引数に分割されることです。

1つの代替方法は、cmd.pyが各ファイルを別々の行に出力する場合、シェルIFSに改行のみを含めるように設定できます。

IFS='
'
cmd.py $(files.py)

これは、改行を含むファイル名のみが問題であり、失敗するケースの数を減らすことを意味します。

もう1つの問題は、files.pyから出力されるファイルの数が多い場合にどうなるかです。コマンドラインがシステムで処理できるよりも長くなる可能性があります(制限要因は、コマンドラインの合計サイズとその他の要素の合計がLinuxでARG_MAXの場合です)。 xargsプログラムはこの状況向けに設計されており、コマンドラインがプログラムの1回の実行に対して長すぎる場合、プログラムは異なる実行に分割されます。これが役立つ場合は、次のことができます。

files.py | xargs cmd.py

もちろん、これは問題のある文字を含むファイル名がシェルに直接名前を入力するときと同じように引用/エスケープされることを想定しているため、問題が発生する可能性もあります。 1つのオプションは、出力が適切に引用されるようにcmd.pyを変更することですが、上記のxargsの設定と同様に、IFSの一部のバージョンで改行で区切られたファイル名を受け入れることができます。 -dオプションがサポートされている場合(これはLinuxではGNU xargs)です):

files.py | xargs -d '\n' cmd.py

最後に、おそらく最良の方法(現在、ほとんどのxargs実装でサポートされています)は、入力ファイルを改行ではなくnullで区切ることができる場合です。これは、複雑な引用符を導入せずにanyファイル名を簡単に処理します。Unixファイル名で許可されていない文字はnullだけだからです。

files.py | xargs -0 cmd.py
1
Graeme