Ян. 302009
 

Реших да понауча малко Perl. Всички го хвалят, че бил супер гъвкав език. Аз, обаче, не съм програмирал от години (ако не броим по някоя друга процедурка на PL/SQL тук-там). Оказа се, че програмирането като работа не се забравя, но сблъсъка с нов език ме изненада.

Както и да е. Предисторията е следната: тази седмица трябваше да инсталираме един тестов Oracle 10.2 на Linux и в знак на оптимизъм избрах Oracle Unbreakable Linux 4 Update 2 x86_64, защото от Oracle 10.2 на RHEL 5 имам лоши спомени. Интересното тук е архитектурата. Не знам RHEL4 дали се държи по същия начин, но се сблъскахме с един много тъп проблем. Преди инсталацията на Oracle DB, когато слагах всички необходими пакети, rpm започна да се държи странно – обясняваше ми, че един пакет го няма, а rpm -q показваше, че го има. Оказа се, че инсталатора е сложил i386 версията, а на мен ми трябва x86_64 версията. И двете си стоят мирно на инсталационното CD, но инсталера по най-тъпия начин е избрал 32 битовата.

Това го преборихме. Но то ме вдъхнови за първата, може би не много смислена, но ПЪРВА за мен програмка на perl. Реших да изнамеря всички пакети, които са инсталирани, но не и в x86_64 вариант.

Почнах наистина а началото, но с много оптимизъм. Примерно, за да взема името на всеки пакет реших най-оптимистично да се боря с regular exressions – това само по себе си е едно дълбоко море. Започнах така:

#!/usr/bin/env perl

use strict;
use warnings;

#my $s = "world";
#print "Hello, $s\n";
my $pn;
my @in=`rpm -qa`;
chomp @in;

