Bourne Shell 中 read 的 silent mode

這兒近三個月沒發表技術性的文章,實在情非得已。

今年負責的專案,是典型的 one man force 模式,
從先期研究到兩階段開發一手包辦,歷經八個月著實累積不少知識。
但是礙於 NDA (Non-disclosure agreement),在開發期間無法提及太多技術細節。

趕在年底休假前,將成果交付給合作單位,
現在可以暢所欲言來談技術細節了…(去它的 NDA)

先挑非核心技術來說,由於需求規格之一是無需安裝,
且及不倚賴其他 run-time library & framework 的 “綠色軟體”。

故 UNIX-like 環境下號稱 3P 的 Perl/PHP/Python 便無用武之地。
一切只能用 shell script 來實作,而且還是 POISX 標準的 Bourne Shell (sh)。

Linux 使用案例
其中一個比較典型的案例,
是當使用者於互動模式輸入某些機敏資料時 (如:password 或 pass phrase),
比較好的做法是將使用者的輸入隱藏不顯示。

若是 GNU/Linux 的 Bourne Shell,則可用以下指令讀取鍵盤輸入並存入變數:

read -s VARIABLE

如此即可達成較安全的互動模式。

問題來了,FreeBSD 下又如何?
但 FreeBSD 的 Bourne Shell 內建 read 並不支援 silent mode -s 參數;
因此鍵盤輸入將原封不動的回應在 terminal/console 上,這顯然不符需求。

為此,動員了不少人力去尋找相關的 solution;
但由於工作單位裡沒啥人碰 FreeBSD,後來還是自己找到了解法 – stty

解法
stty 指令原意是 set tty,用來調整 terminal 的組態與行為屬性,
以滿足各種環境的標準。

其中有個參數 echo (-echo) 便是用來開啟 (或關閉) 鍵盤輸入的回應。
簡單來說,讀取機敏資料時只要先抑制鍵盤輸入的回應,
使用 read 指令讀取後再開啟即可,像這樣:

stty -echo
read VARIABLE
stty echo

但這是單純且略嫌粗糙的做法。

比較好的做法,是先儲存 stty 狀態,再行變更:

OLD_STTY=`stty -g`
stty -echo
read VARIABLE
stty ${OLD_STTY}

如此即可達成與 GNU/Linux 下 read -s 相同的效果,且事後不影響環境設定值。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *