36.11. pipes — シェルパイプラインへのインタフェース

ソースコード: Lib/pipes.py


pipes モジュールでは、 pipeline の概念 — あるファイルを別のファイルに変換する機構の直列接続 — を抽象化するためのクラスを定義しています。

このモジュールは /bin/sh コマンドラインを利用するため、 os.system() および os.popen() のための POSIX 準拠のシェル、または互換のシェルが必要です。

class pipes.Template

パイプラインを抽象化したクラス。

例:

>>> import pipes
>>> t = pipes.Template()
>>> t.append('tr a-z A-Z', '--')
>>> f = t.open('pipefile', 'w')
>>> f.write('hello world')
>>> f.close()
>>> open('pipefile').read()
'HELLO WORLD'
pipes.quote(s)

バージョン 2.7 で撤廃: Python 2.7 のある時点まで、この関数は公式にドキュメントされてきませんでした。これは Python 3.3 でようやく、ただし shlex モジュール内の quote 関数として公になりました。

文字列 s をシェルエスケープして返します。戻り値は、リストを使えないようなケースで、シェルコマンドライン内で一つのトークンとして安全に利用出来る文字列です。

以下のイディオムは安全ではないかもしれません:

>>> filename = 'somefile; rm -rf ~'
>>> command = 'ls -l {}'.format(filename)
>>> print command  # executed by a shell: boom!
ls -l somefile; rm -rf ~

quote() がそのセキュリティの穴をふさぎます:

>>> command = 'ls -l {}'.format(quote(filename))
>>> print command
ls -l 'somefile; rm -rf ~'
>>> remote_command = 'ssh home {}'.format(quote(command))
>>> print remote_command
ssh home 'ls -l '"'"'somefile; rm -rf ~'"'"''

この引用方法は UNIX シェル、 shlex.split() と互換です:

>>> remote_command = shlex.split(remote_command)
>>> remote_command
['ssh', 'home', "ls -l 'somefile; rm -rf ~'"]
>>> command = shlex.split(remote_command[-1])
>>> command
['ls', '-l', 'somefile; rm -rf ~']

36.11.1. テンプレートオブジェクト

テンプレートオブジェクトは以下のメソッドを持っています:

Template.reset()

パイプラインテンプレートを初期状態に戻します。

Template.clone()

元のパイプラインテンプレートと等価の新しいオブジェクトを返します。

Template.debug(flag)

flag が真の場合、デバッグをオンにします。そうでない場合、デバッグをオフにします。デバッグがオンの時には、実行されるコマンドが印字され、より多くのメッセージを出力するようにするために、シェルに set -x 命令を与えます。

Template.append(cmd, kind)

新たなアクションをパイプラインの末尾に追加します。cmd 変数は有効な bourne shell 命令でなければなりません。kind 変数は二つの文字からなります。

最初の文字は '-' (コマンドが標準入力からデータを読み出すことを意味します)、'f' (コマンドがコマンドライン上で与えたファイルからデータを読み出すことを意味します)、あるいは '.' (コマンドは入力を読まないことを意味します、従ってパイプラインの先頭になります)、のいずれかになります。

同様に、二つ目の文字は '-' (コマンドが標準出力に結果を書き込むことを意味します)、'f' (コマンドがコマンドライン上で指定したファイルに結果を書き込むことを意味します)、あるいは '.' (コマンドはファイルを書き込まないことを意味し、パイプラインの末尾になります)、のいずれかになります。

Template.prepend(cmd, kind)

パイプラインの先頭に新しいアクションを追加します。引数の説明については append() を参照してください。

Template.open(file, mode)

ファイル類似のオブジェクトを返します。このオブジェクトは file を開いていますが、パイプラインを通して読み書きするようになっています。mode には 'r' または 'w' のいずれか一つしか与えることができないので注意してください。

Template.copy(infile, outfile)

パイプを通して infileoutfile にコピーします。