Bash

KSH 使用 STDERR 設置基於文本的菜單樣式

  • April 13, 2020

是否可以使用 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)STDERRselect命令中處理

b) 更改select命令中顯示的項目的外觀

已經解決了替代方法——即不使用select命令的解決方案。所以我不會走這條路。

select命令非常方便,因為它會自動處理選項的列佈局,基本上您所要做的就是案例處理。因此,與其重新發明輪子,不如說它可以成為許多簡單案例的好解決方案。

a) 處理STDERR

您已經有了原始問題中的解決方案:重定向STDERRSTDOUT.

select choice in ...; do
...
done 2>&1

兩個文件句柄都提供相同的功能,因此恕我直言,沒有理由擺弄這個。使用STDERRforselect實際上是一個好主意,因為您不會破壞您的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 序列可能很棘手,需要進一步測試。

引用自:https://unix.stackexchange.com/questions/38200