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
| [reply] |
|
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.
| [reply] |
|
#!/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? | [reply] [d/l] [select] |
|
|
|
| [reply] |
|
|
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.
| [reply] |
|
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.
| [reply] |
|
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
| [reply] |
|
|
|
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 ) | [reply] |
|
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.
| [reply] |
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";
}
}
}
| [reply] [d/l] |
|
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.
| [reply] |
|
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
| [reply] [d/l] [select] |
|
|
|
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?
| [reply] |
|
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.
| [reply] [d/l] [select] |
|
|
|
Re: unix to perl questions
by Anonymous Monk on Mar 12, 2015 at 07:36 UTC
|
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
}
| [reply] [d/l] |
|
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.
| [reply] |