Battle Forum

Battle Forum (http://battlefox.rooty.ru/index.php)
-   Программная - Linux (http://battlefox.rooty.ru/forumdisplay.php?f=80)
-   -   Сила shell'ов (http://battlefox.rooty.ru/showthread.php?t=3519)

tmp0000 29.05.2007 01:06

Сила shell'ов
 
Вот написал скриптик:
Спойлер

#/bin/bash
# Script for cleaning old Debian packaged
# Author: Igor Pellinen (Russia) aka Igron aka tmp0000

# First, create file with Packages
dpkg-scanpackages . /dev/null > Packages 2>/dev/null

# Make temporary directory
mkdir temp_dir_with_new_packages

# Move actual files to temporary directory
for i in `awk '/^Filename:/ {print $2}' Packages`; do test -f $i && mv $i ./temp_dir_with_new_packages/; done

# Delete old Debian packages, they are in current directory
rm -f ./*.deb

# Now, after deleting old packages, we must back actual packages back to the current directory:
cd ./temp_dir_with_new_packages/
for i in *.deb; do mv $i ../; done
cd ../

# Remove temporary directory and packages files
rmdir temp_dir_with_new_packages
rm Packages

Он занимается тем, что удаляет старые deb-пакеты, если существуют пакеты более новых версий.
Сам знаю, что все довольно топорно и неэффективно в плане скорости (создается временная директория, туда перемещаются нужные (актуальные) пакеты, удаляются старые, затем все перемещается назад.

Как можно улучшить скорость работы скрипта?

Frosty 29.05.2007 14:59

Не прокатит такой вариант:в очищаемой папке создать файлик old-debs и при нахождении старого пакета записать в него remove /path/to/old/deb/ и интер :) и так по циклу, а потом просто запустить этот скрипт :) Или бред?

rmn 29.05.2007 16:46

Код:

#!/bin/bash

dpkg-scanpackages . /dev/null > Packages 2>/dev/null
ls -1 ./*.deb | sort > old.list
awk '/^Filename: / {print $2}' Packages | sort > new.list
diff {old,new}.list | grep '^< ' | sed 's/^< //' | xargs rm -f
rm -f {old,new}.list

так лучше ? :)

greiv 29.05.2007 17:36

Цитата:

Сообщение от tmp0000 (Сообщение 123807)
Вот написал скриптик:
Спойлер

#/bin/bash
# Script for cleaning old Debian packaged
# Author: Igor Pellinen (Russia) aka Igron aka tmp0000

# First, create file with Packages
dpkg-scanpackages . /dev/null > Packages 2>/dev/null

# Make temporary directory
mkdir temp_dir_with_new_packages

# Move actual files to temporary directory
for i in `awk '/^Filename:/ {print $2}' Packages`; do test -f $i && mv $i ./temp_dir_with_new_packages/; done

# Delete old Debian packages, they are in current directory
rm -f ./*.deb

# Now, after deleting old packages, we must back actual packages back to the current directory:
cd ./temp_dir_with_new_packages/
for i in *.deb; do mv $i ../; done
cd ../

# Remove temporary directory and packages files
rmdir temp_dir_with_new_packages
rm Packages

Он занимается тем, что удаляет старые deb-пакеты, если существуют пакеты более новых версий.
Сам знаю, что все довольно топорно и неэффективно в плане скорости (создается временная директория, туда перемещаются нужные (актуальные) пакеты, удаляются старые, затем все перемещается назад.

Как можно улучшить скорость работы скрипта?

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

rmn 29.05.2007 17:41

greiv, если бы он мог это сделать, то не заморачивался бы с написанием скриптов. :) Вообще, чтобы "вкурить" что он хочет автоматизировать, надо примерно знать как устроены и создаются репозитории debian/ubuntu и как там нумеруются версии пакетов.

greiv 29.05.2007 18:34

rmn, а ты внимательно прочитай, что он в скобках написал - ...туда перемещаются нужные (актуальные) пакеты. Т.е. все же он их различает актуальные-то. Или он просто выразился не правильно.

rmn 29.05.2007 18:44

greiv, я внимательно читал, более того - этой фигней занимался уже.

Есть каталог, в него навалена куча deb-пакетов различных версий, например, foo 0.40, foo 0.41, foo 0.41 backported. Пакетов для простоты - 1000 штук по 3-4 версии каждого.
Из них в каталоге нужно оставить только "актуальные" пакеты (вроде foo 0.41).

dpkg-scanpackages, грубо говоря, выдаёт список "актуальных" пакетов. Задача сводится к тому, чтобы из начального списка вычленить неактуальные, используя шелл.

greiv 29.05.2007 20:04

rmn, ну цель-то понятна=), раз dpkg-scanpackages такой хороший, что выплевывает список "актуальных" пакетов, то зачем нужна свистопляска с отдельными директориями и перемещениями по тысячу раз... как будто неактуальные нельзя замочиь в том же каталоге

rmn 29.05.2007 21:13

greiv, мне не совсем понятно, что ты предлагаешь. Шелл-сценарий для решения задачи в студию. :)

tmp0000 29.05.2007 21:20

Цитата:

Код:

diff {old,new}.list | grep '^< ' | sed 's/^< //' | xargs rm -f
так лучше ?
Вроде да, я это пытался сделать, но как-то "ниасилил".. :(

Frosty 29.05.2007 21:31

Цитата:

Сообщение от rmn (Сообщение 123990)
Код:

dpkg-scanpackages . /dev/null > Packages 2>/dev/null
ls -1 *.deb | sort > old.list
awk '/^Filename: / {print $2}' Packages | sort > new.list
diff {old,new}.list | grep '^< ' | sed 's/^< //' | xargs rm -f
rm -f {old,new}.list

так лучше ? :)

Нипаешт :) закоим то создает новый Packzges.gz а пакетов старых не потирает :)

rmn 29.05.2007 21:34

Frosty, опять напилсо. попробуй его с утра запустить. :]

tmp0000 29.05.2007 21:34

Цитата:

Сообщение от rmn (Сообщение 124153)
Frosty, опять напилсо. попробуй его с утра запустить. :]

+1!!! :D :D :D

Frosty 29.05.2007 21:59

Цитата:

Сообщение от rmn (Сообщение 124153)
Frosty, опять напилсо. попробуй его с утра запустить. :]

Дануна, я закинул скриптв папку с архивами, запустил, он нахреначил мне новый Packages.gz, о чем и написал в консоли с подробным выводом списка пакетов, которые он включил, а файл gstreamer0.10-plugins-ugly_0.10.4-0ubuntu2_i386, лежащий рядом с gstreamer0.10-plugins-ugly_0.10.5-0ubuntu2_i386 не похерил...

rmn 30.05.2007 13:04

Frosty, дык .gz надо развернуть предварительно. Либо прямо в скрипте изменить строку так:
Код:

zcat Packages.gz | awk '/^Filename: / {print $2}' | sort > new.list


Добавлено через 14 часов 31 минуту
Frosty, все-таки решил проверить на себе код ;) чтобы 100% работало без собственноручных доводок, нужно подправить строку
Код:

ls -1 ./*.deb | sort > old.list

Frosty 30.05.2007 14:25

полностью от начала и до конца выложи скрипт, а то опять тренироваца не хочется :)

tmp0000 30.05.2007 15:55

Цитата:

полностью от начала и до конца выложи скрипт, а то опять тренироваца не хочется
Да, я тоже себе кое-что убил :(

rmn 30.05.2007 16:04

код
должно работать :) но проверять сейчас времени нет.

Frosty 30.05.2007 21:12

Цитата:

Сообщение от rmn (Сообщение 124456)
код
должно работать :) но проверять сейчас времени нет.

Опять мимо :)

Код:

frosty@frosty-desktop:~/Desktop/неозаглавленная папка$ sudo sh "/home/frosty/Desktop/неозаглавленная папка/clean"
diff: пропущен операнд после `{old,new}.list'
diff: Попробуйте `diff --help' для получения более подробного описания.

Но пакеты хотя бы разграничивает:
Цитата:

Сообщение от old.list
./gstreamer0.10-plugins-ugly_0.10.4-5_i386.deb
./gstreamer0.10-plugins-ugly_0.10.5-0ubuntu2_i386.

Цитата:

Сообщение от new.list
./gstreamer0.10-plugins-ugly_0.10.5-0ubuntu2_i386.


rmn 30.05.2007 21:33

Frosty, скрипт написан на bash, а ты его запускаешь через sh. RTFM :)

Frosty 30.05.2007 21:52

Все, работает, идеально ;)

Frosty 02.06.2007 12:01

Хех, запустил скрипт rmn'a в папке с пакетами-моментальный Shift+Delete всей папки, смешно блин, видимо придеца опять выкачивать пару часов все архивы :)
Скрипт удаляет все.deb

rmn 02.06.2007 16:34

Frosty, да-да, деструкция - наше фсё. :]
переделай скрипт, чтобы он не удалял, а перемещал пакеты в отдельный каталог.

Frosty 02.06.2007 17:18

Если запукать скрипт через консоль из сухого и темного места, то все работает нормально, а ели из папки с пакетами, то приходица качать заново :)

tmp0000 03.06.2007 01:01

Скрипт для массового переименования файлов с неправильными названиями
Спойлер
#/bin/bash
#Script that renames deb-packages that have bad filenames.
#Author: Igor Pellinen (Russia) aka Igron aka tmp0000 && Vadim Gusev (Russia) aka Frosty

#First we do a textfile that contains wrong filenames
find . -name '*%3a*' > wrong.names

#Rename files, mask [0-9]%3a is changed to nothing
for i in `grep %3a wrong.names`; do mv $i `echo $i | awk '{gsub("[0-9]%3a","");print }'` ; done

#Remove temporary textfile
rm wrong.names

#All done. What are waiting to see here? :)

dotpack 19.08.2007 22:44

Подскажите, пожалуйста, необходимо для определённой директории сделать следующее:
- всем каталогам присвоить права 755
- всем файлам присвоить права 644

rmn 20.08.2007 19:13

dotpack,
Код:

find /определенная/директория/ -type d -exec chmod 755 {} \;
find /определенная/директория/ -type f -exec chmod 644 {} \;


tmp0000 03.10.2007 21:18

Возник вопросец: вывести все директории в текущей дире.
Код:

for i in *; do test -d $i && echo $i; done
выдает в некоторых строках:
Код:

bash: test: слишком много аргументов
Оффтоп
Оффтоп Это нужно товарищу в дальнейшем для аналога Denver под linux (да, знаю, это абсурдно звучит)

NOboDy 03.10.2007 21:24

Цитата:

Сообщение от tmp0000 (Сообщение 174275)
for i in *; do test -d $i && echo $i; done

Видимо дело в этом:
Код:

for i in *; do test -d "$i" && echo $i; done

rmn 03.10.2007 21:49

золотое правило шелл-программинга - кавычить переменные. Во избежание.

ArcFi 16.04.2008 19:11

Недавно пришлось переустанавливать систему и, чтобы потом не перекачивать заново 2,5 Гб, решил забекапить кэш, предварительно почистив его от пакетов старых версий.
К сожалению, aptitude autoclean удаляет старые пакеты, даже если они находятся в количестве одной версии, поэтому решил было использовать dpkg-scanpackages, как показано несколькими постами выше, немного оптимизировав код:
Код:

dpkg-scanpackages archives 2>&1 | grep -e '^ !.*is repeat;' | \
        grep -o -e 'archives\/.*\.deb' | while read
do
        sudo rm -v "${REPLY}"
done

Предполагаю, что кусок grep -e '^ !.*is repeat;' | grep -o -e 'archives\/.*\.deb' можно было бы заменить чем-то более элегантным...

И всё-таки, dpkg-scanpackages работает достаточно медленно, к тому же требует установки дополнительных пакетов, поэтому немного поразмыслив, написал ещё 1 сценарий:
Код:

ls -1 archives/*.deb | while read
do
        test "${REPLY%%_*}" == "${PREV%%_*}" && sudo rm -v "${PREV}"
        PREV="${REPLY}"
done

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

Elwen 30.09.2008 21:31

Вот такая задача:
Находится с помощью поиска (find) перечень неких каталогов, и необходимо подсчитать количество этих каталогов (с помощью команды wc) и вывести этот перечень на экран вместе с их количеством. Реально ли это сделать? По отдельности то всё работает )

rmn 30.09.2008 21:52

ну, если "в лоб", то так
Код:

list="`find . -type d критерии поиска неких каталогов`"; \
echo "$list"; echo "$list" | wc -l


Elwen 30.09.2008 22:22

rmn, не работает ) echo "$list" просто печатает собственно строку find блаблабла, ито без этого - \

rmn 30.09.2008 22:26

Mornis, первый аргумент у find - корневой каталог поиска. В примере это текущий каталог (ему соответствует точка в шелле). Соответственно, точку надо заменить на каталог, о котором идёт речь в задании. Например, корневой /.

Во-вторых, критерии поиска тоже нужно сформулировать согласно синтактису команды find. Критерии поиска мне не ведомы. ;)

В-третьих, важен порядок, тип и кол-во кавычек. Шелл к этому чувствителен. :) Если всё это в порядок привести, то работать должно.

Elwen 30.09.2008 22:30

rmn, во первых, я додумалась до того чтобы написать в поиске всё что нужно :) во вторых всё остальное ввела так же как у вас, но не работает ) кстати другого способа нет? ато можно ещё два раза поиск написать, то же самое будет

rmn 30.09.2008 22:33

Mornis, какой шелл? версия? Вообще, лучше всё это сразу приводить. И задание дословно, и команда, которая в шелле исполнялось. Иначе разговор слепого с глухим получается.

InS7 30.09.2008 22:48

версия там:
Код:

/bin/bash --help
GNU bash, version 3.1.17(1)-release-(i586-suse-linux-gnu)

у меня работает
Код:

list="`find /home -type d `";echo "$list"; echo "$list" | wc -l
а так
Код:

user@xxx:~> list="`find ~ -type d `";echo "$list"; echo "$list" | wc -l
list="`find ~ -type d `";echo "$list"; echo "$list" | wc -l
find ~ -type d
^C

не хочет

Добавлено через 2 минуты
ps. -maxdepth 1 добавь а то там где ты ищещь запаришься искать ;)

tmp0000 05.03.2009 13:36

В последнее время только и занимаюсь тем, что качаю клипы с трубы.

Накидал скриптик для автоматического получения названия песни с трубы и переименования файлов.
Спойлер
#!/bin/bash
# ver. 0.1.0
# Script for collecting info from truba videos and rename files
# Author: Igor Pellinen <igronus[at]gmail[dot]com>
# Licence: GPL3+

# Directories
CLIPS_DIRECTORY="/home/igron/newclips/"

# Log file
LOG_DIRECTORY="/home/igron/"
LOG_FILE=".truba-parser.log"

# Create a new log file if it doesn't exist
cd "$LOG_DIRECTORY"
[ -e "$LOG_FILE" ]
if [ $? -eq 1 ]; then
echo "It seems like log file does not exist, creating..."
touch "$LOG_FILE"
fi

# Adding start time to log
echo "`date` Truba-parser started" >> "$LOG_DIRECTORY"/"$LOG_FILE"

# Start process
cd "$CLIPS_DIRECTORY"
for file_name in *
do
# File extension
extension=`echo ${file_name##*.}`

# File name without extension
file_short_name=`echo ${file_name%.*}`

# Get html file from truba
wget "http://truba.karelia.ru/video.php?id=$file_short_name" -O temp.file

# Parse info from html file
string=`cat temp.file | sed '1,/<head>/d' | sed '2,/<\/html>/d'`
string_utf=`echo $string | iconv -f koi8-r -t utf8`
length=`echo ${#string_utf}`
new_length=`echo "$length-15" | bc`
new_name=`echo ${string_utf:7:$new_length}`
new_full_name=$new_name"."$extension

# Log and process rename
echo "Renaming $file_name to $new_full_name..." >> "$LOG_DIRECTORY"/"$LOG_FILE"
mv "$file_name" "$new_full_name"

# Removing temporary html file
rm temp.file
done


# Adding end time to log
echo "`date` Truba-parser finished" >> "$LOG_DIRECTORY"/"$LOG_FILE"

Схема такая: URL клипов находится в файле, клипы льются по списку в каталог $CLIPS_DIRECTORY wget'ом, после чего данный скрипт их переименовывает как надо.

PS. No warranty, just idea. Use at your own risk.

NameLess 24.12.2009 22:34

Люди нужна помощь в переделывание скрипта.
есть такой скрипт
Цитата:

#!/bin/bash
while read A TAIL
do
echo $A
done|sort|uniq -c|sort -nr|while read A TAIL
do
echo $TAIL -$A
done
нужно его переделать вот в это:

Цитата:

Системный журнал Linux содержит записи в следующем формате:
дата время хост демон[pid]: сообщение
Пример журнала:
Sep 25 16:55:00 plasma CROND[4014]: bla-bla-bla
Sep 25 16:55:07 plasma CROND[4012]: bla-bla-bla
Sep 25 16:55:23 plasma CROND[4035]: bla-bla-bla
Sep 25 16:55:00 plasma mgetty[4013]: bla-bla-bla

Напишите сценарий, который будет анализировать текст из
системного журнала, поступающий на стандартный ввод сценария,
и сообщать какие различные процессы с какими PID помещают сообщения
в системный журнал.

Пример:
$./myscrpt.sh </var/log/messages
CROND: 4014, 4012, 4035
mgetty: 4013
а то первый осилил а второй пока не могу.


Текущее время: 11:32. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot