perl 创建系统用户
 
 
 
一、标量
1、perl 有三种变量:标量、数组、哈希
2、字符相加不是用“+”号,而是用“.”
3、
#!/usr/bin/perl -w
$num1="a";               #### “”是字符
$num2="5";              
$num3= $num1 x $num2;    #### $num1重复$num2次
print "\$num3 is $num3\n";

执行结果:
[root@test-linux tmp]# ./pe.pl
$num3 is aaaaa
[root@test-linux tmp]#
4、Perl中字符串的比较操作和Shell中的数值测试运算相同,Perl中的数值比较操作就和Shell的字符串比较操作相同。
awk 中“=”表示赋值  “==”表示等于关系的判断
 
二、数组---数组是由一组连续的标量
1、Perl 中使用@加上数组名来表示一个数组; Perl 中的数组下标是从“0” 开始;Perl 中的数组元素不必是同一数据类型
2、使用[]申请数组中第几个元素
3、$name @name  %name  分别表示标量 数组 散列
4、push 能够把一些元素添加到数组尾部,而pop函数每次只能取走一个元素(是取走而不是复制)   末理解的“堆栈数据结构”
[root@test-linux tmp]# cat pg.pl
#!/usr/bin/perl -w
@list1=(1..4);
@list2=("zero","one","two","three","four");
push(@list1,@list2);
$last=pop(@list1);
print "\@list1 is @list1\n";
print "\@list2 is @list2\n";
print "\$last  is $last\n";
[root@test-linux tmp]# vi pg.pl
[root@test-linux tmp]# ./pg.pl
@list1 is 1 2 3 4 zero one two three
@list2 is zero one two three four
$last  is four
[root@test-linux tmp]#
5、unshift函数是在数组的头部插入一个或者是一些新的元素;shift 是从数组的头部移走一个元素,整个数组看起来像是向左移动了一个位置。
#!/usr/bin/perl -w
@list1=(0..4);
@list2=("zero","one","two","three","four");
unshift(@list1, @list2);                 ###是将数组list2插入到数组list1
$last=shift(@list1);
print "\@list1 is @list1\n\@list2 is @list2\n\$last is $last\n";

[root@test-linux tmp]# ./ph.pl
@list1 is one two three four 0 1 2 3 4
@list2 is zero one two three four
$last is zero
[root@test-linux tmp]#
6、reverse 函数的功能是颠倒数组,它可以把数组元素的顺序头尾颠倒。
[root@test-linux tmp]# cat pi.pl
#!/usr/bin/perl -w
@list1=(0..4);
print "\@list1 is @list1\n";
@list1=reverse(@list1);
print "\@list1 reverse is @list1\n";

[root@test-linux tmp]# ./pi.pl
@list1 is 0 1 2 3 4
@list1 reverse is 4 3 2 1 0
[root@test-linux tmp]#

7、 哈希
    哈希变量和数组非常类似,都可以存放多个标量,每个标量可以通过索引单独存取。不同的是哈希变量的索引不是数组的下标,而是另一个标量。通常这个标量被称作key,通过key,我们就可以访问
到其对应的数据。另一点的不同是哈希变量中的元素没有先后之分,是无序的,key是能够访问它们的惟一通道。Perl 中使用百分号“%”来表示一个哈希变量。

为以下内容
[root@test-linux tmp]# cat pl.pl
#!/usr/bin/perl -w
$area{'beijing'}=9;
$area{'shanghai'}=8;
print "$area{'beijing'}\n"
%areab=('hebei'=>5, 'handan'=>4);
print "\$areab hebei is $areab{'hebei'}\n";
print "\$areab handan is $areab{'handan'}\n"
[root@test-linux tmp]#
执行错误
[root@test-linux tmp]# ./pl.pl
Unquoted string "areab" may clash with future reserved word at ./pl.pl line 5.
Operator or semicolon missing before %areab at ./pl.pl line 5.
Ambiguous use of % resolved as operator % at ./pl.pl line 5.
Can't modify modulus (%) in scalar assignment at ./pl.pl line 5, near ");"
Execution of ./pl.pl aborted due to compilation errors.

但将2到4行注释掉可以成功执行。原因不清楚

