busybox.pl
30分プログラム、その20。記念すべき20回目なのに、結構手抜き。
head+tail+grep+cat+echoなプログラム。BusyBox風味。
$ ln -s busybox.pl head $ ln -s busybox.pl tail $ ln -s busybox.pl grep $ ln -s busybox.pl cat $ ln -s busybox.pl echo $ perl head busybox.pl #!/usr/bin/env perl use strict; use warnings; .... $ perl tail .... no strict 'refs'; $0->(@ARGV); } $ perl grep perl * busybox.pl:#!/usr/bin/env perl cat:#!/usr/bin/env perl cgi.pl:#!/usr/bin/env perl echo:#!/usr/bin/env perl $ perl cat busybox.pl #!/usr/bin/env perl use strict; use warnings; .... $ perl echo TMTOWTDI TMTOWTDI
要するに1つのファイルなのに、シンボリックリンクの名前によって動作が変わるPerlプログラム。
本来は組み込みOSで、1つの実行ファイルでlsからrmまでを実現したいときに使う手法。だから、Perlで再現する理由はこれっぽっちもない。
うん、特にやることが思いつかなくてhead単体だと時間があまりすぎるからbusyboxっぽくしただけなんだよね。
#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; sub p(@){ print Dumper(@_); } sub head{ my ($filename) = @_; open(FILE,$filename); while(<FILE>){ last if $. > 10; print; } close(FILE); } sub tail{ my ($filename) = @_; open(FILE,$filename); my @lines = (<FILE>)[-10..-1]; print @lines; close(FILE); } sub grep{ my ($pattern,@filenames) = @_; for my $filename (@filenames){ open(FILE,$filename); while(<FILE>){ printf("%s:%s",$filename,$_) if /$pattern/ } close(FILE); } } sub cat{ for my $filename (@_){ open(FILE,$filename); my @lines = <FILE>; print @lines; close(FILE); } } sub echo{ print join(' ',@_),"\n"; } { no strict 'refs'; $0->(@ARGV); }