perl 读书手记
perl 创建系统用户 一、标量1、perl 有三种变量:标量、数组、哈希2、字符相加不是用“+”号,而是用“.” 3、 #!/usr/bin/perl -w$num1="a"; #### “”是字符
$num2="5";
$num3= $num1 x $num2; #### $num1重复$num2次
print "\$num3 is $num3\n";
执行结果:
# ./pe.pl
$num3 is aaaaa
#
4、Perl中字符串的比较操作和Shell中的数值测试运算相同,Perl中的数值比较操作就和Shell的字符串比较操作相同。awk 中“=”表示赋值“==”表示等于关系的判断 二、数组---数组是由一组连续的标量 1、Perl 中使用@加上数组名来表示一个数组; Perl 中的数组下标是从“0” 开始;Perl 中的数组元素不必是同一数据类型
2、使用[]申请数组中第几个元素3、$name @name%name分别表示标量 数组 散列4、push 能够把一些元素添加到数组尾部,而pop函数每次只能取走一个元素(是取走而不是复制) 末理解的“堆栈数据结构” # 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 "\$lastis $last\n";
# vi pg.pl # ./pg.pl
@list1 is 1 2 3 4 zero one two three
@list2 is zero one two three four
$lastis four
#
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";
# ./ph.pl
@list1 is one two three four 0 1 2 3 4
@list2 is zero one two three four
$last is zero
#
6、reverse 函数的功能是颠倒数组,它可以把数组元素的顺序头尾颠倒。# cat pi.pl #!/usr/bin/perl -w
@list1=(0..4);
print "\@list1 is @list1\n";
@list1=reverse(@list1);
print "\@list1 reverse is @list1\n";
# ./pi.pl
@list1 is 0 1 2 3 4
@list1 reverse is 4 3 2 1 0
#
7、 哈希
哈希变量和数组非常类似,都可以存放多个标量,每个标量可以通过索引单独存取。不同的是哈希变量的索引不是数组的下标,而是另一个标量。通常这个标量被称作key,通过key,我们就可以访问
到其对应的数据。另一点的不同是哈希变量中的元素没有先后之分,是无序的,key是能够访问它们的惟一通道。Perl 中使用百分号“%”来表示一个哈希变量。
为以下内容
# 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"
#
执行错误 # ./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行注释掉可以成功执行。原因不清楚
# 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函数,它会把哈希变量保存的所有的值作为一个数组返回。# 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 is %name{$keyname}\%name{\$valuesname is $valuesname}}\n";
#
3、each函数
each 函数的功能就是遍历哈希变量中所有的数据并把每一对key =>value 作为一个只有两个元素的数组返回,key在前,value在后。each函数会循环地取出所有的数据,直到所有数据都被取出反返回false。 # cat pu.pl
#!/usr/bin/perl -w
$name{'beijing'}=99;
$name{'shanghai'}=88;
$name{'shenzhen'}=77;
while (@value=each(%name)) {
print "$value is $value\n";} # ./pu.pl shenzhen is 77
beijing is 99
shanghai is 88
#
4、delete和exists函数 delete函数的功能就是从哈希变量中删除一个元素,而exists函数的功能则是判断哈希变量中是否存在某一个值。 # 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=> $value\n";} # ./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= ;
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语句的简写
# 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 ( 初始语句,条件判断语句,循环变量步进速度) {循环体语句}# cat pfor.pl #!/usr/bin/perl -w
for ($i=1;$i 10) {
print "$i\n"; $i++
}
do{} while/until 循环
do { } while/until (条件表达式);
do {} while 的语意是执行循环体,直到条件表达式为“假”;而do{} until的语意是执行循环体,直到表达条件式为“真”。
foreach 循环foreach 标量 (标量) {
循环体语句}# 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 等完成。
# 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”时,就跳出外层循环,代码执行完毕:内层循环中,当循环变量是奇数时,就不执行打印操作,而执行下一次循环。这样就是下面的结果。
# ./next.pl
aa
aaaa
aaaaaa
bb
bbbb
bbbbbb
Done! 五、Perl 的输入输出 print printf
# ./print.pl hello bo, age= 0
# cat print.pl
#!/usr/bin/perl -w
$name = "bo";
$age = 0.5;
if ($name)
{
printf ("hello %10s, age= %5d\n", $name, $age);
}
#
%来定义一些格式 %d 输入十进制整数 %o 输入八进制整数 %x输入十六进制整数 %u输入无符号十进制整数 %c输入字符串%s 输入字符串%e输入实型数(用科学计算法表示)
%f 输入实型数(用小数形式或指数形式) 2. 句柄 # ./jubing.pl jubing.pl
#!/usr/bin/perl -w
while ($file = ) {
print "$file";}简写 # ./jubing.pl jubing.pl
#!/usr/bin/perl -w
while () { ##它会从命令参数中获取文件,打开并读取数据。这是一个简写形式,等价于:while ($_ = )
print ; ##简写,使用了$_作为默认变量} 打开一个文件:open(FH,"filename");
从文件中读取数据:;向文件中写入数据:print FH"string";关闭句柄:close(FH);# ./pyy.pl pyy.pl #!/usr/bin/perl -w
open (FH, "$ARGV");
while ($_ = ) {
print STDOUT "$_";} close (FH);
六、Perl 中应用正则表达式 1、字符串匹配
# 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、字符串匹配# cat p.pl #!/usr/bin/perl -w
$str="hello Perl program ! \n";
print "you input is:\n";
$input=;
chomp($input);
if ($str =~ /$input/i) {
print "haha, find $str\n";}# ./p.pl you input is:
hel
haha, find hello Perl program !
# 2、字符串替换
# ./pap.pl
old string is : hello Perl World!
new string is :hello Perl New World!
#
# 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函数用来创建一个子进程,它只是一字符串参数,这个函数会把这个字符串作为一个命令来执行。
# ./psplit.pl $a,$b,$c is hello,perl,program
@array is hello perl program #
#
# 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";
#
system 例子
# ./psys.pl
Unquoted string "bo" may clash with future reserved word at ./psys.pl line 3.## bo 使用大写就可以了
Filesystem > /dev/sda6 33G 12G 20G38% /
/dev/sda3 19G3.1G 15G17% /home
/dev/sda2 19G5.8G 13G33% /usr
/dev/sda1 190M 11M170M 7% /boot
tmpfs 501M 0501M 0% /dev/shm
# cat psys.pl
#!/usr/bin/perl -w
system("df -lh > df.txt");
open (bo, "df.txt");
while () { print;} #
完全正确的 # ./psys.pl
Filesystem > /dev/sda6 33G 12G 20G38% /
/dev/sda3 19G3.1G 15G17% /home
/dev/sda2 19G5.8G 13G33% /usr
/dev/sda1 190M 11M170M 7% /boot
tmpfs 501M 0501M 0% /dev/shm
# cat psys.pl
#!/usr/bin/perl -w
system("df -lh > df.txt");
open (FH, "df.txt");
while () { print;} #
灵活运用
#!/usr/bin/perl -w
#system("df -lh > df.txt");
open (FH, "/etc/samba/smb.conf");
while () { 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
# ./psys.pl
监控文件系统:# 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 () { next if (/Use\%/); ##如果文本行中包含Use%就跳过
next if !(/\%/);
next if (/^ /); ##如果文本行是以空格开始的就跳过
s/\%//g;
@array=split(/ +/,$_); ##以一个空格和多个空格为分割字符串 if ($array > 33) {
system("logger filesystem over!!!!!!!!"); }} close (FH);
八、Perl 中的函数和模块的使用sub 函数名 {函数体} Perl中允许函数没有参数、没有返回值,而调用函数只需要写上函数名加上括号就可以了。
# ./phs.pl first hs script!!
# cat phs.pl #!/usr/bin/perl -w
sub first_hs() {
print "first hs script!!\n"} first_hs();
#
利用参数,函数可以提供更强大的功能 。Perl 中把函数参数自动地保存到数组变量@_中,你可以在函数中通过数组@_来访问函数的参数。调用时,只需要把参数写在函数的括号中即可。
# ./pp.pl main::first_name() called too early to check prototype at ./pp.pl line 2.
hello tom!
# cat pp.pl
#!/usr/bin/perl -w
first_name("tom");
sub first_name() { my($name)=@_; ##把函数参数保存到本地变量 print "hello $name!\n"; ##
};
#
Perl 中的函数默认是全局函数,所以你可以把函数放在代码的任何位置,Perl 都能找到。不过在使用-w选项之后,Perl 仍然会向你提出一个报警:“called too early to check prototype at ./pp.pl line 2.” ,意思是说:你在定义函数之前就调用 了这个函数。 函数是有值的,我们可以在函数体中指定返回的值,如果不明确指定那么函数的值就是最后一体函数语句的值。
# cat po.pl #!/usr/bin/perl -w
print "2+3=".sum(2,3)."\n";
sub sum() { my($num1,$num2)=@_; return $num1 + $num2;
};# # ./po.pl
main::sum() called too early to check prototype at ./po.pl line 2.
2+3=5
#
默认情况下,Perl 中的变量都是全局的。比如我们在代码的开始时定义一些变量,在函数里仍然可以使用它。方法如下:
# ./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
# 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以上仔细检查是否缺少“;”# 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;
$passwd=$ARGV;
print "user=".$user."\n";
print "password=".$passwd."\n";
@saltchars = (a .. z, A .. Z, 0 .. 9);
srand(time||$$);
$salt = $saltchars .
$saltchars;
#print "$salt\t$row\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);
页:
[1]