Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Is using '-s' really bad and why?

by Rhys (Pilgrim)
on Oct 18, 2004 at 16:26 UTC ( [id://400208]=perlquestion: print w/replies, xml ) Need Help??

Rhys has asked for the wisdom of the Perl Monks concerning the following question:

From perlrun:

(-s) enables rudimentary switch parsing for switches on the command line after the program name but before any filename arguments (or before an argument of --). This means you can have switches with two leading dashes (--help). Any switch found there is removed from @ARGV and sets the corresponding variable in the Perl program. The following program prints "1" if the program is invoked with a -xyz switch, and "abc" if it is invoked with xyz=abc.

#!/usr/bin/perl -s if ($xyz) { print "$xyz\n" }

Do note that --help creates the variable ${-help}, which is not compliant with "strict refs".

Now, this last thing is really enough for me. I use strict in just about everything I write that I intend to actually use, since it has found about a zillion things that I've done wrong in the past.

People also pointed out that using -s is pretty much a giant security hole and can lead to the unanticipated creation of strange and interesting variables. Another compelling argument (to me, anyway) is that the docs themselves call this a 'rudimentary switch parsing' method, whereas Getopt::Std and Getopt::Long are more complete ways of doing this.

So what? Where's the question? Right here: There's a guy in my office who likes -s. He says that the first time he did a Google search on using command-line arguments with Perl, a link to an article that suggested -s was the top hit. He also says that since he is the only one that uses his scripts and because he does validation on the variables so passed, the security risks are moot.

So does anyone have a really strong reason NOT to use -s? It seems both kludgy and dangerous to me, but I'm not having fun trying to convince him. Any advice is welcome.

--J

Replies are listed 'Best First'.
Re: Is using '-s' really bad and why?
by Anonymous Monk on Oct 18, 2004 at 17:20 UTC

    Well, here are some of my thoughts and attempts, some might be a good argument, others might not be (depending on the situation and the code).

    First, I wondered what would happend if some of the predefined variables are changed (as in passed as an argument), but then I thought of changing variables in another package.
    When I passed the argument -Abc::Def::ghi=jkl then the variable $Abc::Def::ghi was changed, at this moment I'm too lazy to find out what would happend if Abc::Def was a real package, which does rely on the value...

    Now, back to the builin variables,

    • Argument -[=45, nothing happend.
    • Argument -,=abc: $, was changed to "abc", but "abc" wasn't used as list seperator in print @x; which means that print join $,, @x; isn't the same as print @x;
    • Argument -\"=abc: $" was changed to "abc", and print "@x" was the same as join $", @x;, or in other words, the value was changed and is used.
    • Argument -#=%06d (that var is deprecated but I tried it anyway): value of $# is changed but not used
    • Argument -]=2.019: value changed, 'use 5.006' still uses the correct version, but if ($] < 5.006) will fail. And particulary intresting about this is that $] is a read-only value

    These are just some vars from perldoc perlvar on which there probably isn't checking and can effect the output/working of the script...

    But aslong as -s is used with care (as in not in public scripts which may be run by others) I don't see any problem using -s, ofcourse it is a lot safer to use a GetOpt module, which is what I usually do.

    Also I don't think -s is the top hit on google, I rather think it is either one of the following: -p, -e, -n, -i or -l. (Or atleast those are the ones which I reguarally use).

      Wouldn't searching for '-s' on Google be rather futile?

      Just a thought... ;-)

      Cheers,

      -- Dave :-)


      $q=[split+qr,,,q,~swmi,.$,],+s.$.Em~w^,,.,s,.,$&&$$q[pos],eg,print
        Search for "-s" then :)

        You want a futile search, try to search for "The Who", when "The" is too common a word, and so is "Who". Quotes are useless. You'd be better off searching for Daltry and Townsend, which is useless if you didn't know Who The Who Were, and you couldn't Guess Who (pun intended) was in the Who.

        Amazon is just as bad. Try searching for "The Band".

Re: Is using '-s' really bad and why?
by grinder (Bishop) on Oct 18, 2004 at 21:01 UTC
    So does anyone have a really strong reason NOT to use -s

    I do. It has weird semantics that can trip you up. Consider:

    % cat s #! /usr/bin/perl -s print "x is [$x]\n"; __END__ ~/perl% ./s -x=s x is [s] ~/perl% ./s -x s x is [1]

    I'm not in the habit of using = to set flag values, so on the odd occasion that I use -s it always trips me up. So -s is only for my private stuff that no-one else needs to use, ever. Even so, I tend to print out flag values as a reminder to watch out for flags that I might be accidently setting to 1.

    That, and it doesn't play very nicely with strict 'vars'.

    On the other hand, I can remember how it works, whereas when using Getopt::Std or Getopt::Long I always have to consult the documentation, or cut and paste some code from another program. But still, those modules do The Right Thing, so there's really no reason not to use them in programs that will be run by anyone other than yourself. The -s assignment oddity is just too annoying.

    Update: it might sound like I'm advocating that it is alright to use -s on some occasion. I should point out that the number of scripts I have written that I can recall using -s make a grand total of... 1.

    - another intruder with the mooring of the heat of the Perl

