For Development HEAD DRAFTSearch (procedure/syntax/module):

12.78 text.sh - シェルのテキストユーティリティ

Module: text.sh

このモジュールは、シェルスクリプト風のスクリプトを書いている時に便利な いくつかのユーティリティを提供します。

Function: shell-escape-string str :optional flavor

{text.sh} strがシェルのコマンドライン引数解析に影響を与える文字を含んでいる場合、 それらがシェルによって解釈されないようにエスケープされた文字列を返します。 そうでなければstr自体を返します。

省略可能なflavor引数はシンボルを取り、プラットフォームを指定します。 現在はwindowsposixが指定可能です。シェルが エスケープやクオートを処理する方法がこの二つのプラットフォームで大きく 異なるからです。windowsフレーバーの場合はMVCSランタイムの 引数パージングに合わせ、posixフレーバーの場合はIEEE Std 1003.1に 合わせます。 省略された場合は、プロセスが走っているプラットフォームが デフォルトの値となります。(Cygwinはposixとみなされます。)

自分でコマンドライン文字列を組み立てる必要がある場合に使ってください。 (単一のコマンドライン文字列でなく、コマンドライン引数のリストを渡す場合は エスケープの必要はありません。引数はシェルを通さずに子プロセスに渡される からです。)

(註: Windowsでバッチファイル(*.bat*.cmd)を起動する場合は、 コマンドラインが異なる方法でパーズされることに注意してください。 特に、あらゆる場合に対して安全に引数をエスケープする方法が無いことが 知られています。バッチファイルに渡す引数を用意する場合は独自にそれが 安全であることを確かめて下さい。sys-execのエントリも参照のこと (プロセス管理))。

Function: shell-tokenize-string str :optional flavor

{text.sh} シェルがやるように、文字列strを引数リストに分割します。

(shell-tokenize-string "grep -n -e \"foo bar\" log")
 ⇒ ("grep" "-n" "-e" "foo bar" "log")

省略可能なflavor引数はシンボルwindowsposixを取り、 構文を指定します。windowsの場合はMVCSランタイムの 引数パージングに合わせ、posixフレーバーの場合はIEEE Std 1003.1 Shell Command Languageに合わせます。 省略された場合は、プロセスが走っているプラットフォームが デフォルトの値となります。(Cygwinはposixとみなされます。)

この手続きはシェルの変数置換のような高度な機能は持っていません。 もしそういった解釈が必要なメタ文字に出会った場合はエラーが投げられます。 言い換えれば、メタ文字はstrの中で全て適切にクオートされている 必要があります。

(shell-tokenize-string "echo $foo" 'posix)
  ⇒ signals error

(shell-tokenize-string "echo \"$foo\"" 'posix)
  ⇒ still signals error

(shell-tokenize-string "echo '$foo'" 'posix)
  ⇒ ("echo" "$foo")

(shell-tokenize-string "echo \\$foo" 'posix)
  ⇒ ("echo" "$foo")
Macro: shell-case expr clause …

{text.sh} このマクロは、シェルのcase組み込みコマンドを実装します。 各clauseは次の形式のいずれかでなければなりません。

  • (pattern body …)
  • ((pattern …) body …)
  • (else body …)

また、elseフォームはあるなら最後のclauseでなければなりません。

まずexprが評価されます。値は文字列でなければなりません。 次に各clauseが順番に吟味され、exprの値がpatternにマッチした 場合にそのclauseが選ばれてbody …が評価され、 最後の式の値が全体の値となります。

いずれのpatternもマッチしなかった場合、else節が与えられていれば そのbody …が評価されて最後の式の値が全体の値となり、 else節がなければ未定義値が返されます。

マッチはglobと同じ方法で行われます (ディレクトリ参照)。 例えば、pattern"abc*"であれば、 exprの値が"abc""abcd""abccc"等である 場合にマッチし、pattern"a[bcd]"であれば、 "ab""ac""ad"がマッチします。

次のシェルのcaseコマンドは:

case $arg in
  foo*)        process_foo $arg;;
  ba[rz]|quux) process_bar $arg;;
   *)          process_other $arg;;
esac

次のように書き直せるでしょう。

(shell-case arg
  ["foo*" (process-foo arg)]
  [("ba[rz]" "quux")  (process-bar arg)]
  [else (process-other arg)])

同等の処理は例えばrxmatch-caseを使って書くこともできますが、 シェルのglobパターンを正規表現に置き換えてゆくのは面倒ですし ミスが入り込む余地もあります。 既存のシェルスクリプトをGaucheで最実装する場合にはshell-caseは非常に便利な ツールになるでしょう。

Function: shell-match pattern str

{text.sh} これはshell-caseのマッチ部分の機能だけを独立して取り出したものです。 patternはglobパターンを表す文字列、もしくは globパターンを表す文字列のリストで、 strは文字列でなければなりません。

strの値がpattern (もしくは、2番めの形式の場合はpatternのいずれかに) マッチしたら#tを、そうでなければ#fを返します。



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT