У меня есть простая echo
распечатка, которую я добавил к своему .bashrc
:
echo "$(tput setaf 2)Wake up....."
sleep 2s
reset
sleep 2s
echo "$(tput setaf 2)Wake up....."
sleep 2s
reset
echo "$(tput setaf 2)Wake up neo....."
sleep 2s
echo "$(tput setaf 2)The Matrix has you......"
sleep 2s
reset
echo "$(tput setaf 2)Follow the white rabbit......"
sleep 2s
reset
cmatrix
Это печатает сообщение на терминал, но я хочу, чтобы оно выглядело так, как будто оно набирается, с постоянной задержкой между символами.
command-line
bash
echo
SimplySimplified
источник
источник
Ответы:
Это не работает с Wayland; если вы используете Ubuntu 17.10 и не переходили на Xorg при входе в систему, это решение не для вас.
Вы можете использовать
xdotool
для этого. Если задержка между нажатиями клавиш должна быть постоянной , это так просто:Это происходит
something
с задержкой в100
миллисекунды между каждым нажатием клавиши.Если задержка между нажатиями клавиш должна быть случайной , скажем, от 100 до 300 миллисекунд, все становится немного сложнее:
Этот
for
цикл проходит через каждую букву строки , сохраненной в переменнойtext
, либо печатиkey <letter>
илиkey space
в случае пространства с последующимsleep 0.
и случайное число между 1 и 3 (xdotool
«секsleep
интерпретирует число в секундах). Затем выводится весь вывод циклаxdotool
, который печатает буквы со случайной задержкой между ними. Если вы хотите изменить задержку, просто измените деталь, будучи нижним и верхним пределом - на 0,2-0,5 секунды это будет .(RANDOM%x)+y
y
x-1+y
(RANDOM%4)+2
Обратите внимание , что этот подход не печатать текст, а тип его так же , как пользователь будет делать, синтезируя одиночные нажатия клавиш. В результате текст печатается в текущем окне; если вы измените фокус, часть текста будет напечатана во вновь сфокусированном окне, что может быть или не быть тем, что вы хотите. В любом случае посмотрите на другие ответы здесь, все из которых являются блестящими!
источник
Я попробовал xdotool после прочтения ответа @sert, но по какой-то причине не смог заставить его работать. Итак, я придумал это:
Передайте текст в приведенный выше код, и он будет напечатан как напечатано. Вы также можете добавить случайность, заменив
sleep 0.1
наsleep 0.$((RANDOM%3))
.Расширенная версия с поддельными опечатками
Эта версия будет время от времени вводить фальшивую опечатку и исправлять ее:
источник
while IFS= read -r line; do for (( i = 0; i < ${#line}; i++ )); do sleep 0.1; printf "%s" "${line:i:1}"; done; echo; done
(замените;
на новые строки и хорошие отступы при необходимости).IFS= read -r
Иprintf "%s"
убедитесь , что пробелы и специальные символы не обрабатываются по -другому. И вgrep
каждой строке разделять на символы не нужно - достаточно простоfor
цикл над каждым символом в строке.Вы упоминаете о постоянной задержке между символами, но если вы действительно хотите, чтобы он выглядел так, как будто он напечатан, время не будет идеально согласованным. Для этого вы можете записать свой собственный набор текста с помощью
script
команды и воспроизвести его с помощьюscriptreplay
:Запись останавливается нажатием CTRL-D.
Передав
-t
параметр,script
он также генерирует информацию о времени, которую я перенаправил вscript.timing
файл. я прошелsed d
как командуscript
поскольку это просто способ поглотить ввод (и эту запись нажатия клавиш) без побочных эффектов.Если вы также хотите сделать все
tput
/reset
материал, вы можете сделатьscript
запись для каждой из ваших строк и воспроизвести их, чередуя с командамиtput
/reset
.источник
Другая возможность - использовать Demo Magic или, если быть точнее, только функцию печати этой коллекции скриптов, которая в основном составляет
Под капотом используется pv , который, конечно же, можно использовать и для непосредственного получения желаемого эффекта, основная форма выглядит следующим образом:
источник
echo
неpv
просто использовать ,pv -qL20 <<< "Hello world"
если ваша оболочка опор herestrings.В соответствии с моим ником я могу предложить другое решение:
Выглядит странно, не правда ли?
-MTime::HiRes=usleep
импортирует функциюusleep
(микросекундный сон) изTime::HiRes
модуля, потому что обычныйsleep
принимает только целые секунды.-F''
разбивает заданный ввод на символы (разделитель пустой''
) и помещает символы в массив@F
.BEGIN {$|=1}
отключает буферизацию вывода, поэтому каждый символ печатается сразу.for (@F) { print; usleep(100_000+rand(200_000)) }
просто перебирает персонажей1_000
(==1000
) или даже1_0_00
если мы посчитаем, что это легче читать.rand()
возвращает случайное число в диапазоне от 0 до заданного аргумента, так что вместе это составляет от 100 000 до 299 999 микросекунд (0,1–0,3 секунды).источник
rand()
возвращает ли число от 0 до аргумента (от 100k до 300k в вашем примере) или между ними (от 100k + 1 до 300k-1 в вашем примере)?[0,200k)
, то есть, включая 0, но исключая 200k. Точное поведение задокументировано здесь : «Возвращает случайное дробное число, большее или равное 0 и меньшее, чем значение EXPR. (EXPR должен быть положительным.)»-F
подразумевает-a
и-a
подразумевает-n
.Еще один инструмент, который может работать, который не зависит от x11 или чего-либо еще, это asciicinema . Он записывает все, что вы делаете в своем терминале, и позволяет вам воспроизвести это, как если бы это был снимок экрана, только тогда он основан исключительно на ascii! Возможно, вам придется временно отключить ваше приглашение, чтобы оно было чисто визуально чистым. Как уже отмечали другие, добавление последовательной задержки не будет выглядеть естественным, и ввод ее самостоятельно может быть одним из самых естественных видов, которые вы можете достичь.
После записи текста вы можете сделать что-то вроде:
источник
Я удивлен, что никто еще не упомянул об этом, но вы можете сделать это с помощью стандартных инструментов и цикла:
Он просто перебирает вводимый символ за символом и печатает их с задержкой после каждого. Единственный сложный момент заключается в том, что вы должны установить IFS на пустую строку, чтобы bash не пытался разделить ваши пробелы.
Это решение очень простое, поэтому добавление переменных задержек между символами, опечатками, что угодно, очень просто.
РЕДАКТИРОВАТЬ (спасибо, @dessert): Если вы хотите немного более естественный интерфейс, вы можете вместо этого сделать
Это позволит вам вызывать функцию как,
typeit foo bar
а неtypeit 'foo bar'
. Имейте в виду, что без кавычек аргументы могут быть разбиты на слова в bash, поэтому, например, ониtypeit foo<space><space>bar
будут напечатаныfoo<space>bar
. Чтобы сохранить пробелы, используйте кавычки.источник
typeit foo<space>bar
приведетfoo bar
, в то время какtypeit foo<space><space>bar
будет также приводитьfoo bar
. Вы должны процитировать это, чтобы убедиться, что это дословно. @dessert не стесняйтесь предлагать редактирование. Я могу сделать это сам, но я хочу дать вам шанс получить за это кредит.read -n1
(что, кстати,read -k1
в zsh)Во-первых, «похоже, что оно набирается с постоянной задержкой между символами ...», как указывали другие, немного противоречиво. Что-то набирается без постоянной задержки. Когда вы видите что-то, произведенное с непоследовательной задержкой, вы получите озноб. "Что захватило мой компьютер !!! ??!?"
Так или иначе...
Я должен сказать
expect
, что должно быть доступно в большинстве дистрибутивов Linux. Старая школа, я знаю, но - при условии, что она установлена - это вряд ли может быть проще:Со страницы руководства:
См. Https://www.tcl.tk/man/expect5.31/expect.1.html.
источник