Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to execute external programs in Perl

How to execute external programs in Perl

2018.06.11 Gotanda.pm Perl Technology Conference #18

Shoichi Kaji

June 11, 2018
Tweet

More Decks by Shoichi Kaji

Other Decks in Programming

Transcript

  1. About Me • Shoichi Kaji • One of the maintainers

    of
 Minilla, Perl::Build, Text::Xslate, Mouse, Test::PAUSE::Permissions
  2. shellΛհ͢΂͔Βͣ • system "find $dir -type f -delete >/dev/null 2>&1";

    • Ͳ͕͜໰୊ʁ • system΍execΛ1Ҿ਺Ͱ࣮ߦ͢ΔͱshellΛհ͠ ࣮ͯߦ͢ΔՄೳੑ͕͋Δɻ
  3. ֎෦ϓϩάϥϜΛ࣮ߦ͢Δ
 Perlͷؔ਺ • ҎԼͷ4ͭ • system • ` ` (όοΫΫΦʔτ,

    qx) • fork & exec ← ࠓ೔͸͜Εʹ஫໨ • open (͜Ε͕Ұ൪PerlͬΆ͍!)
  4. #!/usr/bin/env perl use strict; use warnings; my $pid = fork

    // die; if ($pid == 0) { exec {"ls"} "ls", "-al"; exit 127; } wait; my $status = $?;
  5. redirect • system "gzip —stdout out.txt"; • ίϚϯυͷग़ྗΛout.txt.gzʹ޲͚͍ͨɻ • system

    "gzip —stdout out.txt > out.txt.gz"; ͸ ΍Γͨ͘ͳ͍ɻ • open STDOUT, ">", "out.txt.gz" ͰͰ͖Δ
  6. #!/usr/bin/env perl use strict; use warnings; my $pid = fork

    // die; if ($pid == 0) { open STDOUT, ">", "out.txt.gz"; exec {"gzip"} "gzip", "--stdout", "out.txt"; exit 127; } wait; my $status = $?;
  7. #!/usr/bin/env perl use strict; use warnings; use POSIX 'strftime'; pipe

    my $stdout_read, my $stdout_write; my $pid = fork // die; if ($pid == 0) { close $stdout_read; open STDOUT, ">&=", $stdout_write; exec {"perl"} "perl", "-le", '$|++; for (1..10) { print $_; sleep 1 }'; } close $stdout_write; while (<$stdout_read>) { print strftime("%FT%T", localtime) . " $_"; } wait;
  8. #!/usr/bin/env perl use strict; use warnings; use POSIX 'strftime'; pipe

    my $stdout_read, my $stdout_write; my $pid = fork // die; if ($pid == 0) { close $stdout_read; open STDOUT, ">&=", $stdout_write; open STDERR, ">&=", \*STDOUT; exec {"perl"} "perl", "-le", '$|++; for (1..10) { print $_; warn $_; sleep 1 }'; } close $stdout_write; while (<$stdout_read>) { print strftime("%FT%T", localtime) . " $_"; } wait; ϦμΠϨΫτ!
  9. #!/usr/bin/env perl use strict; use warnings; use POSIX 'strftime'; use

    IO::Select; pipe my $stdout_read, my $stdout_write; pipe my $stderr_read, my $stderr_write; my $pid = fork // die; if ($pid == 0) { close $stdout_read; close $stderr_read; open STDOUT, ">&=", $stdout_write; open STDERR, ">&=", $stderr_write; exec {"perl"} "perl", "-le", '$|++; for (1..10) { print $_; warn $_; sleep 1 }'; } close $stdout_write; close $stderr_write; my $select = IO::Select->new($stdout_read, $stderr_read); while ($select->count) { for my $fh ($select->can_read) { my $len = sysread $fh, my $str, 1024; if ($len) { my $type = $fh == $stdout_read ? "out": "err"; print strftime("%FT%T", localtime) . " $type $str"; } else { $select->remove($fh); close $fh; } } } wait; select!