Bash One-liners
PERL ONE-LINERS IN BASH SCRIPTSSometimes you want the best of both worlds. Bash is great for orchestrating system tasks, but Perl brings that extra punch when you need text processing, colorful output, and proper error handling all rolled into one elegant line.
Today we are looking at a pattern I use all the time: feeding shell commands through a Perl one-liner that executes them with style.
Part 1: THE HEREDOC SETUP
First, we need to collect our commands. Bash heredocs are perfect for this. The quoted delimiter prevents variable expansion, keeping our commands pure:The -r flag prevents backslash interpretation, and -d '' reads until EOF. Now $CMDS holds our multi-line command list, ready for processing.read -r -d '' CMDS <<'CMDS' sudo apt install -y build-essential sudo cpanm JSON::XS CMDS
Part 2: THE PERL ONE-LINER ANATOMY
Here is where the magic happens:Let us break down those flags because they are the secret sauce:echo $CMDS | perl -MTerm::ANSIColor=':constants' -nlE ' chomp; unless ( m~^$|^\#~ ) { say BOLD GREEN qq|> $_|, RESET; system $_; unless ($? == 0) { die BOLD RED qq|> Fail: $?\n|, RESET; } } '
-n Wraps your code in a while(<>) loop, processing line by line -l Handles line endings automatically (chomp on input, newline on print) -E Enables modern features like say() - think of it as -e with benefits -M Loads modules, here importing ANSI color constants
Part 3: WHAT THE SCRIPT ACTUALLY DOES
Walking through the logic:Strips the trailing newline. With -l this is somewhat redundant, but being explicit never hurts and makes the intent crystal clear.chomp;
Skip empty lines and comments. The tilde delimiters let us use slashes freely inside the regex. This is the kind of thoughtful touch that makes Perl one-liners maintainable.unless ( m~^$|^\#~ ) {
Print the command we are about to run in bold green. The qq|...| quoting style avoids escaping issues. Visual feedback matters when running system commands - you want to see what is happening.say BOLD GREEN qq|> $_|, RESET;
Execute the command. This is the whole point. Perl's system() hands off to the shell and waits for completion.system $_;
Check the exit status. If anything goes wrong, die in bold red with the actual exit code. No silent failures here.unless ($? == 0) { die BOLD RED qq|> Fail: $?\n|, RESET; }
Part 4: WHY THIS PATTERN WORKS
You might ask: why not just run the commands directly in bash? A few reasons:- Unified error handling - one place to catch and report failures
- Consistent formatting - every command gets the same visual treatment
- Filtering logic - easy to skip comments, blank lines, or add conditions
- The -n loop - scales to any number of commands without extra scaffolding
This is the Perl philosophy in action: make the common case elegant and the complex case possible.
Part 5: VARIATIONS TO TRY
Dry run mode - just show what would execute:Add timing information:echo $CMDS | perl -nlE 'say "Would run: $_" unless /^$|^#/'
Log to a file while also printing:echo $CMDS | perl -MTime::HiRes=time -nlE ' next if /^$|^#/; my $start = time; system $_; printf "Took %.2fs\n", time - $start; '
CLOSING THOUGHTSecho $CMDS | perl -nlE ' next if /^$|^#/; say $_; open my $log, ">>", "commands.log"; say $log scalar(localtime) . ": $_"; system $_; '
The combination of bash's process control and Perl's text processing creates something greater than either alone. This heredoc-to-one-liner pattern has saved me countless hours when setting up new systems or running maintenance scripts.
The flags -nlE with -M for modules will cover 90% of your one-liner needs. Commit them to muscle memory and you will reach for this technique often.
Created By: Wildcard Wizard. Copyright 2026