KSH 使用 STDERR 設置基於文本的菜單樣式
是否可以使用 select 命令格式化 STDERR 以獲得更好看的菜單?
我有一個簡單的選擇
select oChoice in $(<tempMenu.menu) ; do case "$oChoice" in *) break ;; esac done
我試過一個技巧,比如:
exec 3>&1 select ... ... done 2>&1 1>&3 | sed 's/^/NICE OUTPUT /'
但我不能使用轉義序列(即顏色),例如
... done 22>&1 1>&3 | sed 's/^/\033[1;33m\033[44mNICE OUTPUT /' or done 22>&1 1>&3 | sed 's/^/\\033[1;33m\\033[44mNICE OUTPUT /'
轉義序列沒有被轉義,STDOUT 也被改變,因為我也定制了 PS3。
PS3="$(print \\n\\r)# $(print "\\033[1;33m\\033[44m")"$QUESTION"$(print "\\033[0m\\033[1;1m\\033[44m") `tput sc` $(print "") #$(print "") # $(print "") # Status: $status $(print "") # $(print "") #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ `tput rc` "
據我了解(僅在螢幕上顯示 stderr,但將 stdout 和 stderr 都寫入文件)我無法將 STDERR 與 STDOUT 分開,那麼,是否有更智能的方法來創建僅使用 STDOUT 的基於文本的動態菜單?(或以其他方式解決我的問題)
重新審視一個舊問題以提供更少的實現。事實上,兩個問題合而為一:
a)
STDERR
在select
命令中處理b) 更改
select
命令中顯示的項目的外觀已經解決了替代方法——即不使用
select
命令的解決方案。所以我不會走這條路。該
select
命令非常方便,因為它會自動處理選項的列佈局,基本上您所要做的就是案例處理。因此,與其重新發明輪子,不如說它可以成為許多簡單案例的好解決方案。a) 處理
STDERR
您已經有了原始問題中的解決方案:重定向
STDERR
到STDOUT
.select choice in ...; do ... done 2>&1
兩個文件句柄都提供相同的功能,因此恕我直言,沒有理由擺弄這個。使用
STDERR
forselect
實際上是一個好主意,因為您不會破壞您的STDOUT
,並且可以將其用於其他目的,例如重定向。b) 更改
select
命令中顯示的項目的外觀如果您採用以下語法,那麼增強輸出的解決方案在這裡也很簡單:
select choice in $(...); do ... done
用於
$(...)
執行. _ _select items
例如,您可以在 ANSI 終端上為它們著色:
$(for i in *; do print "\[E31m$i\E[0m"; done)
或呼叫著色函式(在其他情況下可重用):
function colourise_diritems { typeset dir=$1 item for item in $dir/*; do if [[ -d $item ]]; then print "\E[31m$i\E[0m" elif [[ -f $item ]]; then print "\E[32m$item\E[0m" ... fi done } select choice in $(colourise_diritems $PWD); do ... done
顯然,如果您向項目添加標記,則必須在使用之前清理結果;在上面的範例中,在使用 selected 之前
choice
,您必須執行類似的操作choice=${choice#\E[+([^m]*)m} choice=${choice%\E[+([^m]*)m}
刪除 ANSI 序列。
注意:使用 ANSI 序列可能很棘手,需要進一步測試。