Skip to content

Instantly share code, notes, and snippets.

@norm
Created April 10, 2011 22:30
Show Gist options
  • Save norm/912802 to your computer and use it in GitHub Desktop.
Save norm/912802 to your computer and use it in GitHub Desktop.
run multiple processes that output to named pipes
#!/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