2017年1月25日 星期三

emacs 中 shell-command-to-string 的使用在 windows 平台上的一些想法/心得

shell-command-to-string 由於參數是呼叫平台本身預設 locale 的編碼,並非 unicode/utf-8 ,因此傳遞參數必需直接丟 cp950 編碼 ,印出時也必需是 cp950 ,不然會產生亂碼。 然而如果為了這個原因而必需維護 linux 及 windows 兩種程式版本,也是滿麻煩的。 我的建議是被呼叫端使用 base64 來解/編碼, emacs 端則以  (base64-encode-string (encode-coding-string XXX 'utf-8 t) t) 來傳送引數字串 XXX。

當然,多年以後可能會有比較深的領悟,覺得 emacs 也真是很辛苦的在向英文下相容這工作上下苦工。參考 Coding Systems in `shell-command` 上的說明,把 (setq default-process-coding-system '(utf-8 . utf-8)) 執行一下,就發現在 eshell 竟然可以直接輸入/輸出 utf8 字串了!! (cmd.exe 要在命令列輸入 unicode 也要另外設定,關鍵字 chcp ,網路上很多大大有詳解,就不在此掠美了。)

不過阿Q一點想,也是多學一些技能嘛~~

但是很多時候啟動一個應用程式的成本很高,不論是空間上或時間上的成本,這時候會有必要:
  1. 改寫原程式為 socket server / web service,然後你要讀懂原程式…
  2. 利用 netcat 在 linux 平台上直接解決。不過當初原程式可能沒有想到它會有來自網路的要求,這額外的邏輯,是否能在 script shell 的層次解決,可能還是有點不確定性… 而且 netcat 只能接受一次連線的樣子,這只能做為一個一次性的任務之用,比如測試之類的,參 Linux nc 常見用法
  3. 那還是要自己寫個 script 比較妥當(正解)
寫 script 來直接呼叫程式又有兩種思路:
  • 一種是由 ssh 呼叫,實際上是透過了 shell (sh/bash) 來執行程式,這比較偏向 linux-based 、 administrator-oriented 、 session-oriented 的解法,而且要搭配 session 或 tmux 來讓被呼叫的程式在背景執行,參 5 Ways to Keep Remote SSH Sessions and Processes Running After Disconnection ,再建立一個 tcp server 或 http server 來處理請求。
  • 另一種是由 createprocess 來呼叫,再建立一個 tcp server 或 http server 來處理請求。

console-based (stdin/stdout) vs socket-based

上面說的外部應用程式都是傳統的 console 程式,emacs畢竟原生的 socket 支援滿差的,所以思路比較受限。但是如果應用程式的原生語言對 sockets 的支援不錯的話,其實建議直接寫 socket-based 程式,以 line 導向做 IO。甚至對 xml/jason 支援不錯的話,以 xml/jason 導向做IO,以避掉 EOF 的決定條件問題。


沒有留言:

張貼留言