foreach (@in) {
  $pn = $_;
  if ($pn =~ /((\w|-)+)-(\d+[-\.]+[-\w\.]*)/) {
        print "For $pn";
        print ", name is $1";
        print " and version is $3\n";
...

Този regexp сам по себе си е голямо заклинание, обаче колкото и да се мъча, не можах да хвана всички случаи. Най-брадатия пакет се оказа java-1.4.2-gcj-compat-1.4.2.0-27jpp – просто няма (или аз не мога да направя) regexp, който да се справи с отделянето на името от версията. Странното е, че като го погледна и ми става ясно коя част е име и коя – версия; но не мога да формулирам точния алгоритъм, поне в тази нова за мен среда. Като стана дума за среда, използвам просто vim, за по-трудно.

Както и да е. Пробите и грешките бяха много. Пешо помага, Xerxes също удари едно рамо в момент, в който бях забил по много тъп начин. И на края успях да стигна до Първата Работеща Програма на Perl (ПРПП), която съм писал лично аз:

#!/usr/bin/env perl

use strict;
use warnings;

my $Str64 = "x86_64";

sub GetArch {
# This procedure checks if some package's architecture is $Str64
# If thеre is more than one package with the same name
# (and different architectures), it will return $Str64
# If there is no package installation with #Str64 architecture
# it will return the first architecture occured

  # get package name from the parameters
  my $PckName = shift;
  # get installed architectures for the package
  my @PckArchs = `rpm --query --queryformat \"%{ARCH}\n\" $PckName`;
  # init $Result with the first architecture found
  my $Result = $PckArchs[0];
  my $CurrArch;

  # lop through architectures
  foreach (@PckArchs) {
      chomp;
      $CurrArch = $_;
      # Check if the architecture is what we are looking for
      if ($CurrArch eq $Str64)  {
          # Victory!
          $Result = $CurrArch;
          }
      }
  return $Result;
}

my $pn;
# we take all package names
my @in=`rpm -qa --queryformat \"%{NAME}\n\"`;
#sort the package names (will look better)
@in = sort(@in);
# remove the new line character
chomp @in;
my $pa;
my $PckCount = 0;

#loop through the package names
foreach (@in) {
    # take thе current package name
    $pn = $_;
    # get package's architecture
    $pa = GetArch($pn);
    chomp($pa);
    #check if the architecture is fine 
    #(and if thе package has architecture at all)
    if (($pa ne $Str64 ) && ($pa ne "noarch")) {
        # this package is not fine, let's report it
        print "$pn is $pa\n";
        $PckCount++;
    }
}
print "Number of bad packages: $PckCount\n";

Може би може да се направи много по-елегантно, но за ПРПП и това е ОК 🙂

P.S. оказа се че има инсталирани цели 41 такива пакета.

P.P.S. Highlight Source Pro плъгина на WordPress, който си сложих днес, не се справя много блестящо с обратните кавички (`)

P.P.P.S. Оправих си Highlight Source Pro. Във файла wp-content\plugins\highlight-source-pro\geshi\geshi\perl.php на ред 63 вместо
'QUOTEMARKS' => array('"'),
написах
'QUOTEMARKS' => array('"','`'),

 Posted by at 15:58

  6 Responses to “Нови територии”

  1. [root@localhost ~]# time ./proba.pl | wc -l
    42
    
    real    0m23.120s
    user    0m13.018s
    sys     0m10.044s
    [root@localhost ~]# time rpm -qa --queryformat "%{ARCH} %{NAME}\n" \
    | sort -k 2 | uniq -f 1 -c | grep -v x86_64 \
    | grep -v noarch | grep [[:space:]]1 | awk '{ print $3 " is " $2 }' | wc -l
    41
    
    real    0m0.731s
    user    0m0.607s
    sys     0m0.122s
    [root@localhost ~]#
    

    🙂

    (output-a от perl скрипта е с един ред повече заради реда с бройката на пакетите)

  2. Предлагам ти да не продължаваш с Perl защото ще те боли много главата. Ако ще правиш някакви скриптове за Линукс по-добре хвърли едно око на bash. За по-сложни неща винаги може да се ползва Java или C#.

  3. Подкрепям колегата 2. Тоя език е толкова неперспективен, че няма накъде. И понеже сигурно ще се появи някой perl специалист, ще кажа че съм писал на тоя език дооооста.

  4. Perl е създаден 1987 г. специално за текстообработка и създаване на справки в това му предназначение е незаменим. Докато има текстообработка ще има и perl. C# може и да е добър незнам /не сам писал на c#/ нека го видим след 21 години дали някой ще го помни 🙂

  5. @TheWarrior – както писах, това е само упражнение да видя що е то perl. Но наистина се възхищавам на bash заклинанието, което си написал. Ако се постарая малко, ще се доближа до твоето време за изпълнение.
    @Ventsi – да, Java и C# може да правят повече неща. Ама я напиши една Java или C# програмка на vim? 🙂
    @asdasd – Какво става с твоя приятел hkjhkjh? 😉

  6. Аз съм фен на Perl но не мога да не отбележа, че Perl и Java/C# (последното да се чете Microsoft-ска Java) са езици от различни поколения, и следователно имат различни цели. Някой определени неща се програмират по лесно (особено при повече код) на Java/C#, други на Perl. Двете са несравними. Java и производни (като C#) имаха строго определена цел, която ги прави ценни за фирмите специализирани в продажбата и създаването на custom code. Това е високата степен на преизползване на код, поради гаранциите, които се добавят от Framework и виртуална машина.
    Perl е по-скоро като Python – мощен интерпретируем програмен език от трето поколение, който обаче няма екстра гаранции от виртуални машини. Това означава, че е по-бърз, по-контролируем, по-лек за интерация с операционната система и нейни елементи или приложения (следователно по-удобен за системно или поне близко до системното програмиране), но същевременно има по-малка преносимост на кода (въпреки че това е спорно), по труден за програмиране в екип или правене на много големи кодове, и следователно с относително по-малко ниво на преизползване на код (и следователно по-висока цена за създаване на единица ред), което автоматично го прави неизгоден при определени приложения.
    Аз съм относително ангостичен към програмните езици, среди и операционни системи. Вендъж броях че съм програмирал на над 50 среди (от embedded до супер компютри) и над 100 програмни езика. Но поради естеството на работата ми, Perl определено е най-предпочитаният ми език, защото предоставя най-бързо решение на много проблеми, които аз срещам ежедневно.
    За пример – изваждане на всички потребителски имена от /etc/passwd файл в Unix/Linux отнема следният програмен ред (и ред в bash):
    perl -ne ‘m/^([^\:]+)/ and print $1’ /etc/passwd
    За език от друго поколение (например Java/C#) за същата цел (приемайки че въобще е възможно да бъде изпълнена, нарушавайки някой от Security моделите на виртуалната машина) трябва значително повече код и стъпка от компилации отделно стартиране с параметри.
    Perl има уникална мощност в това, за което е създаден, по не особено повторим начин. Например Perl като истински интерпретируем език (за разлика от посочените други) има eval statement (който също се компилира по скрит начин в P код и се Jit-ва). Има възможност да си зареди библиотеките „on demand“ по мрежата, ако ги няма инсталирани (изцяло с код в програмата, без нищо необходимо отвън – само един ред) и други финни екстри. CPAN repository-то създава известна (макар и непълна) преносимост на библиотеките, включително с dependancies и прекарване през test cases, нещо което аз лично не съм виждал интегрирано по толкова естествен начин в нито един друг програмен език, пък камо ли от това поколение.
    Изцяло си зависи какво правите, кой програмен език е най-добър. Но това често е поставяне на каруцата пред коня. Всеки програмен език е добър (дори shell, на който аз лично съм писал web сървър) ако вие можете да създадете продукт на него.

Sorry, the comment form is closed at this time.