Created
April 10, 2011 22:30
-
-
Save norm/912802 to your computer and use it in GitHub Desktop.
run multiple processes that output to named pipes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# | |
# A script to enable running multiple background processes that output | |
# to named pipes from one controlling window. | |
# | |
# To install: | |
# | |
# 1. Install pre-requisite modules from CPAN: | |
# | |
# sudo cpanm Capture::Tiny Config::Std Proc::Fork | |
# | |
# 2. Copy this file into your $PATH: | |
# | |
# curl <raw_file_url> > /tmp/pipe_runner | |
# sudo mv /tmp/pipe_runner /usr/local/bin | |
# sudo chmod 755 /usr/local/bin/pipe_runner | |
use Modern::Perl; | |
use Capture::Tiny qw( capture ); | |
use Config::Std; | |
use Pod::Usage; | |
use POSIX qw( mkfifo ); | |
use Proc::Fork; | |
use Term::ANSIColor qw( :constants ); | |
use constant PIPE_MODE => 0644; # -rw-r--r-- | |
my $config = shift // 'pipe_runner.conf'; | |
pod2usage() if '-h' eq $config; | |
read_config $config => my %config; | |
my @outputs = keys %config; | |
foreach my $output ( @outputs ) { | |
run_fork { | |
child { | |
say MAGENTA . "[$$] $output" . RESET; | |
$SIG{'INT'} = sub { | |
unlink $output; | |
exit 0; | |
}; | |
while ( 1 ) { | |
unless ( -p $output ) { | |
unlink $output; | |
mkfifo( $output, PIPE_MODE ) | |
or die "Cannot make pipe $output: $!"; | |
} | |
my $pipe; | |
open( $pipe, '>', $output ) | |
or die "Cannot write to $output: $!"; | |
print BOLD . CYAN . "Running $output:" . RESET . "\n"; | |
my( $stdout, $stderr ) = capture { | |
system( $config{ $output }{'command'} ); | |
}; | |
print {$pipe} $stdout; | |
close $pipe; | |
say $stderr; | |
# avoid dup signals | |
select undef, undef, undef, 0.1; | |
# touch to confound anything caching based upon mtime | |
utime undef, undef, $pipe; | |
} | |
} | |
} | |
} | |
while (1) { | |
# infinite loop of doing nothing, all handled in the children | |
sleep 3600; | |
} | |
exit; | |
__END__ | |
=head1 NAME | |
B<pipe_runner> - run multiple processes that output to named pipes | |
=head1 SYNOPSIS | |
B<pipe_runner> <config> | |
=head1 CONFIG FILE | |
The config file is in a common "INI" style, like so: | |
[output/screen.css] | |
command = echo "SCREEN" | |
[output/lightbox.css] | |
command = echo "LIGHTBOX" | |
The section name is the named pipe to create, which the output of the | |
command will be sent to when read. | |
=head1 AUTHOR | |
Mark Norman Francis, L<[email protected]>. | |
=head1 COPYRIGHT AND LICENSE | |
Copyright 2011 Mark Norman Francis. | |
This library is free software; you can redistribute it and/or modify it | |
under the same terms as Perl itself. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment