;
標準入力から読み取り、文字を区切り文字として使用して入力行を終了し、ユーザーが行を編集できるようにする簡単なスクリプトを作成しようとしています 。
これが私のテストスクリプトです:
#!/bin/bash
while true; do
read -e -d ";" -t 180 -p "><> " srcCommand
if [ $? != 0 ]; then
echo "end;"
echo ""
exit 0
fi
case "$srcCommand" in
startApp)
echo "startApp command";;
stopApp)
echo "stopApp command";;
end)
echo ""
exit 0
;;
*)
echo "unknown command";;
esac
done
これは機能しますが、区切り文字「;」文字は印刷されません。
# bash test.sh
><> startApp
startApp command
><> stopApp
stopApp command
><> end
-e オプションを削除すると出力されます ;
が、ユーザーはバックスペース文字を使用して間違いを修正できず、エコーされた文字列は区切り文字の直後に表示されます。
# bash test.sh
><> startApp;startApp command
><> stopApp;stopApp command
><> end;
標準入力の読み取り中に区切り文字を印刷し、ユーザーが行を編集できるようにするにはどうすればよいでしょうか?
予想される動作は次のとおりです。
# bash test.sh
><> startApp;
startApp command
><> stopApp;
stopApp command
><> end;
ありがとう
答え1
zsh
ライン エディターにはさらに多くの機能があり、よりカスタマイズ可能な次のものを使用します。
#! /bin/zsh -
insert-and-accept() {
zle self-insert
# RBUFFER= # to discard everything on the right
zle accept-line
}
zle -N insert-and-accept
bindkey ";" insert-and-accept
bindkey "^M" self-insert
vared -p "><> " -c srcCommand
またはbash-4.3
それ以上の場合は、次のようなハックで同様のことを行うことができます。
# bind ; to ^Z^C (^Z, ^C otherwide bypass the key binding when entered
# on the keyboard). Redirect stderr to /dev/null to discard the
# useless warning
bind '";":"\32\3"' 2> /dev/null
# new widget that inserts ";" at the end of the buffer.
# If we did bind '";":";\3"', readline would loop indefinitely
add_semicolon() {
READLINE_LINE+=";"
((READLINE_POINT++))
}
# which we bind to ^Z
bind -x '"\32":add_semicolon' 2> /dev/null
# read until the ^C
read -e -d $'\3' -t 180 -p '><> ' srcCommand
このバージョンでは、 は;
常に現在のカーソル位置ではなく、入力バッファの末尾に挿入されることに注意してください。 をadd_semicolon
次のように変更します。
add_semicolon() {
READLINE_LINE="${READLINE_LINE:0:READLINE_POINT++};"
}
カーソルの位置に挿入し、右側にあるものはすべて破棄したい場合。または:
add_semicolon() {
READLINE_LINE="${READLINE_LINE:0:READLINE_POINT};${READLINE_LINE:READLINE_POINT}"
READLINE_POINT=${#READLINE_LINE}
}
カーソルの位置に挿入したいが、アプローチのように右側にあるものを保持したい場合zsh
。
;
in が不要な場合は$srcCommand
、たとえば後でいつでも削除できますが、 /srcCommand="${srcComman//;}"
で表示するにはウィジェットに挿入する必要があります。zle
readline