LINUX.ORG.RU

инфо о репах на bash (/etc/apt/sources.list.d/)


0

2

Первый раз написал на баш что-то длиннее пары строк, помогите пожалуйста найти ошибки и прочие моветоны..

Общий смысл работы скрипта:

  1. информация о том, какие репы из списка /etc/apt/sources.list.d/*.list реально используются (список установленных пакетов из данного репозитория)
  2. информация о том, какие репы из списка /etc/apt/sources.list.d/*.list устарели и не используются
  3. информация о том, какие репы из списка /etc/apt/sources.list.d/*.list не могут быть использованы (список пакетов пуст или строка deb закомментирована)

Для работы требуются права на чтение /etc/apt/sources.list.d/*.list и /var/lib/apt/lists/*

#!/usr/bin/env bash
DPKG_L="$(dpkg -l)"
INSTALLED=$(echo "$DPKG_L" | sed '1,+6d' | cut -c 5-51)
INSTALLED_VERSIONS=($(echo "$DPKG_L" | sed '1,+6d' | cut -c 52-108))
for FILE in /etc/apt/sources.list.d/*.list
do
        echo $(basename $FILE)
        FILE_LINE=$(grep '^deb ' "$FILE")
        if [[ $FILE_LINE == "" ]]
        then
                echo -e "\t" DISABLED
                continue
        fi
        PACKAGES_CACHE_FILE=/var/lib/apt/lists/$(echo $FILE_LINE | sed 's|/|_|g; s|deb http:__\([^ ]*\) \([^ ]*\) \([^ ]*\).*|\1_dists_\2_\3_binary-amd64_Packages|; s|_\+|_|g;')
        if [[ $(echo $PACKAGES_CACHE_FILE | wc -w) > 1 ]]
        then
                PACKAGES_CACHE_FILE=/var/lib/apt/lists/$(echo $FILE_LINE | sed 's|/|_|g; s|deb http:__\([^ ]*\) \([^ ]*\).*|\1_\2_Packages|; s|_\+|_|g;')
        fi
        PACKAGES=($(grep ^Package: "$PACKAGES_CACHE_FILE" | cut -f 2 -d ' '))
        PACKAGES_VERSIONS=($(grep ^Version: "$PACKAGES_CACHE_FILE" | cut -f 2 -d ' '))
        FROM_CURRENT=''
        FROM_OTHER=''
        NOT_INSTALLED=''
        PACKAGE_KEY=-1
        for PACKAGE in ${PACKAGES[*]}
        do
                PACKAGE_KEY=$[$PACKAGE_KEY+1]
                PACKAGE_INSTALLED=$(echo "$INSTALLED" | grep -w -n $PACKAGE)
                if [[ $PACKAGE_INSTALLED == "" ]]
                then
                        if [[ $(echo $NOT_INSTALLED | wc -w) < 5 ]]
                        then
                                NOT_INSTALLED="$NOT_INSTALLED $PACKAGE"
                        fi
                        continue
                fi

                PACKAGE_INSTALLED_KEY=$[$(echo $PACKAGE_INSTALLED | sed -n 's/\([^:]\+\).*/\1/p') - 1]
                if [[ ${PACKAGES_VERSIONS[$PACKAGE_KEY]} == ${INSTALLED_VERSIONS[$PACKAGE_INSTALLED_KEY]} ]]
                then
                        FROM_CURRENT="$FROM_CURRENT $PACKAGE"
                        if [[ $(echo $FROM_CURRENT | wc -w) < 5 ]]
                        then
                                continue
                        fi
                        break
                fi
                if [[ $(echo $FROM_OTHER | wc -w) < 5 ]]
                then
                        FROM_OTHER="$FROM_OTHER $PACKAGE"
                fi
        done
        echo -e -n "\t "
        if [[ $(echo $FROM_CURRENT | wc -w) != 0 ]]
        then
                echo -e "\t \t\t\t $FROM_CURRENT"
                continue
        fi
        if [[ $(echo $FROM_OTHER | wc -w) != 0 ]]
        then
                echo -e "OBSOLETE \t\t\t $FROM_OTHER"
                continue
        fi
        if [[ $(echo $NOT_INSTALLED | wc -w) != 0 ]]
        then
                echo -e "NOT INSTALLED \t\t\t $NOT_INSTALLED"
                continue
        fi
        echo -e "NO PACKAGES"
done

Результат работы, в консоли правда поровнее чем на форуме:

[aslok@3r]2011.04.14-02:18:20:~$ aptrepotree 
amule-trunk-ppa-maverick.list
                                          amule-common amule amule-utils amule-utils-gui
andrew-crew-kuznetsov-xneur-stable-maverick.list
         DISABLED
atareao-atareao-maverick.list
                                          picapy
debfx-virtualbox-maverick.list
         NOT INSTALLED                    virtualbox-ose virtualbox-ose-dbg virtualbox-ose-fuse virtualbox-ose-guest-utils virtualbox-ose-guest-x11
gnome3-team-gnome3-maverick.list
         NO PACKAGES
hydr0g3n-ppa-maverick.list
         DISABLED
