KSH моделирование основанного на тексте меню с помощью STDERR

Вы могли записать свои изменения в файле/файлах в памяти (tmpfs) и затем выписать эти изменения в диске каждые 10 секунд.

4
13.04.2017, 15:36
2 ответа

Возвращаемся к старому вопросу, чтобы обеспечить меньшую реализацию. По сути, два вопроса в одном:

a )Обработка STDERRв команде select

b )Изменение внешнего вида элементов, показанных в команде select

Уже рассмотрены альтернативные подходы --, то есть решения, в которых не используется команда select. Поэтому я не пойду по этому пути.

Команда selectочень удобна тем, что она автоматически обрабатывает расположение столбцов ваших опций, и, по сути, все, что вам нужно сделать, это обработка регистра. Поэтому вместо того, чтобы заново изобретать колесо , это может быть хорошим решением для многих простых случаев.

a )Обращение сSTDERR

У вас уже есть решение в исходном вопросе :перенаправить STDERRна STDOUT.

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

Оба дескриптора файлов предлагают одинаковые возможности, поэтому, ИМХО, нет причин возиться с этим. Использование STDERRвместо selectна самом деле хорошая идея, так как вы не засоряете свой 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

Очевидно, что если вы добавите разметку к элементам, вам придется очищать результат перед его использованием; в приведенном выше примере перед использованием выбранного choiceвам нужно будет сделать что-то вроде

choice=${choice#\E[+([^m]*)m}
choice=${choice%\E[+([^m]*)m}

, чтобы удалить последовательности ANSI.

Примечание.:игра с последовательностями ANSI может быть сложной и требует дальнейшего тестирования.

1
13.04.2020, 12:54

Иначе избегает выбора, и сделайте меню. Сделайте сценарий оболочки для каждого пункта меню (action1.sh, xxx.sh и passwords.sh), настройте их в 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
0
27.01.2020, 21:06

Теги

Похожие вопросы