在进程 运行 时从键盘读取一个键
reading a key from keyboard while the process is running
我用 wget 在 Linux-Gnu 中用 Perl[=44 写了一个简单的脚本来管理下载时间(开始和完成) =].没有问题,一切正常,除了我希望 我可以在进程 运行ning.
时从键盘读取一个键
我在屏幕上显示了一个我不想停止的简单运动动画,然后读取键。
例如 mplayer 或 mpv 当你在命令行 运行 它时,你可以按 q
退出或 s
从屏幕拍照。
脚本的一部分:
do {
system( "clear" );
($h, $m, $s) = k5mt::second_to_clock( $till_shutdown );
set_screen();
set_screen( 24 );
set_screen();
say "download was started ...";
set_screen();
set_screen( 24 );
set_screen();
printf "till finish: %02d %02d %02d\n", $h, $m, $s;
set_screen();
set_screen( 24 );
set_screen();
say "wget pid: [$wget_pid]";
set_screen();
set_screen( 24 );
set_screen();
$waiting_temp .= $animation[ $counter_animation++ ];
say $waiting_temp;
if( length( $waiting ) == $counter_animation ){
$waiting_temp = "";
$counter_animation = 0;
}
set_screen();
set_screen( 24 );
sleep 1;
$till_shutdown--;
} while( $till_shutdown );
单词waiting till finish.....连续显示(没有中断),我想读一个像q
这样的键退出程序.
更新
我正在寻找一个包含尽可能多选项的解决方案,如果我只想退出程序,我只需告诉用户按 Ctrl + C
是否可以使用 Perl 编写脚本?或不?如果是,如何?
NOTE: if it is possible without any modules please say the solution
without any module, and if not, okay no problem
但是,非常感谢你。
如果您不担心有点延迟,您可以尝试 select
和 alarm
来尝试处理用户输入。
使用 select 您可以处理 STDIN
并使用 alarm
您可以等待几秒钟或更短的时间来等待用户输入。
#!/usr/bin/env perl
use common::sense;
use IO::Select;
my $sel = IO::Select->new();
$sel->add( \*STDIN );
$|++;
my $running = 1;
while ($running) {
eval {
local $SIG{ALRM} = sub { die 'Time Out'; };
alarm 0.5;
if ( $sel->can_read(0) ) {
my $input = <STDIN>;
chomp $input;
print "STDIN > $input\n";
$running = 0;
}
};
if ( !$@ ) {
select( undef, undef, undef, 0.5 );
print ".";
}
}
print "\nEnd Of Script\n";
我告诉过你尝试使用 Term::ReadKey :-)
开始吧:
!/usr/bin/env perl
use common::sense;
use Term::ReadKey;
my $running = 1;
my $key;
while ($running) {
ReadMode 4; # Turn off controls keys
while ( not defined( $key = ReadKey(-1) ) ) {
select( undef, undef, undef, 0.5 );
print '.';
}
print "\nSTDIN> $key\n";
ReadMode 0;
}
print "\nEnd Of Script\n";
现在您只需处理 quit 或 int 等信号即可退出循环,但使用它您可以捕获输入并执行任何您想做的事情。
这对你有用
use 5.010;
use strict;
use Term::ReadKey;
ReadMode 4; # It will turn off controls keys (eg. Ctrl+c)
my $key;
# It will create a child so from here two processes will run.
# So for parent process fork() will return child process id
# And for child process fork() will return 0 id
my $pid = fork();
# This if block will execute by the child process and not by
# parent because for child $pid is 0
if(not $pid){
while(1){
# Do your main task here
say "hi I'm sub process and contains the main task";
sleep 2;
}
}
# Parent will skip if block and will follow the following code
while (1) {
$key = ReadKey(-1); # ReadKey(-1) will perform a non-blocked read
if($key eq 'q'){ # if key pressed is 'q'
`kill -9 $pid`; # then if will run shell command kill and kill
# the child process
ReadMode 0; # Restore original settings for tty.
exit; # Finally exit from script
} elsif( $key eq 'h' ) {
say "Hey! you pressed $key key for help";
} elsif( $key ne '' ) {
say "Hey! You pressed $key";
}
}
参考文献:
假设你的程序有一个中央循环,或者如果你可以简单地将键盘检查放入处理中,你最好使用 Term::ReadKey
而不是尝试放入 fork
并处理必要的 inter-process 交流
调用 ReadKey(-1)
将进行 non-blocking 读取,如果按下某个键,则将 return 读取单个字符,否则 undef
。 (您可以提供第二个参数,即要使用的 IO 通道,但它将默认为 STDIN。)
我建议你运行这个例子。我使用 sleep 1
作为循环处理的虚拟对象
use strict;
use warnings 'all';
use feature 'say';
use Term::ReadKey;
my $n;
while () {
my $key = ReadKey(-1);
say "key $key entered" if defined $key;
sleep 1;
say ++$n;
}
我用 wget 在 Linux-Gnu 中用 Perl[=44 写了一个简单的脚本来管理下载时间(开始和完成) =].没有问题,一切正常,除了我希望 我可以在进程 运行ning.
时从键盘读取一个键
我在屏幕上显示了一个我不想停止的简单运动动画,然后读取键。
例如 mplayer 或 mpv 当你在命令行 运行 它时,你可以按 q
退出或 s
从屏幕拍照。
脚本的一部分:
do {
system( "clear" );
($h, $m, $s) = k5mt::second_to_clock( $till_shutdown );
set_screen();
set_screen( 24 );
set_screen();
say "download was started ...";
set_screen();
set_screen( 24 );
set_screen();
printf "till finish: %02d %02d %02d\n", $h, $m, $s;
set_screen();
set_screen( 24 );
set_screen();
say "wget pid: [$wget_pid]";
set_screen();
set_screen( 24 );
set_screen();
$waiting_temp .= $animation[ $counter_animation++ ];
say $waiting_temp;
if( length( $waiting ) == $counter_animation ){
$waiting_temp = "";
$counter_animation = 0;
}
set_screen();
set_screen( 24 );
sleep 1;
$till_shutdown--;
} while( $till_shutdown );
单词waiting till finish.....连续显示(没有中断),我想读一个像q
这样的键退出程序.
更新
我正在寻找一个包含尽可能多选项的解决方案,如果我只想退出程序,我只需告诉用户按 Ctrl + C
是否可以使用 Perl 编写脚本?或不?如果是,如何?
NOTE: if it is possible without any modules please say the solution without any module, and if not, okay no problem
但是,非常感谢你。
如果您不担心有点延迟,您可以尝试 select
和 alarm
来尝试处理用户输入。
使用 select 您可以处理 STDIN
并使用 alarm
您可以等待几秒钟或更短的时间来等待用户输入。
#!/usr/bin/env perl
use common::sense;
use IO::Select;
my $sel = IO::Select->new();
$sel->add( \*STDIN );
$|++;
my $running = 1;
while ($running) {
eval {
local $SIG{ALRM} = sub { die 'Time Out'; };
alarm 0.5;
if ( $sel->can_read(0) ) {
my $input = <STDIN>;
chomp $input;
print "STDIN > $input\n";
$running = 0;
}
};
if ( !$@ ) {
select( undef, undef, undef, 0.5 );
print ".";
}
}
print "\nEnd Of Script\n";
我告诉过你尝试使用 Term::ReadKey :-)
开始吧:
!/usr/bin/env perl
use common::sense;
use Term::ReadKey;
my $running = 1;
my $key;
while ($running) {
ReadMode 4; # Turn off controls keys
while ( not defined( $key = ReadKey(-1) ) ) {
select( undef, undef, undef, 0.5 );
print '.';
}
print "\nSTDIN> $key\n";
ReadMode 0;
}
print "\nEnd Of Script\n";
现在您只需处理 quit 或 int 等信号即可退出循环,但使用它您可以捕获输入并执行任何您想做的事情。
这对你有用
use 5.010;
use strict;
use Term::ReadKey;
ReadMode 4; # It will turn off controls keys (eg. Ctrl+c)
my $key;
# It will create a child so from here two processes will run.
# So for parent process fork() will return child process id
# And for child process fork() will return 0 id
my $pid = fork();
# This if block will execute by the child process and not by
# parent because for child $pid is 0
if(not $pid){
while(1){
# Do your main task here
say "hi I'm sub process and contains the main task";
sleep 2;
}
}
# Parent will skip if block and will follow the following code
while (1) {
$key = ReadKey(-1); # ReadKey(-1) will perform a non-blocked read
if($key eq 'q'){ # if key pressed is 'q'
`kill -9 $pid`; # then if will run shell command kill and kill
# the child process
ReadMode 0; # Restore original settings for tty.
exit; # Finally exit from script
} elsif( $key eq 'h' ) {
say "Hey! you pressed $key key for help";
} elsif( $key ne '' ) {
say "Hey! You pressed $key";
}
}
参考文献:
假设你的程序有一个中央循环,或者如果你可以简单地将键盘检查放入处理中,你最好使用 Term::ReadKey
而不是尝试放入 fork
并处理必要的 inter-process 交流
调用 ReadKey(-1)
将进行 non-blocking 读取,如果按下某个键,则将 return 读取单个字符,否则 undef
。 (您可以提供第二个参数,即要使用的 IO 通道,但它将默认为 STDIN。)
我建议你运行这个例子。我使用 sleep 1
作为循环处理的虚拟对象
use strict;
use warnings 'all';
use feature 'say';
use Term::ReadKey;
my $n;
while () {
my $key = ReadKey(-1);
say "key $key entered" if defined $key;
sleep 1;
say ++$n;
}