diff options
Diffstat (limited to 'bin/x')
-rwxr-xr-x | bin/x | 124 |
1 files changed, 124 insertions, 0 deletions
@@ -0,0 +1,124 @@ +#!/usr/bin/env perl + +use v5.34; +use warnings; +use feature 'signatures'; +no warnings ('experimental::signatures', 'experimental::smartmatch'); +use Getopt::Std (); + +sub usage($fh) { + print $fh <<~'EOF' + Usage: + x COMMANDS... [ '&&' / '||' / '|' ] COMMANDS... + x COMMANDS... [ 'AND' / 'OR' / 'PIPE' ] COMMANDS... + x -h + EOF +} + +sub help($fh) { + print $fh <<~'EOF' + + Options: + -h, --help show this message + + COMMAND the command to be executed + '&&' / AND "AND" logical operator + '||' / OR "OR" logical operator + '|' / PIPE pipe operator + + + Run command chained together with operators. + + NOTE: Remember to quote '&&', 'OR' and '|' operators, otherwise + they'll get captured by the shell and not be passed to the 'x' + program! + + + Examples: + + Measure the time of two commands: + + $ time x sleep 1 '&&' sleep 2 + # equivalent to: + $ time sh -c 'sleep 1 && sleep 2' + + + Notify when either of the commands finish: + + $ boop x cmd-1 '||' cmd-2 + EOF +} + + +for (@ARGV) { + last if $_ eq '--'; + if ($_ eq '--help') { + usage *STDOUT; + help *STDOUT; + exit; + } +} + +my %opts; +if (!Getopt::Std::getopts('h', \%opts)) { + usage *STDERR; + exit 2; +} + +if ($opts{h}) { + usage *STDOUT; + help *STDOUT; + exit; +} + + +sub status_for($n) { + if ($n == -1) { + return 127; + } elsif ($n & 127) { + return $n & 127; + } else { + return $n >> 8; + } +} + +my @AND = ('&&', 'AND'); +my @OR = ('||', 'OR'); +my @PIPE = ('|', 'PIPE'); +my @OPS = (@AND, @OR, @PIPE); + +my @CMD; +for (@ARGV) { + if ($_ ~~ @OPS) { + system @CMD; + @CMD = (); + if ($_ ~~ @AND && $?) { + exit status_for($?); + } elsif ($_ ~~ @OR && !$?) { + exit 0; + } elsif ($_ ~~ @PIPE) { + ... + } + } else { + push @CMD, $_; + } +} + +exit status_for(system @CMD); + + +__END__ + +=head1 NAME + +x - chain shell commands without creating a subshell + +=head1 SYNOPSYS + +x COMMANDS... [ '&&' / '||' / '|' ] COMMANDS... + +x COMMANDS... [ 'AND' / 'OR' / 'PIPE' ] COMMANDS... + +x -h + +=cut |