コマンドの実行結果を文字列に設定する
ちょwまた難しいことをおっしゃる。
とりあえず、プロセスであるとかOSが絡む話はCommon Lispでは規定されていないので、各Common Lispの実装依存になってしまいます。ここでは自分の利用しているSBCLについてのみ考えます。
とりあえず、外部のプログラムを実行する方法を調べてみるとsb-ext:run-programが使えるようです。
さっそく試してみました。
(sb-ext:run-program "/bin/ls" '("/") :output t) #<SB-IMPL::PROCESS :EXITED 0>
あれ?実行はされてるみたいですが出力が出ません。
slimeでやってるから駄目なのかなと思って普通に端末からsbclを実行してみると。
(sb-ext:run-program "/bin/ls" '("/") :output t) bin cdrom etc initrd.img lost+found mnt proc sbin srv tmp var boot dev home lib media opt root selinux sys usr vmlinuz #<SB-IMPL::PROCESS :EXITED 0>
出力されました。
どうやらslime上で出力するには何か一工夫必要そうです。
調査してみると、run-programのキーワード引数:outputに:streamを指定してsb-ext:process-outputの中で実行すれば動作するっぽい。
(with-open-stream (files (sb-ext:process-output (sb-ext:run-program "/bin/ls" '("/" ) :output :stream))) (loop :for line = (read-line files nil nil) :while line :do (princ line) (terpri) )) bin boot cdrom dev etc home initrd.img lib lost+found media mnt opt proc root sbin selinux srv sys tmp usr var vmlinuz NIL
出来た!
でも出力が出来ただけ。文字列にはまだ出来てないので修正がまだ必要ですね。
と思っていたら、どうやらこの方法は無駄に苦労しているだけだったという罠でした。コメントで教えて頂いた方法の方がずっと良さそうです。
(with-output-to-string (out) (sb-ext:run-program "/bin/ls" '("/") :output out)) "bin boot cdrom dev etc home initrd.img lib lost+found media mnt opt proc root sbin selinux srv sys tmp usr var vmlinuz "
こんな感じで文字列にすることは出来ました。ありがとうございます。