Настольная книга компьютерного исследователя


програмирование на perl-е

perl — очень полезный язык любому нормальному хакеру, желающему автоматизировать какие-то функции. полезен он и админу. отсюда вывод — учить надо. perl расшифровывается как practical extraction and report language. если ты когда-нибудь смотрел на перловый код, то мог увидеть, что по синтаксису это что-то в духе С, а по стилю — shell script. вот и получается такой удобный гибрид. perl не может компилировать — это «интерпритационный» язык. интерпретаторы перла переведены на практически все извесные мне платформы (даешь perl для amiga!!;).

ч.1. ‘hello world’
——————
чтобы показать, насколько прост этот язык, напишем программу, выводящую hello world (интересно, а на скольких языках мы ее уже писали? :):

#!/usr/bin/perl
print «hello world\n»;

первая строчка — указание пути к интерпретатору. теперь просто делаем chmod +x hello.pl и вперед. это все сильно вам напомнило shell scripting? так и должно быть. так perl и был задуман — как альтернатива стандартным shell скриптам. чтобы найти, где у тебя лежит интерпретатор perl-а, напиши ‘which perl’ и вста- вь этот путь.

ч.2 переменные, структуры
————————-
в отличии от основной массы программинговых языков в perl-е нету никаких типов данных. вместо этого есть несколько типов переменных. первый тип — скаляры. они обозначаются как $имя_переменной и могут содержать либо числа, либо текст. есть кстати достаточно большое количество специальных переменных, которые отвечают за какие-то перловские функции (например $_ — переменная ввода, $< — UID, $$ — PID). есть еще в перле массивы, обозначаются они @имя_массива. мы можем исполь- зовать массив целиком, а можем обращаться к каким-либо его частям через индекс. $name[2] выдаст нам третий элемент массива @name. есть еще такая чрезвычайно интересная фишка, как ассоциированный массив. этот массив обозначается %ass, а чтобы обратится к его элементу нам не нужен номер — нам нужен «ключ», «ассоциация», к которой привязано значение. например $gods{bad} выдаст нам переменную, завязанную на ключ bad. вот как показать все элементы в ассоциированном массиве с ключами:

 foreach $key (keys %assoc){
      print "$key = $assoc{$key}\n"};

ч.3 условия
————
синтаксис стандартной операции ветвения таков:

 if (условие) {
      комманды
      }
 elseif (условие) {
      комманды
      }
 else {
      комманды
      }

в качестве условия может служить как какое-нить сравнение, так и любая комманда с результатом true/false. true может выражатся как любая цифра, неравная 0, лю- бая не пустая строка, любая булевая операция с выходом true. вот простой пример того, как исп

ользовать условия:

 if ($music eq "RUKI VVERH") {
       print "Fuck this dumb shit\n"
      }
 elseif ($music eq "BURZUM") {
       print "Yea, dude, you rule\n";
      }
 else {
      print "Your favorite grewp is $music.\n"
      }

ч.4 циклы
———
в перле есть 4 конструкции — for, while, foreach и until. конструкция for очевидно позаимствована из C — синтаксис похож :) :

for (начальное условие; конечное условие; функция прироста) {
комманды
}

в начале цикла устанавливается начальное условие, затем цикл выполняется до тех пор, пока функция прироста не даст конечное условие. примерно так:

 for ($l=1; $l<=10; $l++) {
       $m = 10 -$l
       print "$m lives left\n"
       }

foreach ненамного сложнее. это как бы цикл, в котором функция прироста дает по- зицию в массиве и передает ее аргументу. цикл продолжается до тех пор, пока все значения массива не исчерпаны. выглядит это так:

 foreach $dude (@dudes) {
      print "$dude\n"
      }

т.е. тут в $dude по-порядку пишутся элементы из @dudes. while — старый добрый паскалевский цикл. пока условие выполняется — выполняется и цикл:

 while ($assholes<10) {
      print "$assholes are produced by asshole plant ;>\n";
      $assholes++;
      }

цикл until — прямая противоположность циклу while, выполняется, пока условие не справедливо:

 until ($assholes>10) {
      print "$assholes are in production\n";
      $assholes++;
      }

ч.5 функции над переменными
—————————
сионистам (программерам на С) эти функции уже наверняка знакомы, ведь в С они точно так же часто используются. но в перле этих фунцкий больше, а сами фунцкии жутко навороченные :)) вот например:

$string =- s/h4ck3r/lamer/gi;

эта простенькая строчка сменит все появления слова h4ck3r на слово lamer. а теперь мы рассмотрим подробнее каждый элемент этой строчки

