Автор Тема: bash-скрипт ldd-requires  (Прочитано 3927 раз)

Оффлайн Антон Мидюков

  • alt linux team
  • ***
  • Сообщений: 5 183
  • antohami@
bash-скрипт ldd-requires
« : 17.06.2015 16:46:16 »
Пришла в голову мысль написать скрипт, который бы облегчил жизнь пользователям, которые пытаются запустить бинарные программы или игры, но не умеют ни фига  ;-) Рабочее название ldd-requires.
Дано: Некий бинарный файл, который требует какие-то библиотеки для своей работы.
Нужно:
1. Определить библиотеки, которых не хватает бинарнику
2. Найти в каких пакетах эти бинарники есть и подсказать пользователю как их установить.

Решение:
1 Необходимо определить какая разрядность ОС пользователя и разрядность бинарника. Тогда получим 4 варианта:
a) 64 битная ОС и 64 битный бинарник;
b) 64 битная ОС и 32 битный бинарник;
c) 32 битная ОС и 32 битный бинарник;
d) 32 битная ОС и 64 битный бинарник.
2. В зависимости от получившегося варианта предложить 4 варианта решения.
2.1 Для a и c вариант простой, можно предложить сделать:
apt-get install библиотека1.so библиотека2.so ...2.2 Для варианта b нужно найти пакеты в которых содержатся эти библиотеки и выбрать пакеты начинающиеся с i586-*. Я сделал так:
... | while read line; do apt-cache search "$line"; done | grep i586| ... 2.3 Для варианта d уведомить пользователя, что файл этот он не сможет запустить.
3. Получился вот такой скрипт:
#!/bin/bash
if [ "`uname -m`" = "x86_64" ]
then
echo -e "У вас 64 битная ОС"
if [[ "`file $1`" =~ "32" ]]
then
echo -e "Файл 32 битный"
echo -e "Идёт поиск пакетов, в которых содержатся необходимые для запуска приложения библиотеки. Это может занять длительное время."
ldd $1 | grep 'not found'| cut -d ' ' -f1 | while read line; do apt-cache search "$line"; done | grep i586 | cut -d ' ' -f1 | tr "\t" " " |echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
else
echo -e "Файл 64 битный"
ldd $1 | grep 'not found'| cut -d ' ' -f1 | tr " \t" " " |echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
fi
else
echo -e "У вас 32 битная система"
if [[ "`file $1`" =~ "32" ]]
then
echo -e "Файл 32 битный"
ldd $1 | grep 'not found'| cut -d ' ' -f1 | tr " \t" " " |echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
else
echo -e "Файл 64 битный. Вы не можете запустить 64 битный файл на 32-битной ОС"
fi
fi

