<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=305858&amp;view=findpost&amp;p=2726567</guid>
        <pubDate>Thu, 14 Oct 2010 13:00:47 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=305858&amp;view=findpost&amp;p=2726567</link>
        <description><![CDATA[Nadz Goldman: <strong class='tag-b'>Q: Покажите что-нибудь по работе с потоками.</strong><br>
A: Очень понравился простейший пример, опубликованный на <a class='tag-url' href='http://habrahabr.ru/blogs/perl/65592/' target='_blank'>Хабрахабре</a>.<br>
<br>
Вот перепост:<br>
<strong class='tag-b'>Perl и GUI. Работа с потоками</strong><br>
Я затрону весьма наболевшую тему, Perl + GUI + потоки.<br>
Наболевшую, потому что попытка заставить работать ваше приложение с потоками может закончиться неудачей. Программа «виснет», «сегфолитится», Вы обратитесь к документации, увидете там, что библиотека не thread-safe. Потраченное время было коту под хвост?<br>
<br>
Хинт: создать потоки до вызова Tkx::MainLoop, так как MainLoop() запускает свой цикл событий и блокирует выполнение кода. Было бы все так просто&#33; Переписали Вы код с этим условием, а она все равно виснет…<br>
<br>
Что же делать? Выход есть.<br>
Нужно использовать модель Boss/Workers (Начальник и Работники) и очереди сообщений (Queue).<br>
<br>
Цель: написать приложение с GUI и использовать многопоточность.<br>
Давайте, рассмотрим задачу «на пальцах», представим все в виде абстрактной модели.<br>
<br>
Есть склад. Вы приходите к начальнику (boss),<br>
— Привет, соберите мне вот этот списочек…<br>
— Окей, сейчас раскидаю задание по частям, работники (workers) все сделают.<br>
<br>
Кладовщики задания берут из стопки (причем берут по порядку их поступления).<br>
<br>
Подобную очередь реализует пакет Thread::Queue.<br>
<br>
Мы будем использовать несколько методов<br>
— enqueue — положить задание<br>
— dequeue, dequeue_nb — взять задание<br>
<br>
Разница между dequeue и dequeue_nb в том, что последний неблокирующийся.<br>
<br>
Другими словами, когда мы вызываем dequeue, мы ждем пока задание не появится, и только тогда его получаем. А во втором случае, если задания нет — то возвращается undef.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">while( defined( my $item = $queue-&#62;dequeue() ) ) {</div><div class="code_line">&nbsp;&nbsp;# выполняем какие-либо действия.</div><div class="code_line">}</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
<br>
<br>
Кладовщики собрали весь необходимый товар, теперь его заберет грузчик, и Вам принесет.<br>
…<br>
<br>
Теперь приступим к реализации (упрощенный вариант).<br>
<br>
Task -&gt; Tk -&gt; Boss -&gt; Worker -&gt; Result<br>
<br>
<span class="b-attach" data-size="28145" data-hits="1272" data-attach-id="3224" data-attach-post-id="2726567">
			<span class="b-attach__title"></span><a class='b-attach-link' href='https://forum.sources.ru/index.php?act=Attach&amp;type=post&amp;id=2726567&amp;attach_id=3224' title='Скачать файл' target='_blank'>1.png</a> (, : 1272)
		</span><br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#!/usr/bin/perl</div><div class="code_line">use strict;</div><div class="code_line">&nbsp;</div><div class="code_line">use Tkx; # тулкит</div><div class="code_line">&nbsp;</div><div class="code_line">use threads; # работа с потоками</div><div class="code_line">use Thread::Queue; # реализует очередь</div><div class="code_line">&nbsp;</div><div class="code_line"># создаем очереди</div><div class="code_line">my $queue_tk &nbsp; = Thread::Queue-&#62;new(); # получаем задания из Tk</div><div class="code_line">my $queue_job &nbsp;= Thread::Queue-&#62;new(); # отправляем работникам</div><div class="code_line">my $queue_box &nbsp;= Thread::Queue-&#62;new(); # результаты</div><div class="code_line">&nbsp;</div><div class="code_line"># босс</div><div class="code_line">sub thread_boss {</div><div class="code_line">&nbsp;&nbsp; &nbsp;my $self = threads-&#62;self();</div><div class="code_line">&nbsp;&nbsp; &nbsp;my $tid &nbsp;= $self-&#62;tid();</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;while( defined( my $item = $queue_tk-&#62;dequeue() ) ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;print STDERR &quot;Boss($tid) has received the task from Tk: $item\n&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# отправляем задание на обработку работнику</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$queue_job-&#62;enqueue( $item );</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$queue_job-&#62;enqueue( undef );</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line"># работник(и)</div><div class="code_line">sub thread_worker {</div><div class="code_line">&nbsp;&nbsp; &nbsp;my $self = threads-&#62;self();</div><div class="code_line">&nbsp;&nbsp; &nbsp;my $tid &nbsp;= $self-&#62;tid();</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;while( defined( my $job = $queue_job-&#62;dequeue() ) ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;print STDERR &quot;Worker($tid) has received task from Boss: $job\n&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# выполняем какую-нибудь работу...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;print STDERR &quot;Worker($tid) has finished the task\n&quot;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;# скидываем все в одну коробку ;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$queue_box-&#62;enqueue( &quot;processed: $job&quot; );</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;$queue_box-&#62;enqueue( undef ); &nbsp; &nbsp;</div><div class="code_line">}</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line"># создаем потоки</div><div class="code_line">my $boss &nbsp; = threads-&#62;new( \&amp;thread_boss );</div><div class="code_line">my $worker = threads-&#62;new( \&amp;thread_worker );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line"># Создаем UI</div><div class="code_line">my $main_window = Tkx::widget-&#62;new( &#39;.&#39; );</div><div class="code_line">my $frame = $main_window-&#62;new_ttk__frame( -padding =&#62; q/10 10 10 10/ );</div><div class="code_line">$frame-&#62;g_grid();</div><div class="code_line">&nbsp;</div><div class="code_line">my $label = $frame-&#62;new_ttk__label( -text =&#62; &#39;waiting&#39; );</div><div class="code_line">$label-&#62;g_grid( -row =&#62; 0, -column =&#62; 0, -columnspan =&#62; 2 );</div><div class="code_line">&nbsp;</div><div class="code_line"># поле для ввода</div><div class="code_line">my $entry_data = &#39;enter data here&#39;;</div><div class="code_line">my $entry = $frame-&#62;new_ttk__entry( -textvariable =&#62; $entry_data );</div><div class="code_line">&nbsp;</div><div class="code_line">my $button = $frame-&#62;new_ttk__button(</div><div class="code_line">&nbsp;&nbsp; &nbsp;-text =&#62; &#39;Send to Boss&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;-command =&#62; sub {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$queue_tk-&#62;enqueue( $entry_data );</div><div class="code_line">&nbsp;&nbsp; &nbsp;},</div><div class="code_line">);</div><div class="code_line">&nbsp;</div><div class="code_line">$entry-&#62;g_grid( -row =&#62; 1, -column =&#62; 0 );</div><div class="code_line">$button-&#62;g_grid( -row =&#62; 1, -column =&#62; 1 );</div><div class="code_line">&nbsp;</div><div class="code_line"># обработчик события WM_DELETE_WINDOW</div><div class="code_line">sub on_destroy {</div><div class="code_line">&nbsp;&nbsp; &nbsp;my $mw = shift;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# отсылаем очереди undef, что завершит потоки</div><div class="code_line">&nbsp;&nbsp; &nbsp;$queue_tk-&#62;enqueue( undef );</div><div class="code_line">&nbsp;&nbsp; &nbsp;$queue_box-&#62;enqueue( &#39;finish&#39; );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;# Destroy</div><div class="code_line">&nbsp;&nbsp; &nbsp;# или Tkx::destroy( &#39;.&#39; )</div><div class="code_line">&nbsp;&nbsp; &nbsp;$mw-&#62;g_destroy();</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">$main_window-&#62;g_wm_protocol( &#39;WM_DELETE_WINDOW&#39;, [\&amp;on_destroy, $main_window] );</div><div class="code_line">&nbsp;</div><div class="code_line"># обрабатываем результат</div><div class="code_line">sub monitor {</div><div class="code_line">&nbsp;&nbsp; &nbsp;my $status_lbl = shift;</div><div class="code_line">&nbsp;&nbsp; &nbsp;my $result = $queue_box-&#62;dequeue_nb; &nbsp; &nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;if( $result ne &#39;finish&#39; ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if( defined $result ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$label-&#62;configure( -text =&#62; &quot;job completed: &quot;.scalar(localtime));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Tkx::after( 1000, [\&amp;monitor, $label]);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line"># запускаем мониторинг</div><div class="code_line">Tkx::after( 100, [\&amp;monitor, $label] );</div><div class="code_line">&nbsp;</div><div class="code_line"># открепляем потоки</div><div class="code_line"># иначе при завершении программы, у нас будут предупреждения</div><div class="code_line"># Perl exited with active threads:</div><div class="code_line"># &nbsp; &nbsp; &nbsp; &nbsp;2 running and unjoined</div><div class="code_line"># &nbsp; &nbsp; &nbsp; &nbsp;0 finished and unjoined</div><div class="code_line"># &nbsp; &nbsp; &nbsp; &nbsp;0 running and detached</div><div class="code_line">$boss-&#62;detach();</div><div class="code_line">$worker-&#62;detach();</div><div class="code_line">&nbsp;</div><div class="code_line">Tkx::MainLoop();</div></ol></div></div></div></div><br>
]]></description>
        <author>Nadz Goldman</author>
        <category>Perl</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=305858&amp;view=findpost&amp;p=2617406</guid>
        <pubDate>Thu, 10 Jun 2010 10:08:31 +0000</pubDate>
        <title>FAQ</title>
        <link>https://forum.sources.ru/index.php?showtopic=305858&amp;view=findpost&amp;p=2617406</link>
        <description><![CDATA[Nadz Goldman: Аннотация.<br>
<br>
1. Поиск. Всегда пользуйтесь поиском.<br>
2. Материалов по языку Perl, модулям и особенностям работы в той или иной среде очень и очень много в сети.<br>
<br>
<strong class='tag-b'>FAQ.</strong><br>
<br>
<strong class='tag-b'><br>
Q: Перл. Где взять?</strong><br>
A: http://www.perl.com/<br>
<br>
Windows:<br>
http://strawberryperl.com/<br>
http://www.activestate.com/activeperl<br>
<br>
UNIX/Linux: В распространенных системах уже есть в минимальной поставке.<br>
Если не установлен, то ставим из репозитария (UNIX FreeBSD: cd /usr/ports/lang/perl5.8; make; make install clean).<br>
<strong class='tag-b'><br>
Q: Что почитать?</strong><br>
A: http://www.perl.com/pub/q/documentation<br>
http://bookwebmaster.narod.ru/perl.html<br>
<br>
<strong class='tag-b'><br>
Q: Где взять модули/библиотеки?</strong><br>
A: http://search.cpan.org/<br>
<br>
<br>
<strong class='tag-b'><br>
Q: Как подключиться к MySQL?</strong><br>
A: Использовать DBI.<br>
A: Библиотечка и пример:<br>
<br>
<br>
mysql.pm<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">use DBI;</div><div class="code_line">&nbsp;</div><div class="code_line">$sql_user=$ENV{SQL_USER};</div><div class="code_line">$sql_password=$ENV{SQL_PASSWD};</div><div class="code_line">$sql_base=$ENV{SQL_BASE};</div><div class="code_line">$sql_host=$ENV{SQL_HOST};</div><div class="code_line">&nbsp;</div><div class="code_line">if (! $sql_user) { $sql_user=&quot;USERNAME&quot;; }</div><div class="code_line">if (! $sql_password) { $sql_password=&quot;PASSWORD&quot;; }</div><div class="code_line">if (! $sql_base) { $sql_base=&quot;DATABASE_NAME&quot;; }</div><div class="code_line">if (! $sql_host) { $sql_host=&quot;HOST&quot;; }</div><div class="code_line">&nbsp;</div><div class="code_line">if ($debug) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;print &quot;User:$sql_user\nPassword:$sql_password\n&quot;;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">sub connect {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;my($u,$p)=@_;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$sql_user=$u if $u;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$sql_password=$p if $p;</div><div class="code_line">&nbsp;</div><div class="code_line">if ($debug) {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;print &quot;User:$sql_user\nPassword:$sql_password\n&quot;;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$dbh = DBI-&#62;connect(&quot;DBI:mysql:$sql_base;host=$sql_host&quot;, $sql_user, $sql_password);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$dbh-&#62;{RaiseError} = 1;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub disconnect {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;$dbh-&#62;disconnect;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">1;</div></ol></div></div></div></div><br>
 <br>
Пример кода:<br>
sample.pl<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">use DBI;</div><div class="code_line">require &#39;mysql.pm&#39;;</div><div class="code_line">$sth=$dbh-&#62;prepare(&quot;SELECT * FROM SomeTable WHERE SomeData = &#39;test&#39;&quot;);</div><div class="code_line">$sth-&#62;execute || die $DBD::errstr;</div><div class="code_line">&nbsp;</div><div class="code_line">while(($a,$b)=$sth-&#62;fetchrow) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;print $a;</div><div class="code_line">&nbsp;&nbsp;}</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'> <br>
Q: Как отдать HTML?</strong><br>
A: Если не через библиотеки (CGI::WebOut, к примеру), то так:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#!/usr/bin/perl -w</div><div class="code_line">print &quot;Content-type: text/html\n\n&quot;;</div><div class="code_line">print &quot;Some tezt&quot;;</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'><br>
Q: А через CGI:WebOut?</strong><br>
A: Код:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#!/usr/bin/perl -w</div><div class="code_line">use CGI::WebOut;</div><div class="code_line">print &quot;Некоторый текст&quot;;</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'> <br>
Q: А вот дайте пример работы с телнетом?</strong><br>
A: Простой пример.<br>
<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#!/usr/bin/perl</div><div class="code_line">&nbsp;</div><div class="code_line">use Net::Telnet</div><div class="code_line">&nbsp;</div><div class="code_line">$conn = new Net::Telnet (Timeout =&#62; 10,&#39;);</div><div class="code_line">$conn-&#62;open(&quot;some.host.org&quot;);</div><div class="code_line">$conn-&#62;login($username);</div><div class="code_line">$conn-&#62;password($passwd);</div><div class="code_line">@somedata = $conn-&#62;cmd(&quot;do something&quot;);</div><div class="code_line">print @somedata;</div></ol></div></div></div></div><br>
<br>
<br>
A: А вот пример большой и деревянный.<br>
Суть такова: есть количество управляемых свичей, нужно с них собирать конфигурационные файлы.<br>
Берем TFTP сервер, Perl и два модуля (Net::Telnet &amp; File::Copy).<br>
Так же есть файлик hosts.txt<br>
Его вид такой:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">12.23.45.54 dlink</div><div class="code_line">24.21.23.54 dlink_simple</div></ol></div></div></div></div><br>
Суть такова: айпи адрес и... &quot;тип устройства&quot; =)<br>
Файлик обрабатывается подпрограммой parse();<br>
В этой подпрограмме указывается какое содержимое переменной &#036;cmd нужно сказать свичу что бы он отдал конфиг на TFTP.<br>
А&#33; Есть еще момент.<br>
В старой и доброй традиции юниксового TFTPD нужно что бы файлик, который мы передаем на сервер, уже был на этом сервере.<br>
Т.е. подпрограмма tftp_create() как раз и создает такой файлик нулевого размера.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#!/usr/bin/perl</div><div class="code_line">&nbsp;</div><div class="code_line">##########################################</div><div class="code_line">##</div><div class="code_line">## ololo</div><div class="code_line">## (C) Ilya Vasilyev, 2010</div><div class="code_line">## nadz.goldman@gmail.com</div><div class="code_line">##</div><div class="code_line">##########################################</div><div class="code_line">##########################################</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">use Net::Telnet;</div><div class="code_line">use File::Copy;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">$cmd;</div><div class="code_line">$host;</div><div class="code_line">$type;</div><div class="code_line">$conn;</div><div class="code_line">&nbsp;</div><div class="code_line"># айпи тфтп сервера</div><div class="code_line">$tftp_ip = &quot;12.2.2.3&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line"># логин+пароль свича</div><div class="code_line">$username = &quot;bak&quot;;</div><div class="code_line">$passwd = &quot;bak&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line"># директория тфтп-сервера, в которую кидаются/из которой берутся файлы, прилетевшие на тфтп</div><div class="code_line">$tftp_path = &quot;/tftp&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line"># рабочая директория скрипта</div><div class="code_line">$main_path = &quot;/home/bak/ololo&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line"># так у меня выглядит дата</div><div class="code_line">$date = `/bin/date &quot;+%Y-%m-%d&quot;`;</div><div class="code_line">&nbsp;</div><div class="code_line"># это для винды</div><div class="code_line">#$date = `date /T`;</div><div class="code_line">&nbsp;</div><div class="code_line"># так выглядит имя файла конфигурации, прилетевшего со свича</div><div class="code_line">$filename = $host.&quot;-&quot;.$date;</div><div class="code_line">&nbsp;</div><div class="code_line">####################################################################################</div><div class="code_line">&nbsp;</div><div class="code_line"># вызов подпрограммы для распарсивания файла с хостами</div><div class="code_line">parse();</div><div class="code_line">&nbsp;</div><div class="code_line"># выполнение бэкапа</div><div class="code_line">execute();</div><div class="code_line">&nbsp;</div><div class="code_line"># перенос в директорию бэкапа</div><div class="code_line">mov_bak();</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line"># подпрограмма переноса</div><div class="code_line">sub mov_bak()</div><div class="code_line">{</div><div class="code_line"># обрезаем фигню всякую</div><div class="code_line">chomp( $date );</div><div class="code_line">&nbsp;</div><div class="code_line"># создаем директорию на текущую дату для бэкапа</div><div class="code_line">system( &quot;mkdir -p &quot;.$main_path.&quot;/bak/&quot;.$date );</div><div class="code_line"># двигаем туда прилетевшие к нам конфиги</div><div class="code_line">system( &quot;mv &quot;.$tftp_path.&quot;/*_&quot;.$date.&quot; &quot;.$main_path.&quot;/bak/&quot;.$date );</div><div class="code_line"># скидываем в файл список пустых файлов - это те свичи, до которых мы либо не достучались, либо с них ничего не прилетело</div><div class="code_line">system( &quot;find &quot;.$main_path.&quot;/bak/ -empty -exec ls {} \; &#62; &quot;.$main_path.&quot;/NOT_BACKUP.txt &quot; );</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">sub put_conf()</div><div class="code_line">{</div><div class="code_line"># на будущее =))</div><div class="code_line"># here I put new conf to switch</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line"># подпрограмма соединения со свичом по телнету</div><div class="code_line">sub connect_()</div><div class="code_line">{</div><div class="code_line">my $temp;</div><div class="code_line">$temp = length( $host );</div><div class="code_line"># если вдруг переменная $host оказалась пуста, значит какой-то ахтунг произошел и скрипт умирает</div><div class="code_line">if( $temp == 0 ){ die &quot;No ip address ( func::connect_ ) !\n Exiting...\n&quot;; }</div><div class="code_line">&nbsp;</div><div class="code_line"># опции соединения</div><div class="code_line">$conn = new Net::Telnet( Timeout =&#62; 5 , Errmode =&#62; &#39;return&#39; , Dump_Log =&#62; &#39;DUMP.LOG&#39; );</div><div class="code_line">$conn-&#62;open( Host=&#62;$host );</div><div class="code_line">&nbsp;</div><div class="code_line"># допиливаю вывод ошибок</div><div class="code_line">$msg = $conn -&#62; errmsg;</div><div class="code_line">$prev = $conn -&#62; errmsg( @msgs );</div><div class="code_line">foreach $prev( @msgs ){ print &quot;$prev\n&quot;; }</div><div class="code_line">&nbsp;</div><div class="code_line"># создание дампов</div><div class="code_line">$dump = $conn -&#62; dump_log;</div><div class="code_line">$dump = $conn -&#62; dump_log( $dump );</div><div class="code_line">$dump = $conn -&#62; dump_log( $main_path.&#39;/dump/DUMP.LOG&#39; );</div><div class="code_line">&nbsp;</div><div class="code_line"># ожидаем строки UserName/PassWord и дождавшись, скидываем туда логин и пароль</div><div class="code_line"># Можно и вот так: $conn -&#62; waitfor( &#39;/username[: ]*$/i&#39; ); , но эт потом...</div><div class="code_line"># Просто потому что некоторые свичи пишут login или сразу password</div><div class="code_line">$conn -&#62; waitfor( &#39;/ame[: ]*$/&#39; );</div><div class="code_line">$conn -&#62; print( $username );</div><div class="code_line">$conn -&#62; waitfor( &#39;/ord[: ]*$/&#39; );</div><div class="code_line">$conn -&#62; print( $passwd );</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line"># дисконнектимся</div><div class="code_line">sub disconnect()</div><div class="code_line">{</div><div class="code_line">$conn -&#62; print( &quot;logout&quot; );</div><div class="code_line">$conn -&#62; close;</div><div class="code_line">undef( $conn );</div><div class="code_line">copy( $main_path.&#39;/dumps/DUMP.LOG&#39;, $main_path.&#39;/dumps/DUMP.LOG-&#39;.$host );</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line"># собственно здесь мы и забираем конфиг</div><div class="code_line">sub get_conf()</div><div class="code_line">{</div><div class="code_line">my $temp;</div><div class="code_line">$temp = length( $host );</div><div class="code_line"># если вдруг переменная $host оказалась пуста, значит какой-то ахтунг произошел и скрипт умирает</div><div class="code_line">if( $temp == 0 ){ die &quot;No ip address ( func::get_conf ) !\n Exiting...\n&quot;; }</div><div class="code_line">&nbsp;</div><div class="code_line"># создаем файлик в директории тфтп сервера</div><div class="code_line">tftp_create();</div><div class="code_line"># говорим свичу команду на отправку конфига</div><div class="code_line">$conn -&#62; print( $cmd );</div><div class="code_line"># ждем - иногда свичи тупят, если сразу отвалится, то глупости будут</div><div class="code_line">sleep( 15 );</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line"># подпрограмма создания файла в каталоге тфтп</div><div class="code_line">sub tftp_create</div><div class="code_line">{</div><div class="code_line">my $temp;</div><div class="code_line">$temp = length( $host );</div><div class="code_line"># если вдруг переменная $host оказалась пуста, значит какой-то ахтунг произошел и скрипт умирает</div><div class="code_line">if( $temp == 0 ){ die &quot;No ip address ( func::tftp_create ) !\n Exiting...\n&quot;; }</div><div class="code_line"># создаем файл</div><div class="code_line">system( &quot;touch $tftp_path&quot;.&quot;/&quot;.&quot;$filename&quot; );</div><div class="code_line"># устанавливаем права</div><div class="code_line">system( &quot;chmod 0666 $tftp_path&quot;.&quot;/&quot;.&quot;$filename&quot; );</div><div class="code_line"># ждем...</div><div class="code_line">sleep( 2 );</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line"># подпрограмма выполнения</div><div class="code_line">sub execute</div><div class="code_line">{</div><div class="code_line">my $i;</div><div class="code_line">&nbsp;</div><div class="code_line"># ищем файлик со свичами цисок</div><div class="code_line">if( -f $main_path.&quot;/cisco.txt&quot; )</div><div class="code_line">{</div><div class="code_line">open( cs , &quot;&#60; &quot;.$main_path.&quot;/cisco.txt&quot; ) or print &quot;While executing, can not open cisco.txt&quot;;</div><div class="code_line">while( defined( $i = ))</div><div class="code_line">{</div><div class="code_line">print( &quot;Yeeehaaa!!! It is CISCO!! =)) \n\n&quot; );</div><div class="code_line">}</div><div class="code_line">close( cs );</div><div class="code_line">}</div><div class="code_line"># ищем файлик с длинками</div><div class="code_line">if( -f $main_path.&quot;/dlink.txt&quot; )</div><div class="code_line">{</div><div class="code_line">open( dl , &quot;&#60; &quot;.$main_path.&quot;/dlink.txt&quot; ) or print &quot;While executing, can not open dlink.txt&quot;;</div><div class="code_line">while( defined( $i =</div><div class="code_line">&nbsp;</div><div class="code_line">))</div><div class="code_line">{</div><div class="code_line">chomp( $i );</div><div class="code_line">$host = $i;</div><div class="code_line">$filename = $host.&quot;_&quot;.$date;</div><div class="code_line"># ВОТ эта команда будет сказана свичю после соедиенения и атворизации</div><div class="code_line">$cmd = &quot;upload cfg_toTFTP $tftp_ip $filename&quot;;</div><div class="code_line"># для дебага =)</div><div class="code_line">#print( &quot;Host: $host\nfile: $filename cmd: $cmd&quot; );</div><div class="code_line"># соеденились</div><div class="code_line">connect_();</div><div class="code_line"># забрали</div><div class="code_line">get_conf();</div><div class="code_line"># ушли</div><div class="code_line">disconnect();</div><div class="code_line">}</div><div class="code_line">close( dl );</div><div class="code_line">}</div><div class="code_line"># А! Вот эта штука... Потому что длинки разные, то и набор команд у них разный.</div><div class="code_line"># сейчас как раз пилю что бы этой ереси с кучей файлов не было</div><div class="code_line">if( -f $main_path.&quot;/dlink_simple.txt&quot; )</div><div class="code_line">{</div><div class="code_line">open( dl_simple , &quot;&#60; &quot;.$main_path.&quot;/dlink_simple.txt&quot; ) or print &quot;While executing, can not open dlink_simple.txt&quot;;</div><div class="code_line"># upload configuration</div><div class="code_line">while( defined( $i = ))</div><div class="code_line">{</div><div class="code_line">chomp( $i );</div><div class="code_line">$host = $i;</div><div class="code_line">$filename = $host.&quot;_&quot;.$date;</div><div class="code_line">$cmd = &quot;upload configuration $tftp_ip $filename&quot;;</div><div class="code_line">#print( &quot;Host: $host\nfile: $filename cmd: $cmd&quot; );</div><div class="code_line">connect_();</div><div class="code_line">get_conf();</div><div class="code_line">disconnect();</div><div class="code_line">}</div><div class="code_line">close( dl_simple );</div><div class="code_line">}</div><div class="code_line">return();</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line"># подпрограмма парсинга</div><div class="code_line">sub parse</div><div class="code_line">{</div><div class="code_line">my $i;</div><div class="code_line">&nbsp;</div><div class="code_line">open( cs , &quot;+&#62; &quot;.$main_path.&quot;/cisco.txt&quot; ) or print( &quot;Can not open cisco.txt\n&quot; );</div><div class="code_line">open( dl , &quot;+&#62; &quot;.$main_path.&quot;/dlink.txt&quot; ) or print( &quot;Can not open dlink.txt\n&quot; );</div><div class="code_line">open( dl_simple , &quot;+&#62; &quot;.$main_path.&quot;/dlink_simple.txt&quot; ) or print( &quot;Can not open dlink_simple.txt\n&quot; );</div><div class="code_line">open( err_txt , &quot;+&#62; &quot;.$main_path.&quot;/error.txt&quot; ) or print( &quot;Can not open error.txt\n&quot; );</div><div class="code_line">&nbsp;</div><div class="code_line">open( fh , &quot;&#60; &quot;.$main_path.&quot;/hosts.txt&quot; ) or die &quot;Can not open hosts.txt!\n&quot;;</div><div class="code_line">flock( fh , 2 ) or die &quot;Can not flock hosts.txt!\n&quot;;</div><div class="code_line">while( defined( $i = ))</div><div class="code_line">{</div><div class="code_line">( $host, $type ) = split( / /, $i );</div><div class="code_line">if( $type =~ /cisco/i )</div><div class="code_line">{</div><div class="code_line">#print &quot;host = $host ... type = $type&quot;;</div><div class="code_line">print cs &quot;$host\n&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line">}</div><div class="code_line">elsif( $type =~ /^dlink$/i )</div><div class="code_line">{</div><div class="code_line">#print &quot;host = $host ... type = $type&quot;;</div><div class="code_line">print dl &quot;$host\n&quot;;</div><div class="code_line">}</div><div class="code_line">elsif( $type =~ /^dlink_simple$/i )</div><div class="code_line">{</div><div class="code_line">print dl_simple &quot;$host\n&quot;;</div><div class="code_line">}</div><div class="code_line">else</div><div class="code_line">{</div><div class="code_line">print err_txt &quot;$host $type\n&quot;;</div><div class="code_line">}</div><div class="code_line">}</div><div class="code_line">close( fh );</div><div class="code_line">close( cs );</div><div class="code_line">close( dl );</div><div class="code_line">close( err_txt );</div><div class="code_line">close( dl_simple );</div><div class="code_line">return();</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'><br>
Q: Привык программировать на языке Pascal/Object Pascal/C/другое. Никак не могу понять как писать функции в Перле</strong><br>
A: Очень просто.<br>
В Перле нет четкого объявления функции. Есть подпрограммы.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">sub mySomeSub {</div><div class="code_line"># Здесь тело подпрограммы</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'><br>
Q: А как же переменные передать в подпрограмму?&#33;</strong><br>
A: Очень просто.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">sub mySumm {</div><div class="code_line">&nbsp;&nbsp; &nbsp;my ( $someVar1 , $someVar2 ) = @_;</div><div class="code_line">&nbsp;&nbsp; &nbsp;return ( $someVar1 + $someVar2 );</div><div class="code_line">}</div></ol></div></div></div></div><br>
@_  - массив, в котором содержатся аргументы, переданные подпрограмме.<br>
<br>
Количество переданных аргументов посчитать вот так: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$f = scalar( @_ );</div></ol></div></div></div></div><br>
<br>
Соответственно, работать с такой подпрограммой вот так:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$myVar = mySumm( 10, 50 );</div></ol></div></div></div></div><br>
<br>
На выходе получим 60.<br>
<br>
<br>
<strong class='tag-b'><br>
Q: А можно пример TCP-сервера и его клиента?</strong><br>
A: Используя сокеты:<br>
<br>
Клиент:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">use Socket;</div><div class="code_line">&nbsp;</div><div class="code_line">socket(TO_SERVER, PF_INET, SOCK_STREAM, getprotobyname(&#39;tcp&#39;));</div><div class="code_line">&nbsp;</div><div class="code_line">$internet_addr = inet_aton( $remote_host )</div><div class="code_line">&nbsp;&nbsp; &nbsp;or die &quot;Не могу сделать резолв хоста $remote_host в ip: $!\n&quot;;</div><div class="code_line">$paddr = sockaddr_in( $remote_port , $internet_addr );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">connect(TO_SERVER, $paddr)</div><div class="code_line">&nbsp;&nbsp; &nbsp;or die &quot;Не могу соеденится с $remote_host:$remote_port : $!\n&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line"># Организуем работу с сервером.</div><div class="code_line">print TO_SERVER &quot;HALO, SERVER!\n&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line">close(TO_SERVER);</div></ol></div></div></div></div><br>
<br>
<br>
Сервер:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">use Socket;</div><div class="code_line">&nbsp;</div><div class="code_line">socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname(&#39;tcp&#39;));</div><div class="code_line">&nbsp;</div><div class="code_line">setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);</div><div class="code_line">&nbsp;</div><div class="code_line">$my_addr = sockaddr_in($server_port, INADDR_ANY);</div><div class="code_line">bind(SERVER, $my_addr)</div><div class="code_line">&nbsp;&nbsp; &nbsp;or die &quot;Не могу использовать порт $server_port : $!\n&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line">listen(SERVER, SOMAXCONN)</div><div class="code_line">&nbsp;&nbsp; &nbsp;or die &quot;Не могу слушать порт: $server_port : $!\n&quot;;</div><div class="code_line">&nbsp;</div><div class="code_line">while (accept(CLIENT, SERVER)) {</div><div class="code_line">&nbsp;print &quot;Halo, my dear client!\n&quot;;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">close(SERVER);</div></ol></div></div></div></div><br>
<br>
<br>
<strong class='tag-b'>Q: А что у нас с метапрограммированием в Перле?</strong><br>
A: Да все не так просто. Ожидается в 6 версии Перла, но вот в соседнем топике отвечал на этот вопрос, решил и сюда добавить.<br>
Красочный пример. Очень советую поглядеть ссылки из комментариев.<br>
Сам Перл 6 пока что официально не признан, но есть.<br>
Смотреть здесь: http://www.perl6.org/<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#!/usr/bin/env perl6</div><div class="code_line">&nbsp;</div><div class="code_line"># see:</div><div class="code_line"># * http://transfixedbutnotdead.com/2010/01/13/anyone_for_metaprogramming/</div><div class="code_line"># * http://transfixedbutnotdead.com/2010/01/14/anyone-for-perl-6-metaprogramming/</div><div class="code_line"># * http://fingernailsinoatmeal.com/post/292301859/metaprogramming-ruby-vs-javascript</div><div class="code_line">&nbsp;</div><div class="code_line"># below runs on Rakudo (31-Oct-2009).</div><div class="code_line">&nbsp;</div><div class="code_line">use v6;</div><div class="code_line">&nbsp;</div><div class="code_line">class Ninja {</div><div class="code_line">&nbsp;&nbsp; &nbsp;has Str $.name is rw;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">my Ninja $drew .= new( name =&#62; &#39;Drew&#39; );</div><div class="code_line">my Ninja $adam .= new( name =&#62; &#39;Adam&#39; );</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">###########################################################</div><div class="code_line"># Reopen Ninja class (&quot;is also&quot; does the biz)</div><div class="code_line"># and add &#39;battle_cry&#39; method</div><div class="code_line">&nbsp;</div><div class="code_line"># augment class Ninja {}</div><div class="code_line">class Ninja is also {</div><div class="code_line">&nbsp;&nbsp; &nbsp;method battle_cry {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;say $.name ~ &#39; says zing!!!&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">$drew.battle_cry; # =&#62; Drew says zing!!!</div><div class="code_line">$adam.battle_cry; # =&#62; Adam says zing!!!</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">###########################################################</div><div class="code_line"># add &#39;throw_star&#39; method to $drew object by creating</div><div class="code_line"># and applying (&quot;does&quot;) role to it (Singleton method)</div><div class="code_line">&nbsp;</div><div class="code_line">role ThrowStar {</div><div class="code_line">&nbsp;&nbsp; &nbsp;method throw_star { say &quot;throwing star&quot; }</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">$drew does ThrowStar;</div><div class="code_line">$drew.throw_star; # =&#62; throwing a star</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">###########################################################</div><div class="code_line"># call method dynamically</div><div class="code_line">&nbsp;</div><div class="code_line">$drew.&#39;battle_cry&#39;; # =&#62; Drew says zing!!!</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">###########################################################</div><div class="code_line"># add &quot;colour&quot; method closing over $colour_name (ie. closure):</div><div class="code_line">&nbsp;</div><div class="code_line">my $colour_name = &#39;black&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">class Ninja is also {</div><div class="code_line">&nbsp;&nbsp; &nbsp;method colour { say &quot;{$.name}&#39;s colour is $colour_name&quot; }</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">$drew.colour; # =&#62; Drew&#39;s colour is black</div><div class="code_line">$adam.colour; # =&#62; Adam&#39;s colour is black</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">###########################################################</div><div class="code_line">&nbsp;</div><div class="code_line"># &quot;defining a method dynamically on an instance that closes</div><div class="code_line"># over local scope and accesses the instance’s state&quot;</div><div class="code_line">#</div><div class="code_line"># Opps - Class method slipped in while working it out.</div><div class="code_line"># $drew.^add_method() does a singleton method.. nice!</div><div class="code_line">&nbsp;</div><div class="code_line">my $sword_symbol = &#39;********&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">$drew.^add_method( &#39;swing&#39;, method ( Str $sound_effect ) {</div><div class="code_line">&nbsp;&nbsp; &nbsp;say &quot;$.name: $sword_symbol $sound_effect&quot;;</div><div class="code_line">} );</div><div class="code_line">&nbsp;</div><div class="code_line">$drew.swing( &#39;slash!!&#39; );</div></ol></div></div></div></div><br>
<br>
<span class='tag-size' data-value='6' style='font-size:6pt;'><br>
А вообще это нафиг никому не надо. Ни было, ни есть.</span>]]></description>
        <author>Nadz Goldman</author>
        <category>Perl</category>
      </item>
	
      </channel>
      </rss>
	