[root@test-linux tmp]# cat pt.pl
#!/usr/bin/perl -w
%area=(1,"a",2,"b");
print "\%area is 1 $area{1}\n";
   2、keys 和values 函数
  
   keys 函数会遍历所有的哈希变量,并把哈希变量的key作为一个数组返回,我们可以通过遍历这个数组来访问哈希变量的所有元素。需要注意,这个数组中的key仍然是无序的。对应的函数就是
values函数,它会把哈希变量保存的所有的值作为一个数组返回。
[root@test-linux tmp]# cat py.pl
#!/usr/bin/perl -w
$name{'bo'}=1;
$name{'hong'}=2;
$name{'quan'}=3;
@keyname=keys(%name);
@valuesname=values(%name);
print "\@keyname is @keyname\n";
print "\@valuesname is @valuesname\n";
print "\%name{\$keyname[0] is %name{$keyname[1]}  \%name{\$valuesname[0] is $valuesname[1]}}\n";
[root@test-linux tmp]#

   3、each函数
   each 函数的功能就是遍历哈希变量中所有的数据并把每一对key =>value 作为一个只有两个元素的数组返回,key在前,value在后。each函数会循环地取出所有的数据,直到所有数据都被取出反返
回false。

[root@test-linux tmp]# cat pu.pl
#!/usr/bin/perl -w
$name{'beijing'}=99;
$name{'shanghai'}=88;
$name{'shenzhen'}=77;
while (@value=each(%name))
{
        print "$value[0] is $value[1]\n";
}
 
[root@test-linux tmp]# ./pu.pl
shenzhen is 77
beijing is 99
shanghai is 88
[root@test-linux tmp]#
 
    4、delete和exists函数
    delete函数的功能就是从哈希变量中删除一个元素,而exists函数的功能则是判断哈希变量中是否存在某一个值。
[root@test-linux tmp]# cat pq.pl
#!/usr/bin/perl -w
$city{'hebei'}= "is sheng";
$city{'hadan'}= "is shish";
$city{'xiang'}= "is xianL";
if (exists ($city{'hebei'}))
{
        delete ($city{'hebei'});
}
while (@value = each(%city))
{
print "$value[0]  => $value[1]\n";
}
 
[root@test-linux tmp]# ./pq.pl
hadan  => is shish
xiang  => is xianL
 
Perl 中的函数和模块
   1、创建函数
    sub 函数名 {
   
    函数体
}
 
三、Perl 中的流程控制语句
 条件选择语句1
     if (条件表达式) {
语句块1;
}  else {
语句块2;
}
 
 条件选择语句2
     unless (判别运算式)
   {
       语句2;
   } else {
       语句1;  
   }
 
  if条件语句嵌套
  if (条件表达式1)
{
语句1
} elsif (条件表达式2) {
语句2
} elsif (条件表达式3) {
语句3
} else {
语句4
}
例:
#!/usr/bin/perl -w
print "input ?\n";
$name= <STDIN>;
chop($name);
if ($name eq "bo")
{
 print "my name is $name\n";
} elsif ($name eq "ji") {
print " my last name is $name\n";
} elsif ($name eq "liu") {
print "my first name is $name\n";
} else {
print "unkonw ------!!!!!!!!!!\n";
}
 
灵活使用perl
   条件表达式 &&  语句块
这的确是个逻辑与操作,若条件表达式为“真”,要根据后面语句块的执行结果才能判断整个逻辑与操作的结果,这样就会执行后面的语句;而当条件表达式为“假”,则整个表达式为“假”,不用考虑
后面语句块的值。所以为假时的语句块不被执行。

   open (FH, " >filename") || die "打开文件出错。";
这时整个表达式的含义是:当前面的语句执行结果是“真”时,就不执行后面的语句了;当前面的语句执行出错,结果是“假”时,就执行后面的语句。这里die的含义是输出出错信息。

if语句的简写
[root@test-linux tmp]# cat ifp.pl
#!/usr/bin/perl -w
$i=1;
#if ($i < 10) {
#
#print "$i < 10\n";
#
#}
print "$i < 10\n" if ( $i < 10);
 
四、for 循环
   for ( 初始语句,条件判断语句,循环变量步进速度) {
  循环体语句
}
[root@test-linux tmp]# cat pfor.pl
#!/usr/bin/perl -w
for ($i=1;$i<10;$i++) {
print "$i\n";
}

    while/until 循环
    while (条件表达式) {
    循环体语句
}
  
