組み込みのreadコマンドの代わりにこのカスタムread_char関数を使用する理由はありますか?

組み込みのreadコマンドの代わりにこのカスタムread_char関数を使用する理由はありますか?

私はbashとLinuxが苦手です。スクリプトを読み、次の関数を見つけました。

get_char()
{
    SAVEDSTTY=`stty -g`
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty $SAVEDSTTY
}

デフォルトでは実装に使用されます。続行するには任意のキーを押します。このような機能。

echo "Press any key to continue!"
char=`get_char`

readこれを達成するために組み込みコマンドを使用できることを知っています。たとえば、

read -rsn1 -p "Press any key to continue"

組み込みreadコマンドの代わりにこの機能を使用する理由はありますか?

答え1

問題の関数はget_charマルチバイト文字のキーを生成するのに問題があり、実際にはstty標準入力では機能しますが[1]でdd読み取られます/dev/tty。したがって、比較のために「固定」と単純化されたバージョンを使用します。

get_char(){
  _g=$(stty -g); stty raw -echo; dd count=1 2>/dev/null; stty "$_g"
}

k=$(get_char)との間のいくつかの違いは次のとおりread -rsn1 kです。

  1. 前者は移植可能です。dash、、bashなどzshで同じように機能し、read -rsn1でのみbash機能しますksh

  2. F1同様のキーを押すと、先行(Esc)を食べて後で使用するために残すのではなく、そのk=$(get_char)キーによって生成されたエスケープ文字()全体が設定されます。k複数の文字を生成するすべてのキーにも同じ内容が適用されます。F1^[OP^[OP

  3. Ctrl-CVINTR)、Ctrl-QVQUIT)、Ctrl-ZVSUSP)は元の制御文字(、または)をk=$(get_char)設定して、使用中にスクリプトを中断または一時停止します[2]。k\x03\x11\x1aread -rsn1


[1] 制御 tty から読む必要がある場合は、単に次のように使用できます。k=$(get_char </dev/tty)

[2]read -rsn1スクリプトが一時停止してCtrl-Z再起動すると、tty設定は復元されませんfg

行エディタがあるシェルで使用される場合の例 - それ自体でtty設定がめちゃくちゃになります。

$ bash -c 'read -rsn1 foo; echo "{$foo}"'
<Ctrl-Z>
[4]+  Stopped                 bash -c 'read -rsn1 foo; echo "{$foo}"'
$ fg
bash -c 'read -rsn1 foo; echo "{$foo}"'
f<Enter>
{f}
$
$ bash -c 'read -rsn1 foo; echo "{$foo}"'
<Ctrl-Z>
[4]+  Stopped                 bash -c 'read -rsn1 foo; echo "{$foo}"'
$ fg
bash -c 'read -rsn1 foo; echo "{$foo}"'
foo<Enter>
{f}
$ oo
bash: oo: command not found

または、tty設定を妨げないシェルで使用されている場合(例dash:):

$ bash -c 'read -rsn1 foo; echo "{$foo}"'
<Ctrl-Z>
[1] + Stopped                    bash -c "read -rsn1 foo; echo \"{\$foo}\""
$ <Blindly type f, g, Enter>bash -c "read -rsn1 foo; echo \"{\$foo}\""
{e}
$

関連情報