Как обработать клавишу Backspace при чтении?

Возможно, мой ответ будет полезный для кого-то:

#!/bin/bash

findpath=$(echo $1 | sed -r 's|(.*[^/]$)|\1/|')

# tarballs to check in
find $findpath -type f | while read tarball; do

    # get list of files in tarball (not dirs ending in /):
    if [ -n "$(file --mime-type $tarball | grep -e "application/jar")" ]; then

        jar tf $tarball | grep -v '/$' | while read file; do
            # get contents of file and look for string
            grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")

            if [ -n "$grepout" ]; then
                echo "*** $tarball has matching file ($file):"
                echo $grepout
            fi

        done

    elif tar -tf $tarball 2>/dev/null; then

        tar -tf $tarball | grep -v '/$' | while read file; do
            # get contents of file and look for string
            grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")

            if [ -n "$grepout" ]; then
                echo "*** $tarball has matching file ($file):"
                echo $grepout
            fi

        done

    else
        file=""
        grepout=$(grep $3 -e "$2" $tarball)

        if [ -n "$grepout" ]; then
            echo "*** $tarball has matching:"
            echo $grepout
        fi

    fi

done
9
20.08.2014, 23:48
3 ответа

Когда вы читаете целую строку с помощью простого , читайте (или читайте -r или другие опции, которые не влияют на это поведение), редактор строк, предоставленный ядром, распознает клавишу Backspace для стирания одного символа, а также несколько других команд (включая Return для завершения строки ввода и ее отправки). Клавиши быстрого доступа могут быть сконфигурированы с помощью утилиты stty . Считается, что терминал находится в режиме приготовления, когда активен его линейный редактор. В режиме raw каждый набранный на клавиатуре символ немедленно передается в приложение. В режиме приготовления символы хранятся в буфере, и в приложение передаются только полные строки.

Для того, чтобы остановить чтение после фиксированного количества символов с целью реализации чтения -n, bash должен переключиться в режим raw. В режиме raw терминал не производит никакой обработки клавиши Backspace (к моменту нажатия клавиши Backspace предыдущий символ уже был отправлен на bash), и bash тоже не производит никакой обработки (предположительно потому, что это дает большую гибкость, позволяя скрипту делать свою собственную обработку).

Вы можете передать опцию -e, чтобы включить собственный строчный редактор bash (readline, который является правильным строчным редактором, не похожим на крайне грубый редактор ядра). Так как bash делает редактор строк, он может перестать читать, как только получит требуемое количество символов.

9
27.01.2020, 20:05

Оболочка заменяет результат выражения в обратных ключах на строку. Но система имеет ограничения на длину списка аргументов для команды. Так что если у вас есть несколько тысяч файлов в/tmp, это пытается создать команду с тысячами имен в качестве аргумента. Это не удается.

Есть несколько способов сделать это проще. Поиск может выполнить команду. Большинство современных версий позволит разделить его и выполнить несколько отдельных команд touch , каждая под пределом.

find /tmp -exec touch {} +
-121--157869-

Использование read -e :

$ read -e -n 5
13acX

read -e означает, что для получения строки используется:

Readline (см. Редактирование командной строки ).

При этом можно отредактировать входные данные в любом из путей, которые можно ввести при записи в обычной командной строке, включая backspace, Home и т. д.

-121--43598-

read является bash builtin. (см. тип читать .) Вы можете найти документацию с помощью man bash :

   read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
   [...]
          -e     If the standard input is coming from a terminal, readline (see READLINE above) is used to obtain the line.
                 Readline uses the current (or default, if line editing was not previously active) editing settings.

или с помощью help read :

read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
      -e                use Readline to obtain the line in an interactive shell

Переключатель -e включает поддержку readline, которая в основном позволяет использовать все функции, доступные в командной строке, включая обработку backspace.

Поэтому read -en 5 должен делать то, что требуется.

1
27.01.2020, 20:05

Использование read -e :

$ read -e -n 5
13acX

read -e означает, что:

Readline (см. Редактирование командной строки ]) используется для получения строки.

Когда вы это сделаете, вы можете редактировать ввод любым способом, который вы использовали бы при вводе в обычном приглашении оболочки, включая backspace, Home и так далее.

8
27.01.2020, 20:05

Теги

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