$string =- строчка обработки для regex (regular expressions, та самая библиоте- ка с всеми этими фунцкиями)
s комманда замены
/ начала текста для поиска
h4ck3r текст для поиска
/ канэц тэкста дла поиска :))))) и начало текста для замены
lamer текст для замены
/ канэц текста для замены
g заменять везде в строчке (сколько угодно раз и где угодно)
i case sensitive — большие/маленькие буквы имеют большое значение

ч.6 взаимодействие с системой
——————————
одним из крупных преимуществ перла является как раз удобные и гибкие возможности взаимодействия с операционной системой. все обращения к оболочке можно вбит ь прямо в переменную, просто прописав в значении вместо скобок «» обратные оди- ночные «. и вот что мы можем получить:

 $curr_dir = `pwd`;
 @listing = `ls -la`;
 print "Listing for $curr_dir\n";
 foreach $file (@listing) {
      print "$file";
      }

красиво? :) и удобно.

ч.7 автоматизация при помощи perl-а
————————————
увидев, насколько могуч perl при работе с файлами, оболочкой и текстом нетрудно догадаться, что perl удобно использовать для автоматизации разнообразных за- дач. я выложил в разделе файло несколько программ, написаных на перле, которые у меня крутятся каждый божий день. несколько наиболее простых примеров приведу прямо тут. вот простой пример программы, работавшей на j00nix-ftp в течении по- лутора лет (кто знает, что это такое, подтвердит :). программа перепимывала оп- ределенный файл из uploads в private и сообщала пользователю, для которого все это затевалось. при этом она ставила права так, что файл можно было скачать, но нельзя было увидеть в списке по ls. т.е. если знать о том, что файл есть — то его можно было скачать. а программа, увидев новые файлы и перенеся их сообщала по мыло администратору и всем пользователям.

 #!/usr/bin/perl
 #
 # Move a file from /uploads to /private
 $file = @ARGV[0];
 $user = @ARGV[1];

 if ($user eq "") {&usage}
 else {
      if (-e "/home/ftp/uploads/$file")
           {`cp /home/ftp/uploads/$file /home/ftp/private/$file`;
           chmod 0644, "/home/ftp/private/$file";
           `rm -f /home/ftp/uploads/$file`;
           if (uc($file) ne $file) {
                $ucfile = uc($file);
                `ln /home/ftp/private/$file /home/ftp/private/$ucfile`;
               }
           if (lc($file) ne $file) {
                 $lcfile = lc($file);
                 `ln /home/ftp/private/$file /home/ftp/private/$lcfile`;
                }

 # Send mail
 open (MAIL, "| /usr/sbin/sendmail -t ftpadmin,$user");
 print MAIL <<EndMail;
 To: ftpadmin,$user
 From: ftpadmin
 Subject: File ($file) moved

 The file $file has been moved
 The file is now available as
 ftp://ftp.j00nix.not.anymore/private/$file

 ftpadmin\@j00nix.not.anymore
 ================================
 EndMail
 close MAIL;
 }

     else { # File does not exist
          print "File does not exist!\n";
          }   # End else (-e $file)

 } # End else ($user eq "")

 sub usage {
 print "move <filename> <username>\n";
 print "where <username> is the user that you are moving this for.\n\n";
 }

расскажу о нескольких вещах, использованых в коде, но не рассказаных раньше. я думаю, что с параметрами коммандной строчки все понятно. в if параметр -e перед именем файла проверяет его существование. значок << позволяет писать без синтаксиса perl-а прямым текстом, пока не встретится параметр, стоящий после <<. в данном случае это было использовано с << EndMail.

приведу еще одну полезную программу — кастратор логов. она просто удаляет заданное слово со всей строчкой из файла. так чистятся логи…

 #!/usr/bin/perl
 #
 #       Be careful using this program!!
 #       This will remove all lines that contain the given word
 #
 #       Usage:  remove <word> <file>
 ###########
 [email protected][0];
 [email protected][1];

 unless ($file)  {
 print "Usage:  remove <word> <file>\n"; }

 else    {
 open (FILE, "$file");
 @lines=<FILE>;
 close FILE;

 # remove the offending lines
 @lines = grep (!/$word/, @lines);

 #  Write it back
 open (NEWFILE, ">$file");
 for (@lines)    { print NEWFILE }
 close NEWFILE;
         }  #  End else

вот собственно и все, что я хотел рассказать. эта статья не претендует на полность или качественность, она просто должна помочь необразованному (в perl-овом плане) человеку. если после прочтения этой статьи не возникло никаких вопросов, значит вам не стоит заниматься этим языком. если вопросы есть — RTFM!!!



©2013 Журнал Хакера Entries (RSS) and Comments (RSS)