http://www.perlmonks.org?node_id=11102960

"Just sit right back and you'll hear a tale
a tale of a fateful trip,
that started from this simple term,
aboard this single slip."

Please, dear reader, learn from my mistake. (It will likely be less painful than repeating it yourself.)

Earlier today I did something I have done dozens of times before-created a command-line perl script (a "one-liner", for some very long definition of a "line") to create a file containing a subset of messages from a set of compressed logs, with the intent of pulling them back to my machine for additional processing. I launched it in a screen session, saw it was running and would take some time to begin generating output, and stepped away for lunch. I was rather surprised, however, when I returned to find it throwing "No space left on device" messages-especially when I looked to find that the partition's previous 40GB of free space was now zero. After cleaning up the space, I began trying to find the cause.

In digging through my code, I almost missed the issue-a line of the form if ( $str -~ m/some pattern/ ) { print $str; }. Notice the issue? An off-by-one-key error from a en.US keyboard, where [-/_] and [=/+] are beside one another. This was compounded by skipping the well-espoused logic of use strict; use warnings; because it was a "one-liner" (where "-Mstrict -Mwarnings" would have added a mere 19 characters in length). Had I have done so, instead of:

# made-up example with actual issue $ perl -le 'my $str = q{zxcv}; if ( $str -~ m/some pattern/i ) { print + $str; }' zxcv
I would have seen:
# made-up example with actual issue, with strict and warnings $ perl -Mstrict -Mwarnings -le 'my $str = q{zxcv}; if ( $str -~ m/some + pattern/i ) { print $str; }' Use of uninitialized value $_ in pattern match (m//) at -e line 1. Argument "zxcv" isn't numeric in subtraction (-) at -e line 1. zxcv
Seeing unexpected output like that (that early) would likely have resulted in my cancelling the command to investigate, and thus likely not filling up 40GB of storage.

I know this will probably be like the tone after the television broadcast day ended to a sleeping viewer, but maybe, just maybe, it will help someone. In the end, learning from others' mistakes is often less painful (but not necessarily as memorable).

(And yes, I do use the the duo on most every script I write-just not always on "one-liners".)

  • Comment on Off by one key... or yet another example of why strict and warnings are always a good idea (even for "one-liners")
  • Select or Download Code

Replies are listed 'Best First'.
Re: Off by one key... or yet another example of why strict and warnings are always a good idea (even for "one-liners")
by LanX (Archbishop) on Jul 18, 2019 at 00:53 UTC
    Good story, we've all been thru this once. =)

    Just a hint

    > (And yes, I do use the the duo on most every script I write-just not always on "one-liners".)

    well you could set up an alias psw=perl -Mstrict -Mwarnings if you think that you'd really go to declare variables.

    IIRC there was also a possibility to globally require a a piece of Perl code whenever your installation runs.

    update

    > where "-Mstrict -Mwarnings" would have added a mere 19 characters in length

    or see perlrun#PERL5OPT: "Switches in this variable are treated as if they were on every Perl command line."

    C:\>set PERL5OPT=-w -Mstrict C:\>perl -e"print $x" Global symbol "$x" requires explicit package name (did you forget to d +eclare "my $x"?) at -e line 1. Execution of -e aborted due to compilation errors.

    though you might prefer to avoid strict vars in one-liners

    C:\>set PERL5OPT=-w -Mstrict=refs,subs C:\>perl -e"print $x" Name "main::x" used only once: possible typo at -e line 1. Use of uninitialized value $x in print at -e line 1.

    comming back to your original case

    C:\>perl -le "my $str = q{zxcv}; if ( $str -~ m/some pattern/i ) { pri +nt $str; }" Use of uninitialized value $_ in pattern match (m//) at -e line 1. Argument "zxcv" isn't numeric in subtraction (-) at -e line 1. zxcv

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      though you might prefer to avoid strict vars in one-liners
      I like to pretend that I don't use strict and warnings on oneliner because it lets me use the full power of unconstrained perl, but trully 95% of the time I just want to be able to use variables without declaring them (4.999% are for being able to leave a word unquoted. The rest is for shooting myself in the foot)

      But this is where Windows is clearly superior to Linux, because you can use ' to be able to use undeclared variables where Linux would require the twice boringer ::

      perl -Mstrict -E "$'x = 2; say $'x" 2
      Or if you're a true smartass, you can just limit yourself to using only _, a and b as variable names :P

        > Windows is clearly superior to Linux,

        You mean because on Windows you need to put the code in double quotes which don't collide with single quotes?

        The best thing would be a Perl shell without the need to quote at all and calling OS commands inside out.

        update

        the second best thing is perl <RET>

        Perl reads from STDIN then, Ctrl-d or __END__ ends it. Works on both plattforms.

        C:\>perl -w print $x ^D Name "main::x" used only once: possible typo at - line 2. Use of uninitialized value $x in print at - line 1. C:\>

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        > this is where Windows is clearly superior to Linux

        Let me correct you. I'm getting 2 as the output on Linux, too. That's because `$'` is not a valid variable name in the shell (at least in bash which I use).

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Off by one key... or yet another example of why strict and warnings are always a good idea (even for "one-liners")
by Fletch (Chancellor) on Jul 18, 2019 at 12:43 UTC
      the original suggestion was a unicode -ǝ or -Ǝ

      That was a joke, right? I don't know about you but there's no way that I'm going to be able to find the codepoint for that symbol and then work out the right combination of keys to press to generate it for any given combination of keyboard+shell+term+OS in a shorter space of time than it takes to type -Mstrict -w

        Quite (I had to cheat and use the OS X Symbol menu to get them when I typed them above and it still took a minute to scroll to the E's). I think later in the thread saner (or perhaps, less facetious) heads were prevailing and going over free ASCII option characters and maybe -[Zz] being available.

        The cake is a lie.
        The cake is a lie.
        The cake is a lie.

      the original suggestion was a unicode -ǝ or -Ǝ

      Bad idea. There are still many ASCII letters left in perlrun. perl isn't ls. And most people, including me, don't know from memory how to enter -ǝ or -Ǝ. Using perl should be easy, not hard. How about using the unused "-r" (as in run), making perl -r 'say "hi"' the shorter equivalent of perl -Mstrict -w -E 'say "hi"'?

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Off by one key... or yet another example of why strict and warnings are always a good idea (even for "one-liners")
by shmem (Chancellor) on Jul 18, 2019 at 23:49 UTC

    Setting up an alias in your shell's rc file helps - for bash:

    alias sperl='env PERL5OPT="-Mstrict -Mwarnings" perl'

    You keep running your oneliners without strictures; but if something blows or feels fishy, you just interrupt and type

    prompt$ s!!

    to run your latest command under strict and warnings.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'