使用 STDERR KSH 设计基于文本的菜单

使用 STDERR KSH 设计基于文本的菜单

是否可以使用 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 创建基于动态文本的菜单? (或解决我的问题的其他方法)

答案1

重新审视一个老问题以提供一个更少的努力执行。事实上,两个问题合二为一:

a)STDERRselect命令中处理

selectb) 更改命令中显示的项目的外观

替代方法已经得到解决——即不使用该select命令的解决方案。所以我不会走这条路。

select命令非常方便,因为它会自动处理选项的列布局,基本上您所要做的就是案例处理。所以而不是有点重新发明轮子对于许多简单的情况来说,它可以是一个很好的解决方案。

a) 处理STDERR

您已经有了原始问题中的解决方案:重定向STDERRSTDOUT.

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

两个文件句柄都提供相同的功能,因此恕我直言,没有理由摆弄这个。使用STDERRforselect实际上是一个好主意,因为您不会破坏您的内容,STDOUT并且可以将其用于其他目的,例如重定向。

selectb) 更改命令中显示的项目的外观

解决方案为提高如果您采用以下语法,那么这里的输出也非常简单:

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 序列可能很棘手,需要进一步测试。

答案2

另一种方法是避免选择并制作菜单。为每个菜单选项(action1.sh,xxx.sh和passwords.sh)制作一个shell脚本,在menu.cfg中配置它们:

1 action1 Do action 1
2 xxx Another nice item for you
3 passwords Very dangerous

并使用读取 menu.cfg 的脚本启动菜单

#!/bin/ksh
formatmenu()
{
if [ $# -eq 2 ]
then
            printf "%d) %s\n" ${1} "$2" 
    else
            printf "    %s\n" "${1}"
    fi
}
showMenu()
{
    echo "Enter 0 to stop or choose beneath."
    cat menu.cfg|while read option proces description
    do
            formatmenu ${option} ${proces}
            formatmenu "${description}"
    done
}

getAction()
{
    showMenu
    while [ ${CHOICE} -eq -1 ]
    do
            read CHOICE?"Please enter a digit: "
            if [[ ${CHOICE} != +([0-9]) ]]
            then
                    CHOICE=-1
                    echo "Invalid, please enter a digit."
            fi
    done
}

performAction()
{
    if [ ${CHOICE} -eq 0 ]
    then
            return
    fi
    process=$(grep "^${CHOICE} " menu.cfg | cut -d\  -f2)


        echo "===${process}.sh==="
        . ${process}.sh
}

# Start

export CHOICE=-1
getAction
echo choice=${CHOICE} 
performAction
exit 0

相关内容