Mam prosty echo
wydruk, który dodałem do mojego .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
To wypisuje wiadomość do terminala, ale chcę, aby wyglądała tak, jakby była wpisywana, ze stałym opóźnieniem między znakami.
command-line
bash
echo
Po prostu uproszczone
źródło
źródło
Odpowiedzi:
To nie działa z Waylandem; jeśli używasz Ubuntu 17.10 i nie zmieniłeś się na używanie Xorg przy logowaniu, to rozwiązanie nie jest dla ciebie.
Możesz
xdotool
do tego użyć . Jeśli opóźnienie między naciśnięciami klawiszy powinno być spójne , jest to tak proste:Typ ten występuje
something
z opóźnieniem100
milisekund między każdym naciśnięciem klawisza.Jeśli opóźnienie między naciśnięciami klawiszy powinno być losowe , powiedzmy od 100 do 300 milisekund, sprawy stają się nieco bardziej skomplikowane:
Ta
for
pętla przechodzi przez każdą pojedynczą literę łańcucha zapisanego w zmiennejtext
, albo drukowaniakey <letter>
lubkey space
w przypadku spacjęsleep 0.
i losową liczbę między 1 i 3 (xdotool
„ssleep
interpretuje jako liczba sekund). Następnie przesyłane jest całe wyjście pętlixdotool
, które drukuje litery z losowym opóźnieniem pomiędzy nimi. Jeśli chcesz zmienić opóźnienie, po prostu zmień część, która jest dolną i górną granicą - na 0,2 do 0,5 sekundy .(RANDOM%x)+y
y
x-1+y
(RANDOM%4)+2
Zauważ, że to podejście nie drukuje tekstu, a raczej wpisuje go dokładnie tak, jak zrobiłby to użytkownik, syntezując pojedyncze naciśnięcia klawiszy. W rezultacie tekst zostaje wpisany w aktualnie zaznaczonym oknie; jeśli zmienisz fokus, część tekstu zostanie wpisana w nowo zaznaczonym oknie, co może, ale nie musi być tym, czego chcesz. W obu przypadkach spójrz na inne odpowiedzi tutaj, z których wszystkie są genialne!
źródło
Próbowałem xdotool po przeczytaniu odpowiedzi @ deser, ale z jakiegoś powodu nie mogłem go uruchomić. Więc wpadłem na to:
Wklej tekst do powyższego kodu, a zostanie wydrukowany jak napisany na maszynie. Możesz także dodać losowość, zastępując
sleep 0.1
jąsleep 0.$((RANDOM%3))
.Wersja rozszerzona z fałszywymi literówkami
Ta wersja wprowadza co jakiś czas fałszywą literówkę i poprawia ją:
źródło
while IFS= read -r line; do for (( i = 0; i < ${#line}; i++ )); do sleep 0.1; printf "%s" "${line:i:1}"; done; echo; done
(;
w razie potrzeby zastąp nowymi liniami i dobrym wcięciem).IFS= read -r
Iprintf "%s"
upewnić się, że białe znaki i znaki specjalne nie są traktowane inaczej. Agrep
na każdej linii podzielić na bohaterów jest zbędne - po prostufor
pętla nad każdym char w linii jest wystarczające.Wspominasz o spójnym opóźnieniu między postaciami, ale jeśli naprawdę chcesz, aby wyglądał jak napisany, czas nie będzie idealnie spójny. Aby to osiągnąć, możesz zapisać własne
script
polecenie za pomocą polecenia i odtworzyć je za pomocąscriptreplay
:Nagrywanie jest zatrzymywane przez naciśnięcie CTRL-D.
Przekazanie
-t
parametruscript
instruuje go również wygenerować informacje o taktowaniu, które przekierowałem doscript.timing
pliku. Przekazałemsed d
jako polecenie,script
ponieważ jest to po prostu sposób na wchłonięcie danych wejściowych (i ten zapis klawiszy) bez żadnych skutków ubocznych.Jeśli chcesz zrobić wszystkie rzeczy
tput
/reset
, możesz zrobićscript
nagranie dla każdej linii i odtworzyć je, przeplatane poleceniamitput
/reset
.źródło
Inną możliwością jest użycie Demo Magic , a ściślej mówiąc, funkcji drukowania tej kolekcji skryptów, która w zasadzie wynosi
Pod maską używa to pv , którego oczywiście można również użyć, aby bezpośrednio uzyskać pożądany efekt, podstawowa forma wygląda następująco:
źródło
echo
dopv
, wystarczy użyćpv -qL20 <<< "Hello world"
jeśli obsługiwana powłoki herestrings.Zgodnie z moim pseudonimem mogę zaoferować inne rozwiązanie:
Wygląda dziwnie, prawda?
-MTime::HiRes=usleep
importuje funkcjęusleep
(uśpienie mikrosekundowe) zTime::HiRes
modułu, ponieważ zwyklesleep
przyjmuje tylko sekundy całkowite.-F''
dzieli podane dane wejściowe na znaki (separator jest pusty''
) i umieszcza znaki w tablicy@F
.BEGIN {$|=1}
wyłącza buforowanie danych wyjściowych, dzięki czemu każdy znak jest natychmiast drukowany.for (@F) { print; usleep(100_000+rand(200_000)) }
po prostu iteruje postacie1_000
(==1000
), a nawet1_0_00
jeśli uważamy to za łatwiejsze do odczytania.rand()
zwraca losową liczbę od 0 do podanego argumentu, więc razem śpi to od 100 000 do 299 999 mikrosekund (0,1-0,3 sekundy).źródło
rand()
zwraca liczbę od 0 do argumentu (100k do 300k w twoim przykładzie) lub między nimi (100k + 1 do 300k-1 w twoim przykładzie)?[0,200k)
, tj. Obejmującą 0, ale wykluczającą 200k. Dokładne zachowanie jest tutaj udokumentowane : „Zwraca losową liczbę ułamkową większą lub równą 0 i mniejszą niż wartość WYRAŻ. (WYRAŻ powinna być dodatnia.)”-F
implikuje-a
i-a
implikuje-n
.Innym narzędziem, które może działać, które nie zależy od x11 lub cokolwiek innego, jest asciicinema . Rejestruje wszystko, co robisz w swoim terminalu i pozwala odtworzyć to tak, jakby to był zrzut ekranu, tylko wtedy jest to oparte wyłącznie na ascii! Być może trzeba tymczasowo wyłączyć monit, aby był on czysto wizualnie czysty. Jak zauważyli inni, dodanie spójnego opóźnienia nie będzie wyglądać naturalnie, a samodzielne wpisanie go może być jednym z najbardziej naturalnych efektów, jaki można uzyskać.
Po nagraniu tekstu możesz zrobić coś takiego:
źródło
Dziwi mnie, że nikt o tym jeszcze nie wspominał, ale można to zrobić za pomocą standardowych narzędzi i pętli:
Po prostu zapętla znak wejściowy po znaku i drukuje je z opóźnieniem po każdym. Jedynym trudnym zadaniem jest ustawienie IFS na pusty ciąg znaków, aby bash nie próbował rozdzielać spacji.
To rozwiązanie jest bardzo proste, więc dodawanie zmiennych opóźnień między znakami, literówkami, cokolwiek jest super łatwe.
EDYCJA (dzięki, @dessert): Jeśli chcesz nieco bardziej naturalny interfejs, możesz to zrobić
Umożliwiłoby to wywołanie funkcji
typeit foo bar
zamiasttypeit 'foo bar'
. Pamiętaj, że bez cudzysłowów argumenty podlegają podziałowi na słowa bash, więc na przykładtypeit foo<space><space>bar
zostaną wydrukowanefoo<space>bar
. Aby zachować białe znaki, użyj cudzysłowów.źródło
typeit foo<space>bar
spowodujefoo bar
, natomiasttypeit foo<space><space>bar
będzie również skutkowaćfoo bar
. Musisz to zacytować, aby upewnić się, że jest dosłowne. @dessert możesz zaproponować edycję. Mogę to zrobić sam, ale chcę dać ci szansę na uznanie za to.read -n1
(co, btw. Jestread -k1
w Zsh)Po pierwsze, „wygląda na to, że jest pisany na maszynie, ze stałym opóźnieniem między postaciami ...” jest trochę sprzeczne, jak zauważyli inni. Coś, co jest wpisywane, nie ma spójnego opóźnienia. Kiedy zobaczysz coś wyprodukowanego z niespójnym opóźnieniem, poczujesz dreszcze. „Co przejęło mój komputer !!! ??!?”
Tak czy inaczej...
Muszę wykrzyczeć, że
expect
powinien być dostępny w większości dystrybucji Linuksa. Wiem, że Old School, ale - zakładając, że jest zainstalowany - nie może być prostsze:Ze strony podręcznika:
Zobacz https://www.tcl.tk/man/expect5.31/expect.1.html
źródło