Как правило, это можно сделать, установив termios(3)
/stty(1)
VEOL
/ eol
специальный символ («альтернативный конец -строки -» )в Tab. В системах, которые его поддерживают, также можно использовать VEOL2
/ eol2
.
К сожалению, встроенная -оболочка read
всегда будет пытаться читать до новой строки (или другого разделителя в bash
, если использовался -d
, без поддержки нескольких разделителей ).
Один из способов, который можно обойти, заключается в использовании подстановки команды 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"
сохранят и восстановят настройки терминала.
trap : INT
и trap - INT
не позволят Control -C убить оболочку/цикл (со всеми осложнениями и специфичным для оболочки -поведением, которое это влечет за собой ), и позволят ему только убить dd
и подстановка команды.
$(...; echo x)
, за которым следует ${var%x}
, является уловкой, предотвращающей удаление завершающего символа новой строки из подстановки команды; это необходимо для того, чтобы иметь возможность различать, когда пользователь нажал только Enter
для пустой переменной, и Control-C
или Control-D
для выхода из цикла.
Наконец, ${var%[$'\n\t']}
удалит завершающую новую строку или табуляцию из переменной. В оболочках, которые не поддерживают строки $'...'
, такие как dash
или yash
, их можно заменить на :
nltab='<literal tab here>
'
...
var=${var%[$nltab]}