[root@test-linux tmp]# cat pwhile.pl
#!/usr/bin/perl -w
$i=1;
while ($i < 10) {
print "$i\n";
$i++;
}
 
当条件表达式为“假”时,执行循环体语句
until (条件表达式) {
    循环体语句
}
#!/usr/bin/perl -w
$i=0;
until  ( $i > 10) {
print "$i\n";
$i++
}
 

do{} while/until 循环
do {

} while/until (条件表达式);
do {} while 的语意是执行循环体,直到条件表达式为“假”;而do{} until的语意是执行循环体,直到表达条件式为“真”。
 
foreach 循环
foreach 标量 (标量)
{
   循环体语句
}
[root@test-linux tmp]# cat foreach.pl
#!/usr/bin/perl -w
@array=(1,2,3,4,5);
foreach $i (@array) {
print "$i\n";
}
#!/usr/bin/perl -w              ####### 有一个默认变量$_
@array=(1,2,3,4,5);
foreach (@array) {
print ;
}

#!/usr/bin/perl -w             
@array=(1,2,3,4,5);
foreach $_ (@array) {
print $_;
}

循环体控制    next和last 等完成。
[root@test-linux tmp]# cat next.pl
#!/usr/bin/perl -w
@array=("a","b","c","d","e","f");
foreach (@array) {
        if ($_ ge "c"){
            last;                     ##跳出循环
        }
        for ($i =1; $i < 7; $i++) {
          if (($i % 2) == 1) {
             next;                    ##进行下一次循环
          }
          print "$_" x "$i";
          print "\n";
        }
}
          print "\nDone!\n";
注:当外层循环变量大于等于“c”时,就跳出外层循环,代码执行完毕:内层循环中,当循环变量是奇数时,就不执行打印操作,而执行下一次循环。这样就是下面的结果。

[root@test-linux tmp]# ./next.pl
aa
aaaa
aaaaaa
bb
bbbb
bbbbbb
Done!

五、Perl 的输入输出   print         printf
[root@test-linux tmp]# ./print.pl
hello         bo, age=     0
[root@test-linux tmp]# cat print.pl
#!/usr/bin/perl -w
$name = "bo";
$age = 0.5;
if ($name)
{
printf ("hello %10s, age= %5d\n", $name, $age);
}
[root@test-linux tmp]#

%来定义一些格式   %d 输入十进制整数     %o 输入八进制整数       %x输入十六进制整数        %u输入无符号十进制整数      %c输入字符串  %s 输入字符串  %e输入实型数(用科学计算法表示)
%f 输入实型数(用小数形式或指数形式)
 
   2. 句柄
  
[root@test-linux tmp]# ./jubing.pl jubing.pl
#!/usr/bin/perl -w
while ($file = <>) {
print "$file";
}
简写
[root@test-linux tmp]# ./jubing.pl jubing.pl
#!/usr/bin/perl -w
while (<>) {                 ##它会从命令参数中获取文件,打开并读取数据。这是一个简写形式,等价于:while ($_ = <>)
print ;                      ##简写,使用了$_作为默认变量
}
  
打开一个文件:open(FH,"filename");
从文件中读取数据:<FH>;
向文件中写入数据:print FH"string";
关闭句柄:close(FH);
[root@test-linux tmp]# ./pyy.pl pyy.pl
#!/usr/bin/perl -w
open (FH, "$ARGV[0]");
while ($_ = <FH>) {
        print STDOUT "$_";
}
close (FH);
 
六、Perl 中应用正则表达式
 
    1、字符串匹配
[root@test-linux tmp]# cat pst.pl
#!/usr/bin/perl -w
while (<>) {
        if (/\/bin\/bash$/) {
           print ;
        }
}

     2、更多的时候,我们可能不能使用默认变量来进行正则表达式的匹配,所以Perl提供了一个专门的运算符“=~”,它专门用来进行正则表达式的匹配。  忽略大小写
#!/usr/bin/perl -w
$str="hello perl world!\n";
if ( $str =~ /perl/i ) {     ###  忽略大小写,匹配$str中是否存在Perl 字符;
   print "$str";
}
 
Perl 中的正则表达式还可以使用变量来动态地改变匹配的模式,如:
     1、字符串匹配
