Reputation: 43
Ok so bear with me as I am not a professional, this is a proof of concept project to learn more about my shell, programming and just basic bash scripting.
So WHAT I WANT TO DO is: whenever anything is printed out in my terminal, be it the result of a command or an error message from the shell I want to apply some "filters" to what is being displayed so for example if I input "ls -a" in the terminal I would like to get the list of folders that the command returns but apply a TIME DELAY to the characters so that it seems like the list is being typed in real time.
More SPECIFICALLY I'd like for the script to take every alphanumerical character in STDOUT and spend a specific amount of time (say 100 milliseconds) iterating through random characters (these can be accessed randomly from a list) before finally stopping at the original value of the character.
WHAT I KNOW: not much, I am new to programming in general so also the bash language but I can read some code and browsing through I found this http://brettterpstra.com/2012/09/15/matrixish-a-bash-script-with-no-practical-application/ script that plays with tput. This shows me the visual effect I'd like to accomplish can be accomplished...now to make it happen orderly and individually for each character printed to STDOUT...that is what I can't figure out.
WHAT I THINK: in my mind I know I could take the STDOUT and pipe it to a file in which through any language (let's say python!) I can do all kinds of string manipulation and then return the output to STDOUT but I'd like for the characters to be manipulated in realtime so if for example the code was
cool_chars="£ ア イ ウ エ オ カ キ ク ケ コ サ シ ス "
stdout=whatever module works to grab STDOUT from shell as string
stdout = stdout.split(" ")
for word in stdout:
for letter in word:
n=0
while (n<10):
#print the following iteration in real time @ shell but how????
print random.choice(cool_chars)
#finally stop at correct character
print letter
n++
Anyway, I've read a little about curses and ncurses and how you can create new windows with whatever specified parameters, I wonder if it'd be just a matter of creating a terminal with the specified parameters with the curses libraries and then making a link so that each new terminal instance opens my modified curses shell or if I can just do a bash shell script or if it'd be easiest to use something like python. I know all of the above can be options but I'm looking for the simplest, not necessarily most resource efficient answer.
Any help, comments, pointers etc is appreciated.
Upvotes: 4
Views: 452
Reputation: 7969
This does not answer you question fully, but it does print any input as if it was being type in real time:
perl -MTime::HiRes -F -ane '$|=1;$old=""; foreach $char(@F){Time::HiRes::sleep(0.1); print "\r${old}${char}"; $old.=$char}' /etc/hosts
instead of file, STDIN can be used:
echo -e "abc\ndef\nghi" | perl -MTime::HiRes -F -ane '$|=1;$old=""; foreach $char(@F){Time::HiRes::sleep(0.1); print "\r${old}${char}"; $old.=$char}'
We can make it shorter using shell's sleep:
perl -F -ane '$|=1;$old=""; foreach $char(@F){`sleep 0.1`; print "\r${old}${char}"; $old.=$char}'
EDIT:
The script below should fully solve your problem:
#!/usr/bin/perl
use strict;
use utf8;
binmode(STDOUT, ":utf8");
our $cols=`tput cols`;
our $|=1;
our $cursor="";
sub reset_line {
print "\r" . " "x$cols . "\r";
}
sub pick_cursor {
my @c = split (//,"£アイウエオカキクケコサシス");
$cursor=$c[int(rand(1+@c))];
}
while (<>) {
my $line="";
my @a=split //;
foreach my $char (@a) {
`sleep 0.1`;
reset_line;
pick_cursor;
if ( $char eq "\n" || $char =~ /\s/) {
print "${line}${char}";
}else {
print "${line}${char}${cursor}";
}
$line .= $char;
}
}
Upvotes: 1