实时修改shell stdout

时间:2015-02-05 11:57:42

标签: bash shell text scripting stdout

好的,请耐心等待我,因为我不是专业人士,这是一个概念验证项目,可以了解有关我的shell,编程和基本bash脚本的更多信息。

所以我想做的是:每当我的终端打印出任何东西时,无论是命令的结果还是来自shell的错误消息,我都想对显示的内容应用一些“过滤器”,例如如果我在终端输入“ls -a”,我想得到命令返回的文件夹列表,但是对字符应用TIME DELAY,这样看起来就像是实时输入列表一样。

更具体地说我希望脚本能够在STDOUT中获取每个字母数字字符并花费特定的时间(比如100毫秒)迭代随机字符(这些可以从列表中随机访问),然后最终停止在角色的原始值。

我知道什么: 并不多,我是编程的新手,也是bash语言的新手,但我可以阅读一些代码并浏览我发现这个与tput一起播放的http://brettterpstra.com/2012/09/15/matrixish-a-bash-script-with-no-practical-application/脚本。这向我展示了我想要完成的视觉效果......现在为了打印到STDOUT的每个角色有条不紊地单独发生......这是我无法弄清楚的。

我在想什么: 在我的脑海里,我知道我可以把STDOUT和管道传递到一个文件,通过任何语言(让我们说python!)我可以做各种字符串操作,然后将输出返回到STDOUT但我喜欢的字符如果代码是

,则实时操作
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++

无论如何,我已经阅读了一些关于curses和ncurses以及如何使用任何指定参数创建新窗口的内容,我想知道是否只需要使用curses库创建具有指定参数的终端并且然后建立一个链接,以便每个新的终端实例打开我修改过的curses shell,或者我可以只做一个bash shell脚本,或者最简单的方法是使用像python这样的东西。我知道以上所有可能是选项,但我正在寻找最简单,不一定是资源效率最高的答案。

任何帮助,评论,指示等都表示赞赏。

1 个答案:

答案 0 :(得分:1)

这并没有完全回答你的问题,但它会打印任何输入,就好像它是实时输入一样:

perl -MTime::HiRes -F -ane '$|=1;$old=""; foreach $char(@F){Time::HiRes::sleep(0.1); print "\r${old}${char}"; $old.=$char}' /etc/hosts

而不是文件,可以使用STDIN:

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}'

我们可以使用shell的睡眠来缩短它的时间:

perl -F -ane '$|=1;$old=""; foreach $char(@F){`sleep 0.1`; print "\r${old}${char}"; $old.=$char}'

修改

以下脚本应完全解决您的问题:

#!/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;     
    }
}