シェルスクリプトで次のような場合:
read my_variable
Enter入力を保存するキーです。
機能を削除せずにTab同じことを行う方法はありますか?EnterEnter
答え1
read -e
少し過剰かもしれませんが、ユーティリティでReadlineツールを有効にすることで取得できますread
。その時点で、目的の結果を得るためにキーを押すだけです。
しかし注意してください。 Readlineは、単純化のために完成、記録などの他の多くの機能も提供しますread my_variable
。これらの機能が必要ない場合は、明示的にキーバインディングを消去し、不要な機能を無効にする必要がありますread -e
。
コマンドラインの概念証明の例:
(bind 'TAB: accept-line'; IFS= read -re var && echo "$var" || echo ko)
bind
警告は表示されますが、スクリプトでもこれを行うことができます(リダイレクトを使用して警告を沈黙させることができます2>/dev/null
)。
スクリプトのコマンドの代替案は、bind
影響を及ぼすスクリプトを呼び出す前にカスタム inputrc ファイルを提供することです。実際の文書は必要ありません。ここの文書で十分です。
上記の例はスクリプトによって実装されています。
#!/bin/bash
export INPUTRC=/dev/fd/3
script2.sh 3<<EOF
TAB: accept-line
set history-size 0
EOF
# this example 'inputrc'-like file also disables history support
上記のスクリプトはカスタムinputrcファイルをファイル記述子3のHere Documentとして準備し、実行中のシェルは環境変数の指示に従ってファイルを読み取りますscript2.sh
。INPUTRC
それからscript2.sh
:
#!/bin/bash
echo start
bind -q accept-line 2>/dev/null # shows which keys are configured to accept input
IFS= read -re var && echo "$var" || echo ko
echo end
入力を待つ前に、read
スクリプトは次のように印刷します。
accept-line can be invoked via "\C-i", "\C-j", "\C-m".
ディスプレイTab(Ctrl-I例:上記のもの)\C-i
は、行のプラス(キャリッジリターンなど)または改行()を許可します。ReturnCtrl-MCtrl-J
もう少し「実際」の例を次に示します。
#!/bin/bash
bind 'TAB: accept-line' &>/dev/null
echo "enter your name:"
IFS= read -re var
echo "your name is: $var"
この道に降りたらぜひご覧くださいReadlineユーザーガイド、あなたの項目の1つ以上が減少しましたman bash
。set convert-meta off
非ASCII文字のより良いサポートのために、これらの設定について特に言及する価値があります。
答え2
通常、これを行うには、//特殊文字(「代替行末」)をtermios(3)
Tabに設定することです。これをサポートするシステムでは/も使用できます。stty(1)
VEOL
eol
VEOL2
eol2
残念ながら、read
組み込みシェルは常に改行文字(またはbash
ifで-d
使用されている他の区切り文字、複数の区切り文字はサポートされていません)を読み取ろうとします。
この問題を解決する1つの方法は、var=$(dd count=1 bs=big)
代わりにコマンド置換を使用することですread
。以下はこれの例です。
while :; do
t=$(stty -g)
stty eol ^I
trap : INT
var=$(dd bs=10k count=1 2>/dev/null; echo x)
stty "$t"
trap - INT
var=${var%x}
[ "$var" ] || break
var=${var%[$'\n\t']}
printf '{%s}\n' "$var"
done
端末設定を保存して復元しますt=(stty -g)
。stty "$t"
Control-Cがシェル/ループ(およびそれに伴うすべての合併症およびシェル関連の動作)を終了するのを防ぎ、コマンド置換のみを終了させますtrap : INT
。trap - INT
dd
以下は、コマンドの置き換えから末尾の改行が削除されるのを防ぐためのトリック$(...; echo x)
です。これは、単に空の変数を押すか、ループを終了するユーザーを区別できるようにするために必要です。${var%x}
Enter
Control-C
Control-D
最後に、${var%[$'\n\t']}
末尾の改行またはタブが変数から削除されます。 orなどの文字列をサポートしていないシェルでは、$'...'
これを次のように置き換えることができます。dash
yash
nltab='<literal tab here>
'
...
var=${var%[$nltab]}