- как сделать чтобы цикл не останавливался, rew, 17:44 , 02-Фев-14 (1)
Проще запоминать последнюю отработанную строку в файле и при следующем запуске начинать с нее.
- как сделать чтобы цикл не останавливался, gorlum300, 19:16 , 02-Фев-14 (2)
хм, а как это можно здесь сделать?
- как сделать чтобы цикл не останавливался, skb7, 22:30 , 02-Фев-14 (3)
> хм, а как это можно здесь сделать?Как мне видится, скрипт должен дергаться по какому-то событию, например по cron'у, или по событию изменения файла. Скрипт должен обрабатывать строки с последней обработанной (в предыдущем запуске скрипта) и до конца файла. После того как обработали файл, сохранить номер последней обработанной строки:
last_processed_line=$(wc -l file_name | awk '{print $1}')
и сохранить в свой файл (для примера пусть будет "my_file.txt") в /var/tmp/:
echo -n $last_processed_line >/var/tmp/my_file.txt
При следующем вызове скрипта, считать из того временного файла номер последней обработанной строки:
last_processed_line=$(cat /var/tmp/my_file.txt)
Дальше надо вычислить сколько строк не обработано на данный момент:
line_count=$(wc -l file_name | awk '{print $1}') not_processed_lines=$((line_count - last_processed_line))
Вывести и обработать только необработанные строки:
for dir_name in $(tail -n $not_processed_lines file_name | grep var2 | awk '{print $2}'); mkdir -p $dir_name .... do done
- как сделать чтобы цикл не останавливался, skb7, 01:08 , 03-Фев-14 (4)
Сорри, в последнем куске кода должно быть:
for dir_name in $(tail -n $not_processed_lines file_name | grep var2 | awk '{print $2}'); do mkdir -p $dir_name .... done
- как сделать чтобы цикл не останавливался, михалыч, 20:53 , 03-Фев-14 (5)
>[оверквотинг удален] > var1 frog32 > var2 2013-01-014234 > var3 "url" > var1 rabit1 > var2 2013-01-033122 > var3 "url2" > итд > Задача периодически читать этот файл и для новых данных создавать директорию по > имени значения следующего после var2, куда записывать текстовый файл с именем > после var1 и скачивать файл следующий после var3.Похоже как на менеджер закачек файлов по запросу. Попробовал на perl Вроде взлетает и летит )) Но есть подводные камни (( какие файлы закачиваются - большие, маленькие? проверять на обрыв закачки? что будет если закачка прервётся? #!/usr/bin/perl use strict; use warnings; my ($usr, $dir, $url);
# корневая директория my $r_dir = "/tmp"; # дополняемый файл my $file = "/tmp/txt"; open FH, $file or die "can't open $file: $!"; for (;;) { exit if (stat(FH))[3] == 0; while (<FH>) { chomp; if (/var1/) { s/^var1\s(.*)$/$1/; $usr = $1; } if (/var2/) { s/^var2\s(.*)$/$1/; $dir = $1; } if (/var3/) { s/^var3\s(.*)$/$1/; $url = $1; # название файла для закачки my $out = $url; # обрезаем его - из "http://ya.ru" получаем ya.ru $out =~ s|.*/(.*)\"|$1|; mkdir "$r_dir/$dir"; `touch "$r_dir/$dir/$usr"`; `wget -O "$r_dir/$dir/$out" $url`; } } sleep "1"; seek (FH, 0, 1); } Лучше было бы писать в дополняемый файл строки массивчиками user date url типа frog32 2013-01-014234 "url" было бы гораздо надёжнее его потрошить
- как сделать чтобы цикл не останавливался, gorlum300, 23:06 , 03-Фев-14 (6)
спасибо! похоже начинает работать, однако, у меня выдает ошибки в этом месте: $out =~ s|.*/(.*)\"|$1|; mkdir "$r_dir/$dir"; `touch "$r_dir/$dir/$usr"`; `wget -O "$r_dir/$dir/$out" $url`; --- Global symbol "$out" requires explicit package name at ./workp.pl line 38. Global symbol "$out" requires explicit package name at ./workp.pl line 42. я вот неуверен, что это значит? > какие файлы закачиваются - большие, маленькие? > проверять на обрыв закачки? > что будет если закачка прервётся? закачиваются небольшие файлы по 50-500kb. в идеале, конечно, нужно попробовать добавить вторую попытку скачать, и в случае если закачка не идет(идет не до конца), создавать файл с именем типа warning в директории куда скачиваются файлы. > Лучше было бы писать в дополняемый файл строки массивчиками > user date url > типа > frog32 2013-01-014234 "url" > было бы гораздо надёжнее его потрошить Сейчас потестируем рабочий вариант и если будет стабильно работать, то это будет не важно. Но тем не менее, расскажите, почему будет надежнее?
- как сделать чтобы цикл не останавливался, михалыч, 12:23 , 04-Фев-14 (7)
> Но тем не менее, расскажите, почему будет надежнее?А потому, что будет не просто всем сёстрам по серьгам, а будет конкретным сёстрам конкретные серьги. user1 2013-01-014234 http://ya.ru user2 2013-01-033122 http://google.ru Прочитал строку, а в ней сразу указано какому юзеру что и куда. Значения в строке файла должны быть разделены пробелами, url для закачки без кавычек.
#!/usr/bin/perluse strict; use warnings; my ($usr, $dir, $url, $out);
# корневая директория my $r_dir = "/tmp"; # дополняемый файл вида разделён пробелами # user1 date url # user2 date url my $file = "/tmp/txt"; open FH, $file or die "can't open $file: $!"; for (;;) { # вываливаемся если дополняемый файл вдруг удалили или он исчез )) exit if (stat(FH))[3] == 0; while (<FH>) { chomp; # разбиваем входную строку split'ом по пробелам и складывем в массив my @str = split(" ", $_); $usr = $str[0]; # название юзера $dir = $str[1]; # директория по дате и времени $url = $str[2]; # линк для закачки файла $out = $url; # выходной файл для записи в него загрузки через wget $out =~ s|^.*/(.*)$|$1|; # обрезаем его, делаем из http://ya.ru только ya.ru # создаём директорию по дате mkdir "$r_dir/$dir"; # создаём файл по имени юзера `touch "$r_dir/$dir/$usr"`; # путь к исполняемому файлу wget и параметры закачки # wget -q (тихий режим) -t 1 (1 повтор при неудаче) -O сохранить в файл my $wget = "/usr/bin/wget -q -t 1 -O \"$r_dir/$dir/$out\" $url"; # если загрузка неудачна - удаляем выходной файл и создаем файл warning unlink "$r_dir/$dir/$out" and `touch "$r_dir/$dir/warning"` if system $wget; } # спать. спать.. спать... )) sleep "1"; # читаем файл до конца, сбрасываем флаг EOF seek (FH, 0, 1); } Закачиваете странички или файлы? Кто или что формирует дополняемый файл?
- как сделать чтобы цикл не останавливался, gorlum300, 14:55 , 04-Фев-14 (8)
закачиваются файлы. файл со списком имен и урлов формируется другим скриптом. я его немного переделал и теперь он формирует данные в виде:user1 2013-01-014234 http://ya.ru http://google.com user2 2013-01-013311 http://ya2.ru http://google2.com добавился еще один урл Неуверен насколько правильно, но я добавил закачку второго урла в код, выдает ошибки но все работает: #!/usr/bin/perl use strict; use warnings; my ($usr, $dir, $url, $url2, $out, $out2);
my $r_dir = "~/Downloads";
my $file = "~/Downloads/txt";
open FH, $file or die "can't open $file: $!"; for (;;) { exit if (stat(FH))[3] == 0; while (<FH>) { chomp; my @str = split(" ", $_); $usr = $str[0]; $dir = $str[1]; $url = $str[2]; $url2 = $str[3]; $out = $url; $out =~ s|^.*/(.*)$|$1|; $out2 = $url2; $out2 =~ s|^.*/(.*)$|$1|; mkdir "$r_dir/$dir";
`touch "$r_dir/$dir/$usr"`; my $wget = "wget -q -t 1 -O \"$r_dir/$dir/$out\" $url"; my $wget1 = "wget -q -t 1 -O \"$r_dir/$dir/$out2\" $url2"; unlink "$r_dir/$dir/$out" and `touch "$r_dir/$dir/warning"` if system $wget; unlink "$r_dir/$dir/$out2" and `touch "$r_dir/$dir/warning-big"` if system $wget1; } sleep "1"; seek (FH, 0, 1); exit; } ошибки вида: Use of uninitialized value $out in substitution (s///) at ./work2.pl line 31, <FH> line 3. Use of uninitialized value $out2 in substitution (s///) at ./work2.pl line 33, <FH> line 3. Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 36, <FH> line 3. Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 38, <FH> line 3. Use of uninitialized value $usr in concatenation (.) or string at ./work2.pl line 38, <FH> line 3. Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 40, <FH> line 3. Use of uninitialized value $out in concatenation (.) or string at ./work2.pl line 40, <FH> line 3. Use of uninitialized value $url in concatenation (.) or string at ./work2.pl line 40, <FH> line 3. Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 41, <FH> line 3. Use of uninitialized value $out2 in concatenation (.) or string at ./work2.pl line 41, <FH> line 3. Use of uninitialized value $url2 in concatenation (.) or string at ./work2.pl line 41, <FH> line 3. wget: missing URL Usage: wget [OPTION]... [URL]... Просто интересно - насколько это критично?
- как сделать чтобы цикл не останавливался, михалыч, 16:41 , 04-Фев-14 (9) +1
>[оверквотинг удален] > Use of uninitialized value $usr in concatenation (.) or string at ./work2.pl line 38, <FH> line 3. > Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 40, <FH> line 3. > Use of uninitialized value $out in concatenation (.) or string at ./work2.pl line 40, <FH> line 3. > Use of uninitialized value $url in concatenation (.) or string at ./work2.pl line 40, <FH> line 3. > Use of uninitialized value $dir in concatenation (.) or string at ./work2.pl line 41, <FH> line 3. > Use of uninitialized value $out2 in concatenation (.) or string at ./work2.pl line 41, <FH> line 3. > Use of uninitialized value $url2 in concatenation (.) or string at ./work2.pl line 41, <FH> line 3. > wget: missing URL > Usage: wget [OPTION]... [URL]... > Просто интересно - насколько это критично?не критично это в результате попытки использовать неинициализированные переменные, нужно сделать проверку на существование $dir, $out, $url видимо попадаются строки только с юзером без dir и/или url типа user user dir #!/usr/bin/perluse strict; use warnings; my ($usr, $dir, $url, $url2, $out, $out2);
# корневая директория my $r_dir = "/tmp"; # дополняемый файл вида разделён пробелами # user1 date url url2 # user2 date url url2 my $file = "/tmp/txt"; open FH, $file or die "can't open $file: $!"; for (;;) { # вываливаемся если дополняемый файл вдруг удалили или он исчез )) exit if (stat(FH))[3] == 0; while (<FH>) { chomp; # разбиваем входную строку split'ом по пробелам и складывем в массив my @str = split(" ", $_); $usr = $str[0]; # название юзера $dir = $str[1]; # директория по дате и времени $url = $str[2]; # линк для закачки файла $url2= $str[3]; # линк для закачки файла # если нет $usr или $dir дальнейшее безсмысленно, переходим к следующей строке next if !defined $usr or !defined $dir; # если нет $url и $url2 дальнейшее безсмысленно, переходим к следующей строке next if !defined $url and !defined $url2; # создаём директорию по дате mkdir "$r_dir/$dir"; # создаём файл по имени юзера `touch "$r_dir/$dir/$usr"`; # если переменная $url определена - делаем вещи if (defined $url) { $out = $url; # выходной файл для записи в него загрузки через wget $out =~ s|^.*/(.*)$|$1|; # обрезаем его, делаем из http://ya.ru только ya.ru # путь к исполняемому файлу wget и параметры закачки # wget -q (тихий режим) -t 1 (1 повтор при неудаче) -O сохранить в файл my $wget = "/usr/local/bin/wget -q -t 1 -O \"$r_dir/$dir/$out\" $url"; # если загрузка неудачна - удаляем выходной файл и создаем файл warning unlink "$r_dir/$dir/$out" and `touch "$r_dir/$dir/warning"` if system $wget; } # если переменная $url2 определена - делаем вещи if (defined $url2) { $out2 = $url2; # выходной файл для записи в него загрузки через wget $out2 =~ s|^.*/(.*)$|$1|; # обрезаем его, делаем из http://ya.ru только ya.ru # путь к исполняемому файлу wget и параметры закачки # wget -q (тихий режим) -t 1 (1 повтор при неудаче) -O сохранить в файл my $wget2 = "/usr/local/bin/wget -q -t 1 -O \"$r_dir/$dir/$out2\" $url2"; # если загрузка неудачна - удаляем выходной файл и создаем файл warning2 unlink "$r_dir/$dir/$out2" and `touch "$r_dir/$dir/warning2"` if system $wget2; } } # спать. спать.. спать... )) sleep "1"; # читаем файл до конца, сбрасываем флаг EOF seek (FH, 0, 1); } Есть ещё чо пожевать? ))
- как сделать чтобы цикл не останавливался, gorlum300, 21:37 , 04-Фев-14 (10)
блин, спасибо большое! оно действительно работает!:) Еще я сейчас заметил, что в случае если в дополняемом файле значение $dir для нескольких юзеров одинаковое (это таймстемп) то все складывается в одну директорию.те если например: user1 2013-01-014234 http://ya.ru user2 2013-01-014234 http://google.ru то все летит в папку 2013-01-014234 я думаю как бы сделать проверку для одинаковых имен и в случае если такое уже есть, то создавать такое же, но с дополнением (напр., 2013-01-014234-duble) что-то вроде: if (-d "$dir") { print "dublicate"; mkdir "$r_dir/$dir"; rename "$r_dir/$dir","$r_dir/$dir,duble"; `touch $r_dir/$dir,duble/$usr"`;
- как сделать чтобы цикл не останавливался, михалыч, 22:36 , 04-Фев-14 (11)
>[оверквотинг удален] > то все летит в папку 2013-01-014234 > я думаю как бы сделать проверку для одинаковых имен и в случае > если такое уже есть, то создавать такое же, но с дополнением > (напр., 2013-01-014234-duble) > что-то вроде: > if (-d "$dir") > { print "dublicate"; > mkdir "$r_dir/$dir"; > rename "$r_dir/$dir","$r_dir/$dir,duble"; > `touch $r_dir/$dir,duble/$usr"`; имя пользователя уникально? ну так сразу создавать директорию mkdir "$r_dir/$dir-$usr"; ну и дальше по коду поправить
- как сделать чтобы цикл не останавливался, михалыч, 05:21 , 05-Фев-14 (12)
> имя пользователя уникально? > ну так сразу создавать директорию > mkdir "$r_dir/$dir-$usr"; > ну и дальше по коду поправить sed -i ".bak" 's|/$dir|/$dir-$usr|g' work.pl
|