Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

perl if statement

by Drsin (Novice)
on Feb 29, 2016 at 18:37 UTC ( [id://1156470]=perlquestion: print w/replies, xml ) Need Help??

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

Dear All, I am new to Perl. My code below seems to work only on the else statement even when the if evaluate to true:

if (grep /($FORM{user}|$FORM{pin})/i, "/export/install/users.txt") { `/export/install/sysmo.sh > /export/install/log.txt`; print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Account/title>"; print "</head>"; print "<body>"; print "<h2>Hello $user, your account - ready</h2>"; print "</body>"; print "</html>"; exit(0); } else { print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title>Account /title>"; print "</head>"; print "<body>"; print "<h2>Your user/pin incorrect - Use correct input</h2>"; print "</body>"; print "</html>"; }

Replies are listed 'Best First'.
Re: perl if statement
by 1nickt (Canon) on Feb 29, 2016 at 19:04 UTC

    Hi Drsin,

    It looks like you want to look up in a file and see if either one of two variables match the contents of the file. You're trying to do that in one statement (looks like you sorta copied a shell grep command), but you need some more steps. (You could do it in one command in Perl, but it looks like you want to have this in a script, so let's go with multiple steps as it will be easier to see what's going on.)

    You will need to:

    1. use strict; and use warnings;
    2. Open the file -- see open or Path::Tiny
    3. Read the file -- see readline or Path::Tiny
    4. Store the contents in a list -- see perldata, push
    5. Compare your list of variables against the list items -- see perlsyn for conditionals and loops
    6. See if one thing matches another -- see perlrequick (regular expression quick start)
    7. if there's a match, print one thing
    8. or print the other

    You have #7 and #8 down ;-) The best place to start for the rest, if you haven't already taken time to study it, is the basic Perl documentation perlintro which will touch on most of these things.

    Hope this helps!


    The way forward always starts with a minimal test.
Re: perl if statement
by afoken (Chancellor) on Feb 29, 2016 at 18:43 UTC
    if (grep /($FORM{user}|$FORM{pin})/i, "/export/install/users.txt") {

    What do you expect grep to do here? grep does not read files, it just processes arrays (even those that contain only one string, like "/export/install/users.txt").

    (OK, maybe you want that $FORM{user} or $FORM{pin} contain a regular expression that matches the string "/export/install/users.txt", but I doubt that.)

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Hi Alex, I wanted grep to find user|pin in the file users.txt(this is UNIX flat file with list of users and their pin. if YES then it should run the command in system() and if NO it should run command in else.

        Where are you getting $FORM{user} and $FORM{pin} from ?

        poj
Re: perl if statement
by GrandFather (Saint) on Mar 01, 2016 at 00:02 UTC

    Quite aside from the if issue, that code smells bad. There are many techniques that will will clean it up, but the end point is to move the HTML stuff out of the source altogether into a template. The following code generates the template file as a convenience for testing (just run the script). Usually the "create file" stuff isn't required!

    #!/usr/bin/perl use strict; use warnings; use HTML::Template; # Create a test template file my $tmplFileName = "template.htmlt"; open my $tmplOut, '>', $tmplFileName or die "Can't create $tmplFileNam +e: $!\n"; print $tmplOut <<TMPL; Content-type:text/html <html> <head> <title>Account/title> </head> <body> <h2><TMPL_VAR message /></h2> </body> </html> TMPL close $tmplOut; # "production" code my $tmpl = HTML::Template->new(filename => $tmplFileName); my $user = 'Mr. Foo'; if (1) { $tmpl->param(message => "Hello $user, your account - ready"); print $tmpl->output(); exit 0; } else { $tmpl->param(message => "Your user/pin incorrect - Use correct in +put"); print $tmpl->output(); }

    Prints:

    Content-type:text/html <html> <head> <title>Account/title> </head> <body> <h2>Hello Mr. Foo, your account - ready</h2> </body> </html>

    Note too that the test file content is generated using a HEREDOC to inline the file contents. If you really need to include a fragment of HTML in your source code that's a much nicer way to do it than multiple print statements!

    Also note the use of strictures (use strict; use warnings;) and the open statement using lexical file handle and result testing.

    Premature optimization is the root of all job security

      Note that you can also simply place your template code into the DATA file (which begins with the token "__END__" or "__DATA__" at the end of your script), loading it with the filehandle parameter to HTML::Template::new() instead of the filename parameter. I like to use this technique for very simple scripts/short templates, as it keeps your HTML in the same physical file but separate from your Perl program:

      #!/usr/bin/perl use strict; use warnings; use HTML::Template; my $tmpl = HTML::Template->new( filehandle => \*DATA ); my $user = 'Mr. Foo'; if (1) { $tmpl->param( message => "Hello $user, your account - ready" ); print $tmpl->output(); exit 0; } else { $tmpl->param( message => "Your user/pin incorrect - Use correct in +put" ); print $tmpl->output(); } __END__ Content-type:text/html <html> <head> <title>Account/title> </head> <body> <h2><TMPL_VAR message /></h2> </body> </html>

      Hope this helps!


      The way forward always starts with a minimal test.

        Sure, Perl provides lots of ways of providing inline data that are better than the string of print statements used by the OP. I use DATA a lot for one off scripts that filter data I've copied and pasted from somewhere for example (Clipboard saves the need for paste and DATA though). If I need a fragment of HTML inlined then a HEREDOC is a really good choice because it makes the HTML clear and puts it right where it's used.

        However, the big win with using a template system (there are may btw - HTML::Template is a really good starting point) is being able to spin off the HTML into something that is very close to a static page file that a page designer can work on without having to have any understanding of the business code that uses it. Encouraging this usage pattern is why I went to the trouble of creating a test file in the example.

        The problem with the DATA section is that it doesn't scale. There is only one of them. Inline data seems rather like peanuts, it's hard to stop at one!

        Premature optimization is the root of all job security
Re: perl if statement
by Laurent_R (Canon) on Feb 29, 2016 at 18:55 UTC
    How do you know that:
    if (grep /($FORM{user}|$FORM{pin})/i, "/export/install/users.txt") {
    evaluates to true? This is very unlikely.

    Take a look at what the grep function does, it is not what you apparently think. In Perl, grep is used to filter the elements of an array.

      Hi Laurent, You are right.. I am thinking more of shell script grep. what ways can I get this done in Perl.. any help appreciated.
        Well, for changing as little as possible to your code, you could slurp the content of the file into an array and then use your grep function on that array.

        One quick and simple possibility is as follows:

        my $infile = "/export/install/users.txt"; open my $IN, "<", $infile or die "Cannot open $infile $!"; my @lines = <$IN>; if (grep /($FORM{user}|$FORM{pin})/i, @lines) { # ... }
Re: perl if statement
by AnomalousMonk (Archbishop) on Mar 01, 2016 at 00:05 UTC

    Just a parenthetic note: neither the  "<title>Account/title>" string in the if-block true clause nor the  "<title>Account /title>" string in the false clause of the OPed code are valid HTML elements.


    Give a man a fish:  <%-{-{-{-<

      which is a one line fix in the templated version, and a fix in two different places in the code in the OP's version. ;-)

      Templates for the win!

      Premature optimization is the root of all job security
Re: perl if statement
by Anonymous Monk on Mar 01, 2016 at 14:22 UTC

    From your other posts in this thread, especially this one, I get the feeling that you are searching the file for the literal string "username|pin" - is that correct? Because if so, your pattern is not correct, as it will match any line that contains either the username or the pin due to the alternation |. You should probably be using the pattern /^\Q$FORM{user}|$FORM{pin}\E$/ instead (see quotemeta for what \Q...\E does). Otherwise, you've built yourself a huge security hole if someone sets their password to, for example "."!

    Could you show us an example of what your input file actually looks like?

      Hi.. the text file looks:
      SAPPE 5681 ANNE 8152 AUDIT 8302 AUDIT1 5201 AUDIT3 1124
        Thank you all. I sorted the issue. It was my text file format. Now I made it:
        SAPPE|5681 ANNE|8152 AUDIT|8302 AUDIT1|5201 AUDIT3|1124

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-19 03:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found