Конвейеры страшно длинные получились  :-( В-общем, прошу советов по окультуриванию кода. А также проверить работоспособность.
« Последнее редактирование: 23.06.2015 00:02:42 от Антон Мидюков »

Оффлайн ASte

  • Мастер
  • ***
  • Сообщений: 1 549
Re: bash-скрипт ldd-info
« Ответ #1 : 17.06.2015 19:25:25 »
натравил на заведомо рабочий бинарник.  получил такой ответ
$ ~/test.sh idlj
У вас 64 битная ОС
Файл 64 битный
Пожалуйста установите следующие библиотеки командой:
 apt-get install
В ощем я понял что он хочет сказать что ничего не нужно.. Но для новичков лучше в этом случае вывести что-то типа "все необходимые пакеты установлены"
« Последнее редактирование: 17.06.2015 19:39:14 от ASte »

Оффлайн ASte

  • Мастер
  • ***
  • Сообщений: 1 549
Re: bash-скрипт ldd-info
« Ответ #2 : 17.06.2015 19:35:24 »
Если натравить скрипт на виндузовый exe-шник
ldd возвращает "не является динамическим исполняемым файлом"
а скрипт просто ничего не находит для установки.
лучше ПМСМ в этом случае вывести то что возвращает ldd

Оффлайн Антон Мидюков

  • alt linux team
  • ***
  • Сообщений: 5 183
  • antohami@
Re: bash-скрипт ldd-info
« Ответ #3 : 18.06.2015 06:53:14 »
Спасибо ASTe! Доработал скрипт с учётом ваших пожеланий. Прошу потестить.

#!/bin/bash
if [ -z "$1" ]
then
echo -e "Отсутствуют аргументы"
else
echo -e 'Список недостающих библиотек:'
ldd $1 | grep 'not found'| cut -d ' ' -f1 | tee $HOME/ldd-info.log
if [ -s $HOME/ldd-info.log ]
then
if [[ "`file $1`" =~ "32" ]]
then
echo -e "Файл 32 битный"
if [ "`uname -m`" = "x86_64" ]
then
echo -e "У вас 64 битная ОС"
echo -e "Идёт поиск пакетов, в которых содержатся необходимые для запуска приложения библиотеки. Это может занять длительное время."
while read line; do apt-cache search "$line"; done < $HOME/ldd-info.log | grep i586 | cut -d ' ' -f1 | tr "\t" " " |echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
else
echo -e "У вас 32 битная система"
cat $HOME/ldd-info.log | tr "\t" " " | echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
fi
elif [[ "`file $1`" =~ "64" ]]
then
echo -e "Файл 64 битный"
if [ "`uname -m`" = "x86_64" ]
then
echo -e "У вас 64 битная ОС"
cat $HOME/ldd-info.log | tr " \t" " " |echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
else
echo -e "Файл 64 битный. Вы не можете запустить 64 битный файл на 32-битной ОС"
fi
else
echo -e "Не является динамическим исполняемым файлом"
fi
else
echo -e "Все библиотеки уже установлены"
fi
fi

Оффлайн ASte

  • Мастер
  • ***
  • Сообщений: 1 549
Re: bash-скрипт ldd-info
« Ответ #4 : 18.06.2015 10:39:03 »
В новой версии про виндузовую программу написал что все библиотеки установлены.
ldd-info.log при этом создается пустой.

Оффлайн Антон Мидюков

  • alt linux team
  • ***
  • Сообщений: 5 183
  • antohami@
Re: bash-скрипт ldd-info
« Ответ #5 : 18.06.2015 13:03:34 »
Поправил косяки:

#!/bin/bash
if [ -z "$1" ]
then
echo -e "Отсутствуют аргументы"
else
if [[ "`file $1`" =~ "32" ]]
then
echo -e 'Список недостающих библиотек:'
ldd $1 | grep "not found" | cut -d " " -f1 | tee $HOME/ldd-info.log
if [ -s $HOME/ldd-info.log ]
then
echo -e "Файл 32 битный"
if [ "`uname -m`" = "x86_64" ]
then
echo -e "У вас 64 битная ОС"
echo -e "Идёт поиск пакетов, в которых содержатся необходимые для запуска приложения библиотеки. Это может занять длительное время."
while read line; do apt-cache search "$line"; done < $HOME/ldd-info.log | grep i586 | cut -d " " -f1 | tr "\t" " " |echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
else
echo -e "У вас 32 битная система"
cat $HOME/ldd-info.log | tr "\t" " " | echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
fi
else
echo -e "Все библиотеки уже установлены"
fi
elif [[ "`file $1`" =~ "64" ]]
then
echo -e 'Список недостающих библиотек:'
ldd $1 | grep "not found" | cut -d " " -f1 | tee $HOME/ldd-info.log
if [ -s $HOME/ldd-info.log ]
then
echo -e "Файл 64 битный"
if [ "`uname -m`" = "x86_64" ]
then
echo -e "У вас 64 битная ОС"
cat $HOME/ldd-info.log | tr " \t" " " |echo -e "Пожалуйста установите следующие библиотеки командой: \n apt-get install `tr "\n" " "`"
else
echo -e "Вы не можете запустить 64 битный файл на 32-битной ОС"
fi
else
echo -e "Все библиотеки уже установлены"
fi
else
echo -e "$1 не является динамическим исполняемым файлом"
fi
fi
« Последнее редактирование: 18.06.2015 14:15:15 от Антон Мидюков »

Оффлайн Антон Мидюков

  • alt linux team
  • ***
  • Сообщений: 5 183
  • antohami@
Re: bash-скрипт ldd-info
« Ответ #6 : 20.06.2015 19:45:32 »
Новую версию скрипта прилагаю в архиве.
Changelog version 0.2:
1. Скрипт очень сильно переработан
2. Скрипт интернационализирован на русский и английский языки
3. Добавлен Makefile, который помимо прочего выполняет рутину по интернационализации
4. Добавлена лицензия на скрипт (GPL2)
5. Добавлен readme_ru.txt

Upd1: Перезалил архив. Поправил косяки в Makefile. Решил вопрос автоматизации рутинных действий при помощи цикла for.
« Последнее редактирование: 22.06.2015 20:27:22 от Антон Мидюков »

Оффлайн Антон Мидюков

  • alt linux team
  • ***
  • Сообщений: 5 183
  • antohami@
Re: bash-скрипт ldd-info
« Ответ #7 : 22.06.2015 20:41:46 »
Подскажите как опакетить можно? Интересует секция %install. Как ему сказать, чтобы make install делал в %Buildroot, а не в корень системы?

Оффлайн ruslandh

  • Поспешай не торопясь !
  • Модератор глобальный
  • *****
  • Сообщений: 32 251
  • Учиться .... Телепатами не рождаются, ими ....
    • Email
Re: bash-скрипт ldd-info
« Ответ #8 : 22.06.2015 21:03:58 »
Это надо смотреть потроха Makefile и т.п.

Оффлайн ASte

  • Мастер
  • ***
  • Сообщений: 1 549
Re: bash-скрипт ldd-info
« Ответ #9 : 22.06.2015 21:20:48 »
install:
for i in $(obj_script); do \
install -v $$i /usr/bin/ ; \
for j in $(obj_locale); do \
install -v locale/$$j/LC_MESSAGES/$$i.mo /usr/share/locale/$$j/LC_MESSAGES/ ;\
done ;\
done
Меня терзают смутные сомнения что пути прописаны где-то тут..
Соответственно нужно или прописать другие пути  или сдедать chroot перед установкой (запуском make install)?
Или я не прав?

Оффлайн Антон Мидюков

  • alt linux team
  • ***
  • Сообщений: 5 183
  • antohami@
Re: bash-скрипт ldd-info
« Ответ #10 : 22.06.2015 21:24:16 »
Вот такие потроха:

obj_locale = ru en
obj_script = ldd-requires
all:

install:
for i in $(obj_script); do \
install -v $$i /usr/bin/ ; \
for j in $(obj_locale); do \
install -v locale/$$j/LC_MESSAGES/$$i.mo /usr/share/locale/$$j/LC_MESSAGES/ ;\
done ;\
done

uninstall:
for i in $(obj_script); do \
rm -fv /usr/bin/$$i; \
for j in $(obj_locale); do \
rm -fv /usr/share/locale/$$j/LC_MESSAGES/$$i.mo; \
done ;\
done

gen_pot:
for i in $(obj_script); do \
xgettext --from-code=utf-8 -L shell -o $$i.pot $$i; \
done

msgmerge: gen_pot
for i in $(obj_script); do \
for j in $(obj_locale); do \
msgmerge -U $$i-of-$$j.po $$i.pot ;\
done ;\
done

msginit: gen_pot
for i in $(obj_script); do \
msginit -i $$i.pot -o $$i-of-$1.po;\
done

msgfmt:
for i in $(obj_script); do \
for j in $(obj_locale); do \
msgfmt $$i-of-$$j.po -o $$i-of-$$j.mo;\
mv $$i-of-$$j.mo locale/$$j/LC_MESSAGES/$$i.mo;\
done ;\
done

Циклы ввёл для универсализации, чтоб можно было этот Makefile применять для любых bash-скриптов с интернационализацией. Для этого достаточно поменять значения переменных obj_locale и obj_script.

Оффлайн ASte

  • Мастер
  • ***
  • Сообщений: 1 549
Re: bash-скрипт ldd-info
« Ответ #11 : 22.06.2015 21:40:10 »
А %Buildroot передать через через параметр и потом обработать как переменную аналогично obj_script не получится?

Оффлайн ruslandh

  • Поспешай не торопясь !
  • Модератор глобальный
  • *****
  • Сообщений: 32 251
  • Учиться .... Телепатами не рождаются, ими ....
    • Email
Re: bash-скрипт ldd-info
« Ответ #12 : 22.06.2015 21:40:25 »
/usr/bin/ и другие абсолютные пути надо поменять на переменные, типа $bindir и т.п.  ну переменным можно присвоить любое нужное значение.

Оффлайн ruslandh

  • Поспешай не торопясь !
  • Модератор глобальный
  • *****
  • Сообщений: 32 251
  • Учиться .... Телепатами не рождаются, ими ....
    • Email
Re: bash-скрипт ldd-info
« Ответ #13 : 22.06.2015 21:48:56 »
%Buildroot передать через через парамет
Так нет в этом файле никаких параметров. вот если было-бы:
bindir=%Buildroot/usr/binтогда-бы было можно.

Оффлайн Skull

  • Глобальный модератор
  • *****
  • Сообщений: 19 916
    • Домашняя страница
    • Email
Re: bash-скрипт ldd-info
« Ответ #14 : 22.06.2015 22:02:40 »
Обычно в Makefile ставят $(DESTDIR):
mkdir -p $(DESTDIR)/usr/share...
В спеке обычно используется макрос %makeinstall_std, который вызывает %make_install install DESTDIR=%buildroot
Андрей Черепанов (cas@)