.bashrc
に追加した簡単なecho
印刷物があります。
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
これにより、端末にメッセージが出力されますが、文字間で一貫した遅延が発生しているように見えます。
これはWaylandでは機能しません。 Ubuntu 17.10を使用していて、ログイン時にXorgを使用するように変更しなかった場合、このソリューションは適切ではありません。
xdotool
を使用できます そのため。キーストローク間の遅延がconsistentである場合、それはそれと同じくらい簡単です:
xdotool type --delay 100 something
これは、各キーストロークの間に100
ミリ秒の遅延でsomething
を入力します。
キーストローク間の遅延がrandomである場合、100〜300ミリ秒の場合、事態は少し複雑になります。
$ text="some text"
for ((i=0;i<${#text};i++));
do
if [[ "${text:i:1}" == " " ]];
then
echo -n "key space";
else
echo -n "key ${text:i:1}";
fi;
[[ $i < $((${#text}-1)) ]] && echo -n " sleep 0.$(((RANDOM%3)+1)) ";
done | xdotool -
このfor
ループは、変数text
に保存された文字列のすべての文字を通過し、key <letter>
が続くスペースの場合はkey space
またはsleep 0.
のいずれかを出力します。 1から3までの乱数(xdotool
のsleep
は数値を秒として解釈します)。次に、ループの出力全体がxdotool
にパイプ処理され、ランダムな遅延の間に文字が出力されます。遅延を変更する場合は、(RANDOM%x)+y
部分を変更します。y
が下限で、x-1+y
が上限です。0.2〜0.5秒の場合、(RANDOM%4)+2
になります。
このアプローチはテキストをprintするのではなく、むしろtypeのようにユーザーが行うように、単一のキー入力を合成することに注意してください。結果として、テキストは現在フォーカスされているウィンドウに入力されます。テキストのフォーカス部分を変更すると、新しくフォーカスされたウィンドウにテキストが入力されますが、これは必要な場合とそうでない場合があります。いずれの場合も、ここで他の回答をご覧ください。それらはすべて素晴らしいです!
@dessertの答えを読んだ後、xdotoolを試しましたが、何らかの理由で動作しませんでした。だから私はこれを思いついた:
while read line
do
grep -o . <<<$line | while read a
do
sleep 0.1
echo -n "${a:- }"
done
echo
done
テキストを上記のコードにパイプすると、入力したとおりに印刷されます。 sleep 0.1
をsleep 0.$((RANDOM%3))
に置き換えることにより、ランダム性を追加することもできます。
このバージョンでは、時々偽のタイプミスを導入し、修正します。
while read line
do
# split single characters into lines
grep -o . <<<$line | while read a
do
# short random delay between keystrokes
sleep 0.$((RANDOM%3))
# make fake typo every 30th keystroke
if [[ $((RANDOM%30)) == 1 ]]
then
# print random character between a-z
printf "\\$(printf %o "$((RANDOM%26+97))")"
# wait a bit and delete it again
sleep 0.5; echo -ne '\b'; sleep 0.2
fi
# output a space, or $a if it is not null
echo -n "${a:- }"
done
echo
done
文字間の一貫した遅延に言及しますが、入力されたように見せたい場合、タイミングは完全に一貫していません。これを実現するには、script
コマンドを使用して独自の入力を記録し、scriptreplay
で再生します。
$ script -t -c "sed d" script.out 2> script.timing
Script started, file is script.out
Wake up ...
Wake up ...
Wake up Neo ...
Script done, file is script.out
$
$ scriptreplay script.timing script.out
Wake up ...
Wake up ...
Wake up Neo ...
$
CTRL-Dを押すと記録が停止します。
-t
パラメータをscript
に渡すと、script.timing
ファイルにリダイレクトしたタイミング情報も生成されます。 sed d
をコマンドとしてscript
に渡しました。これは、副作用なしで入力を吸収する(およびキーストロークを記録する)ための単なる方法です。
すべてのtput
/reset
の処理も行いたい場合は、各行に対してscript
の録音を行い、tput
/reset
コマンド。
私のニックネームに沿って、別のソリューションを提供できます。
echo "something" |
Perl \
-MTime::HiRes=usleep \
-F'' \
-e 'BEGIN {$|=1} for (@F) { print; usleep(100_000+Rand(200_000)) }'
変に見えますよね?
-MTime::HiRes=usleep
はTime::HiRes
モジュールから関数usleep
(マイクロ秒スリープ)をインポートします。これは、通常の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秒)スリープします。動作する可能性のある別のツールは、x11などには依存しませんが、 asciicinema です。ターミナルで行うすべてを記録し、それをスクリーンキャプチャのように再生できるようにします。ただし、純粋に視覚的にきれいにするために、プロンプトを一時的に無効にする必要がある場合があります。他の人が指摘したように、一貫した遅延を追加することは自然に見えず、自分で入力することはあなたが達成できる最も自然な外観の一つかもしれません。
テキストを記録した後、次のようなことができます。
$ asciinema play [your recording].cast; cmatrix
誰もこれについて言及していないことに驚いていますが、ストックツールとループでこれを達成できます。
typeit() {
local IFS=''
while read -n1 c; do
echo -n "$c"
sleep .1
done <<< "$1"
}
入力文字を1文字ずつループし、それぞれの後に遅延して出力します。唯一の注意点は、bashがスペースを分割しようとしないように、IFSを空の文字列に設定する必要があることです。
このソリューションは非常に単純なので、文字間での可変遅延、タイプミスなど、非常に簡単なものを追加します。
編集(ありがとう、@ dessert):もう少し自然なインターフェイスが必要な場合は、代わりに行うことができます
typeit() {
local IFS=''
while read -n1 c; do
echo -n "$c"
sleep .1
done <<< "$@"
}
これにより、関数をtypeit foo bar
ではなくtypeit 'foo bar'
として呼び出すことができます。引用符がないと、引数はbashのWord分割の対象になるため、たとえばtypeit foo<space><space>bar
はfoo<space>bar
を出力します。空白を保持するには、引用符を使用します。
最初に、「文字が入力されているように見え、文字間で一貫した遅延があります...」は、他の人が指摘しているように、少し矛盾しています。タイプされているものには、一貫した遅延がありません。一貫性のない遅延で生成されたものを見ると、悪寒を覚えます。 「何が私のコンピューターを乗っ取ったのでしょうか!!! ??!?」
とにかく...
ほとんどのLinuxディストリビューションで利用できるはずのexpect
に叫ぶ必要があります。オールドスクール、私は知っていますが、インストールされていると仮定すると、それは簡単ではありません:
echo 'set send_human {.1 .3 1 .05 2}; send -h "The Matrix has you......\n"' | expect -f /dev/stdin
Manページから:
-hフラグは、実際に入力する人間のように(ある程度)出力を強制的に送信します。キャラクター間に人間のような遅延が現れます。 (アルゴリズムは、この特定のアプリケーションに合わせて修正されたワイブル分布に基づいています。)この出力は、変数「send_human」の値によって制御されます...