Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

unix to perl questions

by deyaneria (Acolyte)
on Mar 11, 2015 at 23:18 UTC ( [id://1119704]=perlquestion: print w/replies, xml ) Need Help??

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

I'm a student working on Perl program the class had us write an Admin Menu in week two that did the following below, for week 4 we are to write it in Perl. I've had two weeks of unix and 1 week of Perl. I have spent hours looking for the correct syntax to change my working programn in UNIX to Perl Script.I want to stress I don't want homework script answers I just need a bit of help with syntax and what commands to use in this new language. I've taken other languages COBOL, C+ and most recently java and html but still trying to find similarities so I can connect the dots. The assignment is:Convert your second shell script (User Maintenance) into a Perl script. This Perl script must perform the following tasks: • Generate a menu to ask the system administrator for the task that he or she would like to see performed. • The available tasks are as follows: o Create a UNIX group. o Drop a UNIX group. o Create a user. o Drop a user. • Prompt the user for the choice, and perform the system command. • In addition, check to make sure that before creating either the user or the group that neither already exists; if it does already exist, print out the existing user ID, comment field, and home directory locations from the password file. Here is the code I have written thus far. I figured if I could get the first part working that the others would fall in place.

#! /usr/local/bin/perl –w #Author: # $choice = 0; Do{ Print “Admin Menu \n”; Print “To add a user, press 1 \n”; Print “To delete a user, press 2 \n”; Print “To Add a group, press 3 \n”; Print “To delete a group, press 4 \n”; Print “to exit this menu, press 5 \n”; Print “Please chose an option:” $choice =<>; chomp $choice; Print “You chose option: “; Print $choice; Print “\n”; } while $choice < 1 || $choice > 5; If ($choice == 1); { Do { nUsername = <>; Print “what is new users name?”; #get new user name Chomp $nUsername; #check that new user name is a string If $nUsername =~ tr/A-Za-z0-9//c; { #check to see if user exists if(getpwnam('$nUsername')) print "User exists\n"; } Else { $adduser = '/usr/sbin/adduser'; $cmd = qq($adduser --home $home --gecos $nUsername); #get new user password Do { Print “Please add password: \n”; $nPassword = <>; Print “Please re-enter password: \n”; $nPasstest =<>; } While $nPassword !eq $nPasstest; Print “Please enter group for user: \n”; nGroup= <>; #add user to group if getgrnam($group) { #check to see is group exists print $group; Print “already exists \n”; #add user to group Groupadd $nGroup; } Else {#if group does not exist create group groupadd $nGroup; Print $nGroup; Print “ has been added.\n”; } Else { Print “New username must be a string.”; $nUsername = \n; } while $nUsername = \n;

I tried to follow all recommendations for posting here. My apologies if I messed up the posting rules. I wanted to add what I am particularily looking for is the correct command to add a new group. However any other help would be appreciated. I am usng oracle vm with Ubuntu as a shell.

Replies are listed 'Best First'.
Re: unix to perl questions
by 2teez (Vicar) on Mar 11, 2015 at 23:55 UTC

    Hi deyaneria,
    Welcome to using Perl Programming Language.

    To start with I will advice you always use warnings and strict in your perl program.
    Secondly, am sure your perl program as you showed above would not compile to start with. Why? Does perl has "Do" or "do", "While" or "while", "Else" or "else".

    I think there is need to write the right syntax, then logic can then be put in the right place.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
      I tried using the use warnings: use strict; when i first got this version I had errors even with the simple "hello World" program putting them as you suggested. I found I have to put in the first line like this #! /usr/local/bin/perl –w I think it's due to the fact I'm using version v5.18.2.

        The page Use strict and warnings explains how to get your program working under strict. It sounds like in your case the best way to start your scripts would be

        #!/usr/local/bin/perl use warnings; use strict;

        (The -w command line switch is not needed if you use warnings;.)

        If you get errors, please post the exact error messages here; see How do I post a question effectively?

        ..I tried using the use warnings: use strict; when i first got this version I had errors even with the simple "hello World" program putting them as you suggested...

        How does the error read? Can you show it here?

        If you tell me, I'll forget.
        If you show me, I'll remember.
        if you involve me, I'll understand.
        --- Author unknown to me
Re: unix to perl questions
by Anonymous Monk on Mar 12, 2015 at 00:03 UTC

    It looks like you've got the general idea fairly well, but you're right that there are quite a few syntax issues to work out. First, it looks like you've written this in a program like Microsoft Word, resulting in incorrect capitalization, quoting characters, and such. I suggest you work with a plain text editor, or even better, a programmer's editor with syntax highlighting (depending on your preferred OS and windowing system we can make some suggestions).

    To learn the syntax, it's probably best to take a step back and first get a very short Perl script working, and then extend it with the features that you need. I recommend you start with perlintro, a short but very good introduction that will show you many of the things that you need for your script.

      I work it out in word but then have to retype it into vi. So none of the capitalizaion will be there unless it's a variable. I have written 2 other scripts so that are working so I am getting it. What is this programmers editor you speak of? I am running window 8, using oracle vm shell with Ubuntu, my Perl verison is v5.18.2.

        Komodo Edit or Sublime are good programmer's editors on Windows. However if you are doing this in the context of Unix you'd be better to set up a virtual machine (Virtual Box or VM Player for example) on your Windows box and run Unix in the VM. That way you can work with a real unix system and tools. There's a bit of work getting everything going that way, but you'll learn a lot!

        Perl is the programming world's equivalent of English
Re: unix to perl questions
by Anonymous Monk on Mar 12, 2015 at 00:00 UTC
    Also perl doesn't much like smart quotes ( “ ”) which means you used something like Word or some other doc editor, where as you should use a text editor (notepad) or a programmers editor (scite / ... padre )
      I do use word to work it out but my shell won't allow me to copy and paste into the shell so when I type it into vi (i even set the machine so I could to no avail). they will be changed to single quote lines.
Re: unix to perl questions
by Anonymous Monk on Mar 12, 2015 at 02:42 UTC
    Not beautiful, but better, I hope:
    #!/usr/local/bin/perl use strict; use warnings; use Term::ReadKey qw(ReadMode ReadLine); use IPC::System::Simple qw(system); my $choice=0; GETCHOICE: { print "Admin Menu\n"; print "To add a user, press 1\n"; print "To delete a user, press 2\n"; print "To add a group, press 3\n"; print "To delete a group, press 4\n"; print "To exit this menu, press 5\n"; print "Please choose an option: "; chomp($choice=<STDIN>); redo GETCHOICE if $choice < 1 || $choice > 5; } print "You chose option: $choice\n"; if($choice == 1) { my $nUsername; GETUSER: { print "What is new users name? "; chomp($nUsername=<STDIN>); # check that new user name is a string if($nUsername!~/^[A-Za-z0-9]+$/) { print "New username must be a string.\n"; redo GETUSER; } } # check to see if user exists if(defined getpwnam($nUsername)) { print "User exists\n"; } else { ## FIXME delete "echo" system("echo","/usr/sbin/adduser","--home", "/home/$nUsername","--gecos",$nUsername); # get new user password my ($nPassword,$nPasstest); GETPASS: { ReadMode("noecho"); print "Please add password: "; chomp($nPassword=ReadLine(0)); print "\n"; print "Please re-enter password: "; chomp($nPasstest=ReadLine(0)); print "\n"; ReadMode("restore"); redo GETPASS if $nPassword ne $nPasstest; } print "Please enter group for user: "; chomp(my $nGroup=<STDIN>); # add user to group if(defined getgrnam($nGroup)) { # check to see is group exists print "$nGroup already exists\n"; # add user to group system("echo","groupadd",$nGroup); } else { # if group does not exist create group system("echo","groupadd",$nGroup); print "$nGroup has been added.\n"; } } }
      What is echo? I know we use this in UNIX in place of print. I see that you chose to use STDIN and using ReadLine(0) is that an array index? So you are testing changing nPassword to array ReadLine(0) and comparing it to nPassTest? Just want to be sure I am understanding correctly.
        system("echo",...) is roughly equivalent to print.
        I guess the reason why our anonymous brother didn't use the latter is that you have the "real" commands for debugging, and to change from "dry run" to "wet run" (or how this may be called) afterwards you do (in vi command mode)
        :%s/system("echo",/system(/
        BTW for vi on Windows, see http://www.vim.org/ugrankar.pdf
      I feel like am stalking you...lol Really I am fascinated by the code. Getchoice would be function or subroutine? This eliminates the Do-While loop.I've also never seen "defined" what does that do exactly is it another way of doing a comparison?
        defined does pretty much exactly what the English word suggests: It tests whether the variable has a defined value, which is to say, whether any value has ever been assigned to the variable.

        In this particular case, if(defined getpwnam($nUsername)) checks to see whether getpwnam returns a value at all:
        - If it finds the user, it will return something and "something" is always defined, so the test evaluates as true.
        - If it doesn't find the user, it will return nothing (not just an empty value or a false value, but the absence of a value - in Perl, this not-a-value is called undef, for "undefined"), and the test evaluates as false.

Re: unix to perl questions
by Anonymous Monk on Mar 12, 2015 at 07:36 UTC

    Using a subroutine and a hash will help take out some troubles.
    Something in this like:

    use warnings; use strict; my $choice; my $user_grp = read_doc("/etc/passwd"); my %admin_menu = ( 1 => sub { my $username = get_input("Enter username: "); if ( exists $user_grp->{$username} ) { print "\nUser ", $username, " exist!"; return; } system( "useradd", "-u $$", "-g", "users", "$username" ); }, 2 => sub { my $username = get_input("Enter username: "); if ( exists $user_grp->{$username} ) { system( "userdel", "$username" ) if get_input("Do you really want to remove the $username +?: ") =~ /\by\b/i; } }, 3 => sub { # do for groupadd }, 4 => sub { # do for groupdel }, 5 => sub { get_input("Exiting the Program\n"); exit(); }, ); do { admin_menu(); $choice = get_input("Enter your choice: "); if ( $choice < 1 or $choice > 5 ) { admin_menu(); } else { $admin_menu{$choice}->(); } } while (1); sub get_input { my $prompt = shift; print $prompt; chomp( my $value = <> ); return $value; } sub read_doc { my $file = shift; my %user; open my $fh, '<', $file or die $!; while (<$fh>) { my ( $name, $grp ) = ( split /:/ )[ 0, 4 ]; $user{$name} = $grp; } return \%user; } sub admin_menu { print << "UNIX_ADMIN"; Admin Menu To Add a User, press 1: To Delete a User, press 2: To Add a group, press 3: To Delete a group, press 4: To Exit this Menu, press 5: UNIX_ADMIN }

      I will be pouring over this code as I did the one left last night to figure out all the symbols. I thought subroutines might be useful here and I spent most of the night researching. I notice you added the do-while loop back in as in the previous example it was taken out. It's interesting to see the different ways it can be done. Lots of ah-ha moments thanks to all those here.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (2)
As of 2024-04-26 00:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found