kubuntu-ppa-beta-maverick.list
                                          amarok-common amarok-utils amarok libmygpo-qt1
kubuntu-ppa-ppa-maverick.list
         OBSOLETE                         jovie kmag kmousetool kcron kdeadmin
openoffice-pkgs-ppa-maverick.list
         NO PACKAGES
opera.list
                                          opera
rarewares.org.list
         NOT INSTALLED                    cpp-3.0 g++-3.0 gcc-3.0 gcc-3.0-base libcurl2
ripps818-coreavc-maverick.list
                                          mplayer
tuxonice-ppa-maverick.list
         OBSOLETE                         linux-headers-2.6.35-27 linux linux-source linux-image linux-source-2.6.35
webupd8team-y-ppa-manager-maverick.list
                                          y-ppa-manager yad ppa-purge
[aslok@3r]2011.04.14-02:19:32:~$ 


нормалёк. Только жди щас прибежит толпа «гуру» утверждающих что за башизмы надо голову откручивать. Вопросы к скрипту есть, но я так давно на bash не писал что боюсь даже спрашивать :)

true_admin ★★★★★
()
if [[ 22 < 3 ]]
then
  echo Y
fi

> Y

---------------

if (( 22 < 3 ))
then
  echo Y
fi

> ""

Это к сравнению чисел. Если уж хочется использовать квадратные скобки - нужно писать -lt вместо <

А вообще такие вещи обычно пишут в строку:

[[ $(echo $FROM_OTHER | wc -w) -lt 5 ]] && FROM_OTHER="$FROM_OTHER $PACKAGE"
mosfet
()

Поскольку из внешних программ используется только dpkg, действительно лучше писать такое на perl или python.

Заодно длиннющие строчки с sed-регулярками станут читабельнее.

mosfet
()
Ответ на: комментарий от mosfet

Спасибо, как-то не дошло, а так удобно тестить оказалось! [[ «100» < «90» ]] && echo yeh

