24.3. shlex
— 単純な字句解析¶
ソースコード: Lib/shlex.py
shlex
クラスは Unix シェルに似た、単純な構文に対する字句解析器を簡単に書けるようにします。このクラスはしばしば、 Python アプリケーションのための実行制御ファイルのような小規模言語を書く上で便利です。
shlex
モジュールは以下の関数を定義しています:
-
shlex.
split
(s, comments=False, posix=True)¶ シェルに似た文法を使って、文字列 s を分割します。 comments が
False
(デフォルト値) の場合、受理した文字列内のコメントを解析しません (shlex
インスタンスのcommenters
メンバの値を空文字列にします)。この関数はデフォルトでは POSIX モードで動作し、 posix 引数が偽の場合は非 POSIX モードで動作します。
-
shlex.
quote
(s)¶ 文字列 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 シェルならびに
split()
と互換です:>>> remote_command = split(remote_command) >>> remote_command ['ssh', 'home', "ls -l 'somefile; rm -rf ~'"] >>> command = split(remote_command[-1]) >>> command ['ls', '-l', 'somefile; rm -rf ~']
バージョン 3.3 で追加.
shlex
モジュールは以下のクラスを定義します:
-
class
shlex.
shlex
(instream=None, infile=None, posix=False)¶ shlex
クラスとサブクラスのインスタンスは、字句解析器オブジェクトです。初期化引数を与えると、どこから文字を読み込むかを指定できます。指定先はread()
メソッドとreadline()
メソッドを持つファイル/ストリーム類似オブジェクトか、文字列でなくてはいけません。引数が与えられなければ、sys.stdin
から入力を受け付けます。第 2 引数は、ファイル名を表す文字列で、infile
メンバの値の初期値を決定します。 instream 引数が省略された場合や、この値がsys.stdin
である場合、第2引数のデフォルト値は “stdin” になります。 posix 引数は動作モードを定義します: posix が真でない場合(デフォルト)、shlex
インスタンスは互換モードで動作します。 POSIX モードで動作中、shlex
は、できる限り POSIX シェルの解析規則に似せようとします。
参考
configparser
モジュールWindows
.ini
ファイルに似た設定ファイルのパーザ。
24.3.1. shlex オブジェクト¶
shlex
インスタンスは以下のメソッドを持っています:
-
shlex.
get_token
()¶ トークンを一つ返します。トークンが
push_token()
で使ってスタックに積まれていた場合、トークンをスタックからポップします。そうでない場合、トークンを一つ入力ストリームから読み出します。読み出し即時にファイル終了子に遭遇した場合、eof
(非 POSIX モードでは空文字列 (''
)、POSIX モードではNone
) が返されます。
-
shlex.
push_token
(str)¶ トークンスタックに引数文字列をスタックします。
-
shlex.
read_token
()¶ 生 (raw) のトークンを読み出します。プッシュバックスタックを無視し、かつソースリクエストを解釈しません。 (通常これは便利なエントリポイントではありません。完全性のためにここで記述されています。)
-
shlex.
sourcehook
(filename)¶ shlex
がソースリクエスト (下のsource
を参照してください) を検出した際、このメソッドはその後に続くトークンを引数として渡され、ファイル名と開かれたファイル類似オブジェクトからなるタプルを返すとされています。通常、このメソッドはまず引数から何らかのクオートを取り除きます。処理後の引数が絶対パス名であった場合か、以前に有効になったソースリクエストが存在しない場合か、以前のソースが (
sys.stdin
のような) ストリームであった場合、この結果はそのままにされます。そうでない場合で、処理後の引数が相対パス名の場合、ソースインクルードスタックにある直前のファイル名からディレクトリ部分が取り出され、相対パスの前の部分に追加されます (この動作は C 言語プリプロセッサにおける#include "file.h"
の扱いと同様です)。これらの操作の結果はファイル名として扱われ、タプルの最初の要素として返されます。同時にこのファイル名で
open()
を呼び出した結果が二つ目の要素になります (注意: インスタンス初期化のときとは引数の並びが逆になっています!)このフックはディレクトリサーチパスや、ファイル拡張子の追加、その他の名前空間に関するハックを実装できるようにするために公開されています。 ‘close’ フックに対応するものはありませんが、shlex インスタンスはソースリクエストされている入力ストリームが EOF を返した時には
close()
を呼び出します。ソーススタックをより明示的に操作するには、
push_source()
およびpop_source()
メソッドを使ってください。
-
shlex.
push_source
(newstream, newfile=None)¶ 入力ソースストリームを入力スタックにプッシュします。ファイル名引数が指定された場合、以後のエラーメッセージ中で利用することができます。
sourcehook()
メソッドが内部で使用しているのと同じメソッドです。
-
shlex.
pop_source
()¶ 最後にプッシュされた入力ソースを入力スタックからポップします。字句解析器がスタック上の入力ストリームの EOF に到達した際に利用するメソッドと同じです。
-
shlex.
error_leader
(infile=None, lineno=None)¶ このメソッドはエラーメッセージの論述部分を Unix C コンパイラエラーラベルの形式で生成します; この書式は
'"%s", line %d: '
で、%s
は現在のソースファイル名で置き換えられ、%d
は現在の入力行番号で置き換えられます (オプションの引数を使ってこれらを上書きすることもできます)。このやり方は、
shlex
のユーザに対して、Emacs やその他の Unix ツール群が解釈できる一般的な書式でのメッセージを生成することを推奨するために提供されています。
shlex
サブクラスのインスタンスは、字句解析を制御したり、デバッグに使えるような public なインスタンス変数を持っています:
-
shlex.
commenters
¶ コメントの開始として認識される文字列です。コメントの開始から行末までのすべてのキャラクタ文字は無視されます。標準では単に
'#'
が入っています。
-
shlex.
wordchars
¶ 複数文字からなるトークンを構成するためにバッファに蓄積していくような文字からなる文字列です。標準では、全ての ASCII 英数字およびアンダースコアが入っています。
-
shlex.
whitespace
¶ 空白と見なされ、読み飛ばされる文字群です。空白はトークンの境界を作ります。標準では、スペース、タブ、改行 (linefeed) および復帰 (carriage-return) が入っています。
-
shlex.
escape
¶ エスケープ文字と見なされる文字群です。これは POSIX モードでのみ使われ、デフォルトでは
'\'
だけが入っています。
-
shlex.
quotes
¶ 文字列引用符と見なされる文字群です。トークンを構成する際、同じクオートが再び出現するまで文字をバッファに蓄積します (すなわち、異なるクオート形式はシェル中で互いに保護し合う関係にあります)。標準では、ASCII 単引用符および二重引用符が入っています。
-
shlex.
escapedquotes
¶ quotes
のうち、escape
で定義されたエスケープ文字を解釈する文字群です。これは POSIX モードでのみ使われ、デフォルトでは'"'
だけが入っています。
-
shlex.
whitespace_split
¶ この値が
True
であれば、トークンは空白文字でのみで分割されます。たとえばshlex
がシェル引数と同じ方法で、コマンドラインを解析するのに便利です。
-
shlex.
infile
¶ 現在の入力ファイル名です。クラスのインスタンス化時に初期設定されるか、その後のソースリクエストでスタックされます。エラーメッセージを構成する際にこの値を調べると便利なことがあります。
-
shlex.
source
¶ このメンバ変数は標準で
None
を取ります。この値に文字列を代入すると、その文字列は多くのシェルにおけるsource
キーワードに似た、字句解析レベルでのインクルード要求として認識されます。すなわち、その直後に現れるトークンをファイル名として新たなストリームを開き、そのストリームを入力として、EOF に到達するまで読み込まれます。新たなストリームの EOF に到達した時点でclose()
が呼び出され、入力は元の入力ストリームに戻されます。ソースリクエストは任意のレベルの深さまでスタックしてかまいません。
-
shlex.
debug
¶ このメンバ変数が数値で、かつ
1
またはそれ以上の値の場合、shlex
インスタンスは動作に関する冗長な進捗報告を出力します。この出力を使いたいなら、モジュールのソースコードを読めば詳細を学ぶことができます。
-
shlex.
lineno
¶ ソース行番号 (遭遇した改行の数に 1 を加えたもの) です。
-
shlex.
token
¶ トークンバッファです。例外を捕捉した際にこの値を調べると便利なことがあります。
-
shlex.
eof
¶ ファイルの終端を決定するのに使われるトークンです。非 POSIX モードでは空文字列 (
''
)、POSIX モードではNone
が入ります。
24.3.2. 解析規則¶
非 POSIX モードで動作中の shlex
は以下の規則に従おうとします。
ワード内の引用符を認識しない (
Do"Not"Separate
は単一ワードDo"Not"Separate
として解析されます);エスケープ文字を認識しない;
引用符で囲まれた文字列は、引用符内の全ての文字リテラルを保持する;
閉じ引用符でワードを区切る (
"Do"Separate
は、"Do"
とSeparate
であると解析されます);whitespace_split
がFalse
の場合、wordchar、 whitespace または quote として宣言されていない全ての文字を、単一の文字トークンとして返す。True
の場合、shlex
は空白文字でのみ単語を区切る。空文字列 (
''
) で EOF を送出する;引用符に囲んであっても、空文字列を解析しない。
POSIX モードで動作中の shlex
は以下の解析規則に従おうとします。
引用符を取り除き、引用符で単語を分解しない (
"Do"Not"Separate"
は単一ワードDoNotSeparate
として解析されます);引用符で囲まれないエスケープ文字群 (
'\'
など) は直後に続く文字のリテラル値を保持する;escapedquotes
でない引用符文字 ("'"
など) で囲まれている全ての文字のリテラル値を保持する引用符に囲まれた
escapedquotes
に含まれる文字 ('"'
など) は、escape
に含まれる文字を除き、全ての文字のリテラル値を保持する。エスケープ文字群は使用中の引用符、または、そのエスケープ文字自身が直後にある場合のみ、特殊な機能を保持する。他の場合にはエスケープ文字は普通の文字とみなされる。None
で EOF を送出する;引用符に囲まれた空文字列 (
''
) を許す。