Bash 实时修改shell标准输出
好吧,请容忍我,因为我不是专业人士,这是一个概念验证项目,旨在了解更多关于我的shell、编程和基本bash脚本的信息 所以我想做的是:无论何时在我的终端中打印出任何内容,无论是命令的结果还是来自shell的错误消息,我都想对显示的内容应用一些“过滤器”,例如,如果我输入“ls-a”在终端中,我希望获得命令返回的文件夹列表,但对字符应用一个时间延迟,以便看起来列表是实时输入的 更具体地说,我希望脚本获取标准输出中的每个字母数字字符,并在最终停止字符的原始值之前,花特定的时间(比如100毫秒)遍历随机字符(这些字符可以从列表中随机访问) 据我所知: 不太多,我对编程基本上是新手,bash语言也是如此,但我可以阅读一些代码并浏览我找到的这个与tput一起使用的脚本。这向我展示了我想要实现的视觉效果是可以实现的…现在,让打印到STDOUT的每个字符都有秩序地单独实现…这是我无法理解的 我的想法是: 在我看来,我知道我可以使用STDOUT并将其传输到一个文件中,在这个文件中,通过任何语言(比如python!)我都可以进行各种字符串操作,然后将输出返回到STDOUT,但我希望能够实时处理字符,例如,如果代码是Bash 实时修改shell标准输出,bash,shell,text,scripting,stdout,Bash,Shell,Text,Scripting,Stdout,好吧,请容忍我,因为我不是专业人士,这是一个概念验证项目,旨在了解更多关于我的shell、编程和基本bash脚本的信息 所以我想做的是:无论何时在我的终端中打印出任何内容,无论是命令的结果还是来自shell的错误消息,我都想对显示的内容应用一些“过滤器”,例如,如果我输入“ls-a”在终端中,我希望获得命令返回的文件夹列表,但对字符应用一个时间延迟,以便看起来列表是实时输入的 更具体地说,我希望脚本获取标准输出中的每个字母数字字符,并在最终停止字符的原始值之前,花特定的时间(比如100毫秒)遍历
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++
cool_chars=“)ア イ ウ エ オ カ キ ク ケ コ サ シ ス "
stdout=以字符串形式从shell获取stdout的任何模块
stdout=stdout.split(“”)
对于标准输出中的单词:
对于大写字母:
n=0
虽然(n这并不能完全回答您的问题,但它会打印任何输入,就像实时输入一样:
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的sleep缩短时间:
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;
}
}
!/usr/bin/perl
严格使用;
使用utf8;
binmode(标准输出,“:utf8”);
我们的$cols=`tput cols`;
我们的美元=1;
我们的$cursor=“”;
副复位线{
打印“\r.”“x$cols.”\r;
}
子拾取光标{
my@c=拆分(/,“)アイウエオカキクケコサシス");
$cursor=$c[int(rand(1+@c))];
}
而(){
我的$line=“”;
我的@a=split/;
foreach my$char(@a){
`睡眠0.1`;
复位线;
拾取光标;
如果($char eq“\n”|$char=~/\s/){
打印“${line}${char}”;
}否则{
打印“${line}${char}${cursor}”;
}
$line.=$char;
}
}
您必须连接到终端驱动程序或外壳才能拦截正常的标准输出。看看屏幕如何通过伪tty进行拦截和/或最好是tmux
拦截。感谢您接受我的回答,我用一个脚本对其进行了编辑,完全解决了您的问题。也许您想要手表或尾部-f
?Almost!哈哈,我是PERL新手,所以我花了一分钟的时间来弄清楚所有内容的含义($|=1正在刷新缓冲区???…oke),这样一来,我首先编写的所有内容都变得可见,然后在屏幕上看到它的第二次迭代,这一次以0.1的延迟更改字符,但它不会解析参数(因此,如果我键入“ls-a“它实际上不会将命令传递给终端)它似乎是在使用标准输入法而不是标准输出法。然而,这是一个很棒的代码,因为我可以使用它,弄清楚一切意味着什么,我知道这几乎是我所需要的,让它成为我脑海中的想法。谢谢蒂亚戈。我用谷歌来称赞我的编码文盲,但是这里的“打印”\r“,“x$cols”是什么意思?\r”你为什么用“我们的”(确切地说是什么?)关于@c@a?P.S.你对解析命令到终端/将此代码应用到命令的STDOUT有什么想法?我很糟糕,我通常用一行代码来解决问题,所以我不擅长评论我的代码。如果你有任何疑问,但这是一个非常简单的脚本,我不能用一行代码来解决它的唯一原因是因为花哨的cursor:)