Не сразу понял разницу между [[ и (( , подправил.

Может быть поможете ещё немножко? [[ «asd100» > «asd90» ]] ложное утверждение, а собирался сравнивать версии (

Вторая версия, если что http://paste.kde.org/12439/ Пример вывода:

torproject.list 
  http://deb.torproject.org
                                                     tor tor-geoipdb
ubuntu-audio-dev-ppa-maverick.list 
  https://launchpad.net/~ubuntu-audio-dev/+archive/ppa 
    ppa:ubuntu-audio-dev/ppa
         OBSOLETE                         libportaudio2
         INSTALLED                        linux-alsa-driver-modules-2.6.35-28-generic pulseaudio-utils-dbg pulseaudio-utils pulseaudio-module-zeroconf-dbg...
ubuntu-mozilla-daily-ppa-maverick.list 
  https://launchpad.net/~ubuntu-mozilla-daily/+archive/ppa 
    ppa:ubuntu-mozilla-daily/ppa
         OBSOLETE                         firefox
         NOT UPDATED                 xulrunner-1.9.2
         INSTALLED                        firefox-trunk-globalmenu firefox-trunk firefox-4.0-globalmenu firefox-4.0
ubuntu-wine-ppa-maverick.list 
  https://launchpad.net/~ubuntu-wine/+archive/ppa 
    ppa:ubuntu-wine/ppa
                                                     winetricks ia32-libs wine1.2 ttf-symbol-replacement

aslok
() автор топика
Ответ на: комментарий от aslok

Зато с круглыми скобками сразу видно, где сравнение чисел.

«asd100» > «asd90» некорректно сравнивать, ни bash, ни perl, ни python такую конструкцию не понимают. И вообще здесь непонятно что требуется от интерпретатора - то ли сравнение по ASCII, то ли по длине строки, или ещё как. Лучше всё-таки конкретизировать и придумать как отделить имя пакета от номера версии.

Кстати часто замечал что при проверке идентичности строк добавляют какой-нибудь символ типа «x»:

if [ "X$string1" = "X$string2" ]
на случай если одна из $string пуста.

В ABS тоже это рекомендуют: http://www.opennet.ru/docs/RUS/bash_scripting_guide/c2792.html

mosfet
()
Ответ на: комментарий от mosfet

2 mosfet

Лучше всё-таки конкретизировать и придумать как отделить имя пакета от номера версии

Дело в том, что версии содержат служебные слова, так что я решил переложить эту работу на dpkg, раз уж он всё равно в зависимостях )

[[ 0.10.1-1-webupd8~maverick > 0.10.1-1~getdeb1 ]] && echo ok - не выводит
dpkg --compare-versions 0.10.1-1-webupd8~maverick gt 0.10.1-1~getdeb1 && echo ok - выводит

Поскольку из внешних программ используется только dpkg, действительно лучше писать такое на perl или python.

Пробовал на пхп, вполне себе не плохо получается, но я думаю на баше быстрее и проще, если знаешь его не хуже чем пхп (а это как раз не мой случай)

Если уж хочется использовать квадратные скобки - нужно писать -lt вместо <

Насколько я понял, это только для [ ] , а между [[ ]] можно использовать обычные операторы

Третья версия, выводит как и вторая

#!/usr/bin/env bash
T=$(echo -e \\\t)
T2=$T$T
T3=$T$T2
N=$IFS
COLUMNS=190
WIDTH=$[$COLUMNS - 80]
DPKG_L="$(dpkg -l | grep -v ^rc)"
INSTALLED=$(echo "$DPKG_L" | tail -n +8 | cut -d ' ' -f 3)
INSTALLED_VERSIONS=($(echo "$DPKG_L" | tail -n +8 | cut -c 52-108))
for FILE in /etc/apt/sources.list.d/*.list
do
	FILE_LINE=$(grep '^deb ' "$FILE")
	FILE_HOST=$(echo $FILE_LINE | sed 's|deb http://\([^/]*\).*|\1|')
	FILE_DESC=http://$FILE_HOST
	if [[ "$FILE_HOST" == ppa.launchpad.net ]]
	then
		PPA=$(echo $FILE_LINE | sed 's|deb http://ppa\.\([^/]*\)/\([^/]*\)/\([^/]*\).*|ppa:\2/\3|;')
		LAUNCHPAD=$(echo $FILE_LINE | sed 's|deb http://ppa\.\([^/]*\)/\([^/]*\)/\([^/]*\).*|https://\1/~\2/+archive/\3|;')
		FILE_DESC="$LAUNCHPAD$N    $PPA"
	fi
	echo "$(basename $FILE)$N  $FILE_DESC"
	[[ -z $FILE_LINE ]] && echo "$T" DISABLED && continue
	PACKAGES_CACHE_FILE=/var/lib/apt/lists/$(echo $FILE_LINE | sed 's|/|_|g; s|deb http:__\([^ ]*\) \([^ ]*\) \([^ ]*\).*|\1_dists_\2_\3_binary-amd64_Packages|; s|_\+|_|g;')
	if (( $(echo $PACKAGES_CACHE_FILE | wc -w) > 1 ))
	then
		PACKAGES_CACHE_FILE=/var/lib/apt/lists/$(echo $FILE_LINE | sed 's|/|_|g; s|deb http:__\([^ ]*\) \([^ ]*\).*|\1_\2_Packages|; s|_\+|_|g;')
	fi
	PACKAGES=$(grep ^Package: $PACKAGES_CACHE_FILE | cut -f 2 -d ' ')
	PACKAGES_VERSIONS=($(grep ^Version: $PACKAGES_CACHE_FILE | cut -f 2 -d ' '))
	FROM_CURRENT=''
	FROM_OTHER=''
	NOT_UPDATED=''
	NOT_INSTALLED=''
	PACKAGE_KEY=-1
	for PACKAGE in $PACKAGES
	do
		PACKAGE_KEY=$[$PACKAGE_KEY+1]
		PACKAGE_INSTALLED=$(echo "$INSTALLED" | grep -n ^$PACKAGE$)
		if [[ -z $PACKAGE_INSTALLED ]]
		then
			(( $(echo $NOT_INSTALLED | wc -m) < $WIDTH )) && NOT_INSTALLED="$NOT_INSTALLED $PACKAGE"
			continue
		fi
		PACKAGE_INSTALLED_KEY=$[$(echo $PACKAGE_INSTALLED | cut -d ':' -f 1) - 1]
		if dpkg --compare-versions ${PACKAGES_VERSIONS[$PACKAGE_KEY]} eq ${INSTALLED_VERSIONS[$PACKAGE_INSTALLED_KEY]}
		then
			FROM_CURRENT="$FROM_CURRENT $PACKAGE"
			(( $(echo $FROM_CURRENT | wc -m) < $WIDTH )) && continue
			FROM_CURRENT=$FROM_CURRENT...
			break
		fi
		if dpkg --compare-versions ${PACKAGES_VERSIONS[$PACKAGE_KEY]} gt ${INSTALLED_VERSIONS[$PACKAGE_INSTALLED_KEY]}
		then
			NOT_UPDATED="$NOT_UPDATED $PACKAGE"
			(( $(echo $NOT_UPDATED | wc -m) < $WIDTH )) && continue
			NOT_UPDATED=$NOT_UPDATED...
		fi
		(( $(echo $FROM_OTHER | wc -m) < $WIDTH )) && FROM_OTHER="$FROM_OTHER $PACKAGE"
	done
	SHOW_INSTALLED=$T
	[[ -n $FROM_OTHER ]] && SHOW_INSTALLED=INSTALLED && echo "$T OBSOLETE $T3 $FROM_OTHER"
	[[ -n $NOT_UPDATED ]] && SHOW_INSTALLED=INSTALLED && echo "$T NOT UPDATED $T3 $NOT_UPDATED"
	[[ -n $FROM_CURRENT ]] && echo "$T $SHOW_INSTALLED $T3 $FROM_CURRENT" && continue
	[[ -n $NOT_INSTALLED ]] && echo "$T NOT INSTALLED $T3 $NOT_INSTALLED" && continue
	echo NO PACKAGES
done

aslok
() автор топика
Ответ на: комментарий от aslok

> переложить эту работу на dpkg, раз уж он всё равно в зависимостях )

а вот это очень правильно

mosfet
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.