Playing with module::variables and -s
by pernod (Chaplain) on Oct 18, 2004 at 18:20 UTC

    For what it's worth, here's my fiddling with -s and modules. Consider the following toy module (With horrible style. Don't write real code like this, kids ;):

    1: package MyMod; 2: #$value = "Ding!"; 3: sub spit { 4: return $value; 5: } 6: 1;
    And the following little script:
    1: use MyMod; 2: print MyMod::spit(), "\n";

    With the following command line, this will print "Hey Monks!"

    c:/monks/temp $perl -s ss.pl -MyMod::value="Hey Monks!" Hey Monks!

    If, on the other hand, I uncomment line 2 in MyMod.pm, setting the default value of the variable to "Ding", the same command line will return the value set in the module.

    c:/monks/temp $perl -s ss.pl -MyMod::value="Hey Monks!" Ding!

    To my eyes, this allows -s to set uninitialised module variables from the command line, but it will not override variables already defined. I don't really see how this can come in handy though. Perhaps some funky obfuscation?

    Oh well. Curiosity strikes again :)

    pernod
    --
    Mischief. Mayhem. Soap.

      To my relief, perl -s -e'print $^O' -- -^O=foo doesn't print foo. But perl -we'print `perl -s -eprint" "\$^O -- -\x0f=foo`' does.
Re: Is using '-s' really bad and why?
by pg (Canon) on Oct 18, 2004 at 17:42 UTC
    "So does anyone have a really strong reason NOT to use -s?"

    Now, I will ask the other way around, does anyone has a strong reason why -s should be used.

    I have this principle in general that, when you code, you don't do wierd things.

    "He also says that since he is the only one that uses his scripts and because he does validation "

    The world is changing everyday, so tomorrow he might no longer be the only one. He does validation, true, but by using -s, his code is much more fragile, probably becomes another piece of crape that nobody else wants to maintain or touch.

Re: Is using '-s' really bad and why?
by rdm (Hermit) on Oct 19, 2004 at 02:03 UTC

    This is a great example of a very well written, well tested, and well reasoned set of arguments. That I respectfully disagree with.

    '-s' is not, in itself, intrinsically bad. It does have side effects, as demonstrated by far finer minds than my own, but these do not negate it's usefullness - with the proviso that you are aware of the possible abuses, and take care to mitigate them.

    For example: You would not use '-s' in a module-heavy program, as there is too much risk of malicious arguments changing the behaviour of the modules.

    You would, OTOH, use it in a small script that has no dependant modules. Even the use of '--x' in the context of use strict; is not entirely bad - as it produces an error response to an invalid invocation, although not exactly a useful error response. (Which is why I do not call it good!)

    Lastly, in response to the question 'Why use it?', the answer is simple. If you are writing a small program, especially one that might be run in a number of environments - that you have little or no control over, it allows you to avoid yet another module dependancy.

    -Rob

    -Reality might not get out of Beta today. (O.Timas, "Bot")
Re: Is using '-s' really bad and why?
by melora (Scribe) on Oct 19, 2004 at 00:51 UTC
    Speaking for myself only, I don't see the advantage over simply passing a value from the command line (except that it provides a much less secure way to do it). And as Rhys says, the fact that it won't get past "use strict;" does it for me.
Re: Is using '-s' really bad and why?
by SpanishInquisition (Pilgrim) on Oct 18, 2004 at 18:15 UTC

    Seems safe enough if he knows the risks and limitations. Nobody likes a code nazi...

Re: Is using '-s' really bad and why?
by belden (Friar) on Oct 19, 2004 at 20:58 UTC

    I occassionally use -s in one-off programs. Once I find myself setting more than 3 vars with -s, I switch over to something more suited to the task - usually Getopt::Long, since I like its flexibility.

    At one point I was (ab)using -s so much that I wrote a silly module to parse the variables set by -s. The module is pretty boring; code that used it looked like this:

    #!/usr/bin/perl -s use Getopt::Sparse; our ( $foo, $bar ) ; # set on command line sparse( foo => [ qw( f foo -foo --foo ) ], bar => [ qw( b bar -bar --bar ) ], ); print "foo: $foo\nbar: $bar\n" ;

    I've currently got one script that uses that module: the test script for the module.

    Fortunately I've found better things to waste my time on these days :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://400208]
Front-paged by bart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2024-04-19 18:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found