Lispプログラムがshellを実行して、ユーザーが指定したファイル名を含むコマンドを与える必要がある場合が時折あります。これらのプログラムは任意の有効なファイル名をサポート可能であるはずです。しかしshellは特定の文字を特別に扱い、それらの文字がファイル名に含まれているとshellを混乱させるでしょう。これらの文字を処理するためには関数shell-quote-argument
を使用します。
この関数は実際のコンテンツがargumentであるような引数を表す文字列をshellの構文でリターンする。リターン値をshellコマンドに結合して実行のためにそれをshellに渡すことにより、信頼性をもって機能するはずである。
この関数が正確に何を行うかはオペレーティングシステムに依存する。この関数はそのシステムの標準shellの構文で機能するようデザインされている。非標準のshellを使用する場合には、この関数を再定義する必要があるだろう。セキュリティへの配慮を参照のこと。
;; この例はGNUおよびUnixシステムでの挙動を示す (shell-quote-argument "foo > bar") ⇒ "foo\\ \\>\\ bar" ;; この例はMS-DOSおよびMS-Windowsでの挙動を示す (shell-quote-argument "foo > bar") ⇒ "\"foo > bar\""
以下はshell-quote-argument
を使用してshellコマンドを構築する例:
(concat "diff -u " (shell-quote-argument oldfile) " " (shell-quote-argument newfile))
オプションのposix引数が非nil
の場合には、そのシステムのシェルに関わらず、argumentはPOSIXシェルのクォート規制によってクォートされる。これは一般的にはPOSIXシェルが要求されるリモートホスト上でシェルを実行する際に役に立つだろう。
(shell-quote-argument "foo > bar" (file-remote-p default-directory))
以下の2つの関数はコマンドライン引数の文字列のリストを単一の文字列に結合したり、単一の文字列を個別のコマンドライン引数のリストへ分割するために有用です。これらの関数は主にミニバッファーでのユーザー入力であるLisp文字列をmake-process
、call-process
やstart-process
に渡す文字列引数のリストへ変換したり、そのような引数のリストをミニバッファーやエコーエリアに表示するためのLisp文字列に変換することを意図しています。(call-process-shell-command
を使用して)shellが呼び出される場合には、引数を依然としてshell-quote-argument
で保護する必要があることに注意。combine-and-quote-strings
はshellの評価から特殊文字を保護することを意図していない。
この関数はダブルクォート、シングルクォートと同様にバックスラッシュによるクォートにも注意を払い、stringを部分文字列に分割する。
(split-string-shell-command "ls /tmp/'foo bar'") ⇒ ("ls" "/tmp/foo bar")
この関数はsplit-string
(文字列の作成を参照)が行うように、正規表現separatorsにたいするマッチでstringを部分文字列に分割する。さらに加えてその部分文字列からクォートを削除する。それから部分文字列のリストを作成してリターンする。
separatorsが省略またはnil
の場合のデフォルトは"\\s-+"
であり、これは空白文字構文(構文クラスのテーブルを参照)をもつ1つ以上の文字にマッチする正規表現である。
この関数は2つのタイプのクォートをサポートする。1つは文字列全体をダブルクォートで囲う"…"
のようなクォートで、もう1つはバックスラッシュ‘\’によるエスケープで文字を個別にクォートするタイプである。後者はLisp文字列内でも使用されるので、この関数はそれらも同様に扱うことができる。
この関数はlist-of-stringsの各文字を必要に応じてクォートして単一の文字列に結合する。これはさらに各文字ペアーの間にseparator文字列も挿入する。separatorが省略またはnil
の場合のデフォルトは"
"
。リターン値はその結果の文字列。
list-of-strings内のクォートを要する文字列には、部分文字列としてseparatorを含むものが該当する。文字列のクォートはそれをダブルクォートで"…"
のように囲う。もっとも単純な例では、たとえば個別のコマンドライン引数からコマンドをコンス(cons)する場合には、埋め込まれたブランクを含む文字列はそれぞれクォートされるだろう。