Задать вопрос
  • Нужна помощь с perl. Как правильно сделать?

    Можно так:

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    use POSIX qw/strftime/;
    
    my $src_dir = $ARGV[0];
    my $dst_dir = $ARGV[1];
    
    my $yesterday = strftime("%Y-%m-%d", localtime(time-86400));
    
    my @src_files = split /\s+/, `ls $src_dir`;
    
    for my $sf (@src_files){
        my $df = "$dst_dir/$sf-$yesterday";
        if ( ! -f $df  ){
            print "$df\n";
        }
    }


    Вызывать так:
    check_backup.pl /tmp/src_dir /tmp/dst_dir

    Если высокие требования к надежности скрипта -- стоит аккуратнее вызывать внешний ls (проверять, что он не упал).
    Ответ написан
  • Как на bash'е организовать разбор аргументов и ключей?

    Если у скрипта появляются именованные параметры (опции) -- пора переходить с bash на более богатые структурами и библиотеками языки типа Perl, Python, Ruby. Проще отладка, поддержка, доработка.
    Ответ написан
    Комментировать
  • Как удалить элемент из массива Perl по значению?

    Проблем даже несколько.
    Главная -- в grep'ах потерялись отрицания, и получается, что ищем элементы массива, у которых и первая, и вторая половинки равны одновременно и первой, и второй половинке эталонного (случайного) элемента. Таких никогда не находится.

    Вторая серьезная проблема: в функции adsp создается ссылка на анонимный массив ($arrset), который не возвращается из функции. Исходный же массив @arrset не модифицируется.

    Далее: rand возвращает вещественные числа, использовать их для доступа по индексу в массиве -- странновато (хотя и работает -- вещественные округляются).

    И наконец: ни одна переменная в фунции adsp не объявлена (my var), а значит, и use strict в скрипте не используется, т.е. perl не следит за тем, чтобы не использовались необъявленные переменные. В таких случаях обязательно появляются ошибки "присвоили одной переменной, а использовать пытаемся другую".

    Итого. По-моему, код должен был быть таким:

    sub adsp {
      my $rand = int rand @arrset;
      my $rand_num = $arrset[$rand];
      $rand_num =~ /^(\d+)_(\d+)$/;
      my $buf = $1;
      my $buf2 = $2;
    
      @arrset = grep { !/^\d+_$buf$/ } @arrset;
      @arrset = grep { !/^\d+_$buf2$/ } @arrset;
      @arrset = grep { !/^${buf}_\d+$/ } @arrset;
      @arrset = grep { !/^${buf2}_\d+$/ } @arrset;
      return $rand_num; 
    }


    Случайные индекс берется целый, модифицируется исходный массив @arrset, в grep'ах условия с отрицанием, все переменные объявлены лексическими (my).

    И обязательно используйте в каждом скрипте
    use strict;
    use warnings;

    -- это экономит много времени на отладке.
    Ответ написан
    Комментировать
  • Алгоритмы визуализации графов, откуда взять информацию?

    Например, есть GraphViz -- программа для визуализации графов. Ею можно пользоваться, а кроме того, у них большой и информативный сайт.

    Сайт: www.graphviz.org
    примеры работы: www.graphviz.org/Gallery.php
    описание на русском: www.portablecomponentsforall.com/edu/graphviz-about-ru
    ссылки на теорию: www.graphviz.org/Theory.php
    Википедия английская: en.wikipedia.org/wiki/Graph_drawing
    Википедия русская: ru.wikipedia.org/wiki/%D0%92%D0%B8%D0%B7%D1%83%D0%...

    Надеюсь, ссылки в какой-то степени помогут.

    Кстати, существует целый ежегодный Международный визуализации графов (организаторы: graphdrawing.org), так что тема весьма серьезна.
    Ответ написан
    Комментировать
  • Почему не запускается MySQL?

    Еще не нашли причину проблемы?

    Может быть, не хватает прав на промежуточные директории, чтобы добраться до файла; может быть, в конфиге указан все-таки не тот файл, который потом смотрите. Может быть еще что-то.

    Когда происходит такое "непонятно что" с файлами и процессами, очень полезен strace, который выводит все сделанные системные вызовы с параметрами и результатами (man strace)
    Чтобы проследить и за всеми дочерними процессами -- ключ -f

    Т.е. делаете что-то вроде
    sudo strace -f -s 2000 /usr/bin/mysqld_safe --defaults-file=/etc/mysql/my.cnf 2>strace_log

    (с поправкой на конфиг и бинарник)
    и изучаете strace_log.

    В первую очередь интересно:
    * делается ли open на файл лога,
    * какой результат у open'а,
    * делаются ли write с номером дескриптора, который вернул open.
    Ответ написан
  • Есть массив треугольников, заданных координатами вершин. Как определить номера треугольников, подобных первому?

    1. Проверять подобие по соотношениям периметра и площади -- недостаточно. Контрпример есть в комментарии @tsarevfs, теоретическое обоснование -- в комментарии @jcmvbkbc.

    2. Если треугольники заданы координатами вершин -- проще всего проверять третий признак подобия (все три стороны одного треугольника пропорциональны сторонам другого).

    3. Если координаты вершин -- небольшие целые числа, то лучше проверять пропорциональность не самих сторон, а их квадратов, причем проверять не отношения сторон, а произведения "крест-накрест".
    Чтобы сравнивать только потенциально соответственные стороны -- сортировать длины сторон (на самом деле квадраты длин) в каждом треугольнике по возрастанию.

    Например, вот так можно модифицировать исходный код:
    # квадрат расстояния между двумя точками
    def length2(a, b):
        return (a[0] - b[0])**2 + (a[1] - b[1])**2
    
    # подобны ли 2 треугольника, заданные отсортированными массивами длин сторон
    def is_sim(sample, triangle):
        if sample[0] * triangle[1] != sample[1] * triangle[0]:
            return False
        elif sample[0] * triangle[2] != sample[2] * triangle[0]:
            return False
        elif sample[1] * triangle[2] != sample[2] * triangle[1]:
            return False
        else:
            return True
    
    # преобразование массивов координат в массивы длин сторон
    def make_triangles(v):
        triangles = []
        for i in v:
            a2 = length2(i[0], i[1])
            b2 = length2(i[0], i[2])
            c2 = length2(i[1], i[2])
            triangle = [a2, b2, c2]
            triangle.sort()
            triangles.append(triangle)
        return triangles
    
    # основной код
    triangles = make_triangles(v)
    
    for i in range(1, len(triangles) ):
        if is_sim(triangles[0], triangles[i]):
            print "found similar trinangle: %s" % v[i]


    Если координаты могут быть большими и/или вещественными, то лучше вернуться к длинам и отношениям, но при сравнении в фунции is_sim полагаться не на точное равенство, а с допуском ("с эпсилонами", см. комментарии @bluesky и @tsarevfs)

    И на всякий случай: в комментариях были сомнения про зеркально-симметричные треугольники. Так вот, зеркальное отражение подобно исходному треугольнику, и порядок обхода сторон для сравнения роли не играет.
    Ответ написан
    Комментировать
  • Существуют ли сервисы для построения графических схем баз данных?

    Есть Schema Spy: schemaspy.sourceforge.net
    Генерирует html-документы со схемой отношений, статистикой, аномалиями и т.п.

    Их собственный пример того, что получается: schemaspy.sourceforge.net/sample/relationships.html

    Больше примеров скриншотов -- в Яндекс/Гугл Картинках по запросу schemaspy

    В нашем проекте используем, и новым разработчикам часто оказывается удобно изучать графическую схему отношений. Опытные обычно предпочитают текстовое описание.
    Ответ написан
    1 комментарий
  • Русскоязычные ресурсы по Perl?

    Вот еще новый список русскоязычных Perl-ресурсов на perlmaven.com: ru.perlmaven.com/pomosch
    Ответ написан
    Комментировать
  • Как сократить bash скрипт?

    Если список файлов навсегда останется как есть -- то и так все нормально, только лучше бы #!/bin/bash поменять на #!/bin/sh

    А вот если ожидается, что количество или расположение копируемых файлов будет хотя бы иногда меняться -- я бы сделала так:

    #!/bin/sh
    
    for file in \
        /etc/squid/URLs/accessed/access.sorted \
        /etc/squid/URLs/accessed/oper_kass_url \
        /etc/squid/URLs/denied/deny.url.uniq \
        ;
    do
        cp $file /home/security/urls/
    done
    
    for file in \
        /etc/squid/groups/full.dom \
        /etc/squid/groups/limit.dom \
        /etc/squid/groups/oper_kass.dom \
        /etc/squid/groups/unlim.dom \
        ;
    do
        cp $file /home/security/groups/
    done
    
    for file in \
        /etc/squid/squid.conf \
        ;
    do
        cp $file /home/security/urls/
    done


    На скорость работы не влияет, по строчкам получается даже больше, чем в исходном варианте, и существенно больше, чем в предложении gen1s.
    Зато исходные файлы и целевые каталоги разнесены по разным строкам, а это легче читается и проще правится. Если надо добавить копирование еще одного или нескольких файлов -- просто добавляем однотипные строки. Выкинуть файл из копирования -- удалить строку. Ошибиться невозможно ^_^

    На всякий случай: после бекслешей не должно быть пробелов (это способ разбить длинную команду на несколько строк).
    Ответ написан
    Комментировать