[root@test-linux tmp]# cat p.pl
#!/usr/bin/perl -w
$str="hello Perl program ! \n";
print "you input is:\n";
$input=<STDIN>;
chomp($input);
if ($str =~ /$input/i) {
print "haha, find $str\n";
}
[root@test-linux tmp]# ./p.pl
you input is:
hel
haha, find hello Perl program !
[root@test-linux tmp]#

    2、字符串替换
[root@test-linux tmp]# ./pap.pl
old string is : hello Perl World!
new string is :hello Perl New World!
[root@test-linux tmp]#
[root@test-linux tmp]# cat pap.pl
#!/usr/bin/perl -w
$_="hello Perl World!\n";
print "old string is : $_";
s/Perl/Perl New/g;
print "new string is :$_";

七、 Perl 的函数:split、system                   split的函数是分割的字符串。system函数用来创建一个子进程,它只是一字符串参数,这个函数会把这个字符串作为一个命令来执行。
[root@test-linux tmp]# ./psplit.pl
$a,$b,$c is hello,perl,program
@array is hello perl program
[root@test-linux tmp]#
[root@test-linux tmp]#
[root@test-linux tmp]# cat psplit.pl
#!/usr/bin/perl -w
$str="hello perl program\n";
($a, $b, $c)=split(/ /,$str);                    ## 使用空格做为分割符,分解字符串到标量中
@array=split(/ /, $str);                         ## 使用空格帮为分割符,分解字符串到数组中
print "\$a,\$b,\$c is $a,$b,$c\n";
print "\@array is @array";
[root@test-linux tmp]#
 

system 例子
[root@test-linux tmp]# ./psys.pl
Unquoted string "bo" may clash with future reserved word at ./psys.pl line 3.  ## bo 使用大写就可以了
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda6              33G   12G   20G  38% /
/dev/sda3              19G  3.1G   15G  17% /home
/dev/sda2              19G  5.8G   13G  33% /usr
/dev/sda1             190M   11M  170M   7% /boot
tmpfs                 501M     0  501M   0% /dev/shm
[root@test-linux tmp]# cat psys.pl
#!/usr/bin/perl -w
system("df -lh > df.txt");
open (bo, "df.txt");
while (<bo>) {
       print;
}
[root@test-linux tmp]#
完全正确的
[root@test-linux tmp]# ./psys.pl
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda6              33G   12G   20G  38% /
/dev/sda3              19G  3.1G   15G  17% /home
/dev/sda2              19G  5.8G   13G  33% /usr
/dev/sda1             190M   11M  170M   7% /boot
tmpfs                 501M     0  501M   0% /dev/shm
[root@test-linux tmp]# cat psys.pl
#!/usr/bin/perl -w
system("df -lh > df.txt");
open (FH, "df.txt");
while (<FH>) {
       print;
}
[root@test-linux tmp]#

灵活运用
#!/usr/bin/perl -w
#system("df -lh > df.txt");
open (FH, "/etc/samba/smb.conf");
while (<FH>) {
       print;
}
执行脚本
comment = KuaiLe File Server
path = /opt/switch
security = share
#public = yes
create mask = 0666
directory mask = 0777
#valid users = bo,nobody,aaa
writeable = yes
guest ok = yes
#only user = yes
[root@test-linux tmp]# ./psys.pl
 
监控文件系统:
[root@test-linux tmp]# cat quo.pl
#!/usr/bin/perl -w
system("df -lh > /tmp/df.txt") && system("logger exec command error");    ##这行代码的意思是当system函数执行出错时就执行“&&”后面的代码,否则就不执行。这和我们前面学习到的知识
好像有些不同,这种逻辑过去常常是使用“||”的,而前面我们说过,这行代码的含义是当前面的执行结果为“真”时,执行后面代码的;否则就不执行。关键的区别就是函数执行出错和执行结果为“真
”。我们要特别注意system函数的返回值。当system正常执行时,函数返回值是0;出错时,函数返回值是一个非0值。但是在Perl 中0被认为是“假”,非0值才认为是“真”。所以当我们需要system函
数执行出错时报告错误的异常就要使用“&&”了。
open(FH, "/tmp/df.txt");
while (<FH>) {
        next if (/Use\%/);                                  ##如果文本行中包含Use%就跳过
        next if !(/\%/);
        next if (/^ /);                                     ##如果文本行是以空格开始的就跳过
        s/\%//g;
        @array=split(/ +/,$_);                              ##以一个空格和多个空格为分割字符串
        if ($array[4] > 33) {
        system("logger filesystem over!!!!!!!!");
        }
}
close (FH);
 
