command-substitutionという関数があります。けっこう便利。
上の関数を、バッファを介せずにCLの標準関数だけで作れないかなーと 思ってこんなものを書いてみた。まだまだ処理系依存。
やっていることは以下の3点
- 外部コマンドを呼び出して、結果をファイルに保存
- 保存したファイルの中身を文字列ストリームに流す
- ついでに右端の空白文字を取り除く
(defun cat (file &optional stream)
  "print file contents."
  (with-open-file (fp file)
    (do ((ch (read-char fp nil nil)
             (read-char fp nil nil)))
        ((null ch))
      (princ ch stream))))
(defun shell-command-to-string (command)
  "Execute shell command COMMAND and return its output as a string."
  (let ((outfile (make-temp-file-name "xyzzycmd-")))
    (unwind-protect
        (with-output-to-string (stream)
          (call-process command :output outfile
                        :show :minimize :wait t)
          (cat outfile stream))
      (delete-file outfile))))
(defun command-substitution (command)
  (string-right-trim '(#\SPC #\TAB #\LFD)
    (shell-command-to-string command)))
結果:
(command-substitution
 (format nil "ls -1 ~A"
        (merge-pathnames "*.exe" (user-homedir-pathname))))
=>
"C:/home/xyzzy/xyzzy.exe
C:/home/xyzzy/xyzzycli.exe
C:/home/xyzzy/xyzzyenv.exe"
(command-substitution "echo 舌足らずなブログ")
=> "舌足らずなブログ"
意図してなかったが日本語も通るようだ。
ちなみにshell-command-to-stringという関数名はEmacsから。
後は
- 一時ファイルを作成する関数 (make-temp-file-name)
- 外部プロセスを処理する関数 (call-process)
 
0 件のコメント:
コメントを投稿