編集3

編集3

PressはEnterまだ区切り文字を実行しますが、readコンソールのスクロールを中断することなくコマンドが静かに終了します。デフォルトでは、Aはread -sエンドラインにのみ影響します。

答え1

n1読み取り文字が入力されると、読み取りが読み取り変数(オプションを含む)をnullに設定することを知って、次のことができます。

#!/bin/bash

while IFS= read -srn1 a ;do
    [[ "${a+x$a}" = "x" ]] && break
    var=$var$(printf '%s' "$a")
    printf '%s' "$a"
done
printf '\n%s\n' "$var"

sttyまたは他の文字でキャプチャされた文字はバイト値に変換されません。

以下を除くすべての制御文字:

  1. ^C(ASCII 03 ETX)
  2. ^J(ASCII 0A LF)
  3. ^M(ASCII 0D CR)
  4. ^Z(ASCII 1Aサブ)
  5. ^\(ASCII 1C FS)

前の文字のバックスペース文字を実際に「確認」するには、次のループを追加してvarを印刷します(上記のコードの直後)。

echo
while IFS= read -srn1 a; do
    printf '%s' "$a"
    sleep 0.5
done <<<"$var"

編集3

バックスペースキーを使用して文字をキャプチャし、変更された文字列を印刷せずに文字を削除するには、次のようにします。

#!/bin/bash

while IFS= read -srn1 a ;do
    [[ "${a+x$a}" = "x" ]] && break

    if [[ $a = $'\x7f' || $a = $'\x08' ]]; then
        var=${var%?}
        [[ $a = $'\x7f' ]] && printf '\x0d%s \x08' "$var"
        [[ $a = $'\x08' ]] && printf '\x0d%s ' "$var"
    else
        var=$var$(printf '%s' "$a")
    fi

    printf '%s' "$a"
done
printf '\n%s\n' "$var"
printf '%s' "$var" | od -An -tx1

while IFS= read -srn1 a; do
    printf '%s' "$a"
    sleep 0.5
done <<<"$var"

答え2

zshの行エディタを呼び出すことができます(完全に設定可能であり、多くの場合、より多くの機能があります)。高級readlineより(bashで呼び出すことができますread -e)たとえば、次のようになります。

var=$(
  saved_tty=$(stty -g)
  var=default-value zsh -c '
    zle-line-finish() { # hook run upon leaving the line editor (zle)
      CURSOR=$#BUFFER # move the cursor to the end
      zle -R          # force a redraw of the editor
      printf %s $BUFFER # output value on stdout
      kill $$ # kill ourself to prevent zle cleanup
    }
    zle -N zle-line-finish
    vared -p "Text before [" var'
  # we need to restore the tty settings by ourselves, as we prevented zsh
  # from doing so when killing it:
  stty "$saved_tty"
)
printf '] Text after\n'

printf 'var = "%s"\n' "$var"

実行後に以下を提供します。

Text before [value edited] Text after
var = "value edited"

これでキーをシェルコードウィジェットにバインドできるようになりましたが、bashウィジェットを実行する前に現在の行の内容が消去されるため、ハンドラでプロンプトと値を再描画する必要がありますReturn

var=$(prompt="Text before [" var=default-value bash -c '
  bind -x '\''"\r":printf >&2 %s "$prompt$READLINE_LINE";  printf %s "$READLINE_LINE"; exit'\'' 2> /dev/null
  IFS= read -rep "$prompt" -i default-value')

printf '] Text after\n'
printf 'var = "%s"\n' "$var"

関連情報