八、Perl 中的函数和模块的使用
sub 函数名 {
函数体
}

Perl中允许函数没有参数、没有返回值,而调用函数只需要写上函数名加上括号就可以了。
[root@test-linux tmp]# ./phs.pl
first hs script!!
[root@test-linux tmp]# cat phs.pl
#!/usr/bin/perl -w
sub first_hs() {
        print "first hs script!!\n"
}
first_hs();
[root@test-linux tmp]#

利用参数,函数可以提供更强大的功能 。Perl 中把函数参数自动地保存到数组变量@_中,你可以在函数中通过数组@_来访问函数的参数。调用时,只需要把参数写在函数的括号中即可。
[root@test-linux tmp]# ./pp.pl
main::first_name() called too early to check prototype at ./pp.pl line 2.
hello tom!
[root@test-linux tmp]# cat pp.pl
#!/usr/bin/perl -w
first_name("tom");
sub first_name() {
        my($name)=@_;                    ##把函数参数保存到本地变量
        print "hello $name!\n";          ##
};
[root@test-linux tmp]#
Perl 中的函数默认是全局函数,所以你可以把函数放在代码的任何位置,Perl 都能找到。不过在使用-w选项之后,Perl 仍然会向你提出一个报警:“called too early to check prototype at
./pp.pl line 2.” ,意思是说:你在定义函数之前就调用 了这个函数。
  
     函数是有值的,我们可以在函数体中指定返回的值,如果不明确指定那么函数的值就是最后一体函数语句的值。
[root@test-linux tmp]# cat po.pl
#!/usr/bin/perl -w
print "2+3=".sum(2,3)."\n";
sub sum() {
        my($num1,$num2)=@_;
        return $num1 + $num2;
};
[root@test-linux tmp]#
[root@test-linux tmp]# ./po.pl
main::sum() called too early to check prototype at ./po.pl line 2.
2+3=5
[root@test-linux tmp]#

       默认情况下,Perl 中的变量都是全局的。比如我们在代码的开始时定义一些变量,在函数里仍然可以使用它。方法如下:
[root@test-linux tmp]# ./ppa.pl
main::new_sum() called too early to check prototype at ./ppa.pl line 4.
23
sub's sum is: 43
sub exit 23
[root@test-linux tmp]# cat ppa.pl
#!/usr/bin/perl -w
$sum=23;
print "$sum\n";
new_sum();                  ##调用函数
print "sub exit $sum\n";
sub new_sum() {
        my($sum);           ##定义私有变量,原全局变量被自动保存
        $sum = 43;
        print "sub's sum is: $sum\n";
}
 
模块   使用模块之前,必须在代码中应用它:
    use  模块名;
然后我们就可以使用这个模块中的函数和变量了。Perl 的发行版中包括了大量的成熟模块和相关的使用手册

安装绝大多数的Perl 模块包都使用这4步
perl Makefile.PL
make
make test
make install
 
 
有关写脚本报错:
脚本16以上仔细检查是否缺少“;”
[root@test-linux tmp]# perl bp.pl
syntax error at bp.pl line 16, near "){"
syntax error at bp.pl line 22, near "}"

Execution of bp.pl aborted due to compilation errors.

 

创建系统用户

#!/usr/bin/perl  -w
  $user=$ARGV[0];  
  $passwd=$ARGV[1];  
  print   "user=".$user."\n";  
  print   "password=".$passwd."\n";  
   
  @saltchars   =   (a   ..   z,   A   ..   Z,   0   ..   9);  
    srand(time||$$);  
    $salt   =   $saltchars[rand($#saltchars)]   .
$saltchars[rand($#saltchars)];  
  #print   "$salt\t$row[1]\n";  
  $encrypt_passwd   =   crypt($passwd,$salt);  
  #print   $encrypt_passwd."\n";  
  $add_exec   =   "/usr/sbin/useradd -s /sbin/nologin -p   ".$encrypt_passwd."   ".$user;                                  
   
  #$add_exec   =   "/usr/sbin/useradd   ".$user;  
  print   $add_exec."\n";  
   
  system($add_exec);