Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Помогите усовершенствовать скрипт...  (Прочитано 1958 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Tolik_

  • Автор темы
  • Активист
  • *
  • Сообщений: 335
    • Просмотр профиля
В скрипте используется функция которая выполняет проверку на предмет установлен ли пакет в системе или нет и возвращает соответственно результат. До сего времени это было так
function checkPKGinst()
{
if [ -z "$1" ];then
 echo "Аргумент ф-ии {checkPKGinst} имеет нулевую длину."
 return $ERROR
fi
StatusPKG=`dpkg --status $1 | grep "Status: install" | sed -e 's/Status: install //g' |  cut -c1-2`
if [[ "$StatusPKG" = "ok" ]];then
   # Установлен
   return $TRUE
else
   return $FALSE
fi
}
Но хотелось-бы немножко оптимизировать и проверять не по одному пакету, а иногда на вход давать и цепочку "связанных" пакетов разделенных пробелом. Таким образом, если к примеру, хотя бы один из трех пакетов не установлен функция должна вернуть FALSE.
В голову пришло такое
function checkPKGinst()
{
  if [ -z "$1" ];then
echo "Аргумент ф-ии {checkPKGinst} имеет нулевую длину."
return $ERROR
  fi
  STATUS=$TRUE
  declare -a ARRAY=( $1 )
  ELEMENTS=${#ARRAY[@]}
  for (( i=0;i<$ELEMENTS;i++ ));
do
   StatusPKG=`dpkg --status ${ARRAY[${i}]} | grep "Status: install" | sed -e 's/Status: install //g' |  cut -c1-2`
   if [[ "$StatusPKG" != "ok" ]];then
      STATUS=$FALSE
   fi
done
  return $STATUS
}

Но функция не заработала с самого начала. Ну во первых - не получилось что-то с массивом. Строка переданная функции вида "pkg1 pkg2 pkg3 pkg4" стала одним элементом массива, а подразумевалось в массиве будет 4 элемента.
И второе. Посоветуйте. Может как-то можно по другому. Была мысль дать на вход dpkg --status $1 получилось бы такое dpkg --status pkg1 pkg2 pkg3 pkg4. Она в свое время выводит информацию по каждому пакету отдельно. Но как ее разобрать. Подскажите выход пожалуста.
Второй вариант будет гораздо быстрее (поскольку вызовов dpkg будет меньше), но его реализация мне пока даже не приходит в голову.
« Последнее редактирование: 02 Октября 2012, 13:05:26 от Tolik_ »

Оффлайн aSmile

  • Активист
  • *
  • Сообщений: 755
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #1 : 02 Октября 2012, 15:12:38 »
Воркэраунд по второму методу - проверяй не на "ok", а на то, что говорит когда не установлен. Если хоть раз встречается - возвращаешь false.

И сразу вопрос. Если передаешь несколько имен, то они все содержатся в $1 или в $1, $2, $3 и т.д.?

Оффлайн Tolik_

  • Автор темы
  • Активист
  • *
  • Сообщений: 335
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #2 : 02 Октября 2012, 15:45:10 »
они все содержатся в $1 так точно, типа в одной строке, но между названиями пробел.
к примеру взял и набрал в терминале от балды dpkg --status vlc ttt mencoder
получил вывод:
(Нажмите, чтобы показать/скрыть)
каким образом его разобрать?
Я так понимаю информативные 2 строки
Package: vlc
Status: install ok installed
и
Package: mencoder
Status: install ok installed

« Последнее редактирование: 02 Октября 2012, 15:47:48 от Tolik_ »

Оффлайн aSmile

  • Активист
  • *
  • Сообщений: 755
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #3 : 02 Октября 2012, 15:50:37 »
Про $1, я имел ввиду вот это:
function checkPKGinst()
{
if [ -z "$1" ];then
 echo "Аргумент ф-ии {checkPKGinst} имеет нулевую длину."
 return $ERROR
fi
echo $1
}
Что выведет на экран? Все пакеты или только первый? (Ты уже два раза сказал, что там будут все, но меня что-то смущает это)

А по поводу как разбирать, то, например, наличие вот этого
Для проверки файлов архивов используйте команду dpkg --info (dpkg-deb --info),
для вывода списка файлов в них -- команду dpkg--contents (dpkg-deb --contents).
говорит о том, что хотя бы один из списка не установлен.

Оффлайн Tolik_

  • Автор темы
  • Активист
  • *
  • Сообщений: 335
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #4 : 02 Октября 2012, 16:26:21 »
Цитировать
А по поводу как разбирать, то, например, наличие вот этого
Код: [Выделить]

Для проверки файлов архивов используйте команду dpkg --info (dpkg-deb --info),
для вывода списка файлов в них -- команду dpkg--contents (dpkg-deb --contents).

говорит о том, что хотя бы один из списка не установлен.
Ну таки можно сделать проще, ибо эти две строки есть ....
Тогда
if [[ $? -eq 0 ]]; then
   # все пакеты установлены
else
   # имеется не установленный
fi
после комманды dpkg --status $1 > /dev/null 2>&1
но насколько корректно это все будет работать?

Цитировать
Что выведет на экран? Все пакеты или только первый? (Ты уже два раза сказал, что там будут все, но меня что-то смущает это)
выводит все ибо при вызове функции
checkPKGinst "pkg1 pkg2 pkg3" или checkPKGinst "$InpArgs"
это одна строка передаваемая через $1 , хотя если поменять на так
checkPKGinst pkg1 pkg2 pkg3 или checkPKGinst $InpArgs
может и по другому. Но у меня первый вариант.





Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #5 : 03 Октября 2012, 20:49:26 »
Почему-то мне кажется, что опрашивать статус установленного пакета дольше, чем поискать его в списке установленных.
Я бы сделал так:
function check() {
list=" `dpkg -l | sed 's|.\{4\}||;s| .*||'` "
until [ -z "$1" ]; do check=`grep -c " $1 " <<< $list`
if [ $check -eq 0 ]; then return 1; fi
shift
done
}

Оффлайн Tolik_

  • Автор темы
  • Активист
  • *
  • Сообщений: 335
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #6 : 04 Октября 2012, 10:57:12 »
Цитировать
Почему-то мне кажется, что опрашивать статус установленного пакета дольше, чем поискать его в списке установленных.
Была такая мысль, но не стал заморачиваться в виду того, что не было времени на анализ такой ситуации:
К примеру (пока от балды) имеем в списке пакеты tar и tartle. Первые три символа совпадают. Вопрос, какой будет результат grep если пакет tar не установлен? И при поиске сочетания "tar" не попадет-ли "tartle" в список найденных?
Конечно, с использованием shift, реализация интересная но прийдется менять вызовы функции в основной части скрипта. Подумаю над этим, ибо на сей момент у меня список передается в виде символьной строки, получаемой из вне.
« Последнее редактирование: 04 Октября 2012, 11:06:41 от Tolik_ »

Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #7 : 04 Октября 2012, 11:01:24 »
Опробуйте скрипт. Именно для такой ситуации в поиск grep добавляются пробелы в начале имени пакета и в конце.
Те будет искаться " tar ", а это никак не совпадает с " tartle  ".

Оффлайн Tolik_

  • Автор темы
  • Активист
  • *
  • Сообщений: 335
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #8 : 04 Октября 2012, 11:36:37 »
 Vitsliputsli опробовал. Пока не работает именно в том месте где надо. Так в простом варианте типа
 check "vlc" "ark" "firefox" - работает как надо.
 В моем-же случае имеется цикл построчного чтения из файла типа
  while read l; do
  ...
 done < fileRead
 
и скорее всего, вот эта штука
 list=" `dpkg -l | sed 's|.\{4\}||;s| .*||'` "
until [ -z "$1" ]; do check=`grep -c " $1 " <<< $list`
ведет себя некорректно. Более того каждый раз в цикле делать dpkg -l | sed 's|.\{4\}||;s| .*||'  наверное будет не хорошо и затратно, придется подумать и вынести это за рамки общего цикла т.е. наверное
сливать список в отдельный временный файл и grep-ом уже проверять в цикле.

« Последнее редактирование: 04 Октября 2012, 11:53:16 от Tolik_ »

Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #9 : 04 Октября 2012, 13:40:22 »
Цитировать
Более того каждый раз в цикле делать dpkg -l | sed 's|.\{4\}||;s| .*||'  наверное будет не хорошо и затратно,
Отбросить первые 4 символа и найти пробел в строке - не так уж затратно. Неужели так часто будет запускаться эта функция?

Цитировать
ведет себя некорректно
Как именно? У меня работает как надо:
#!/bin/bash
function check() {
list=" `dpkg -l | sed 's|.\{4\}||;s| .*||'` "
until [ -z "$1" ]; do check=`grep -c " $1 " <<< $list`
if [ $check -eq 0 ]; then return 1; fi
shift
done
}

check $@
echo $?

exit 0

если все перечисленный пакеты установлены возвращает 0.
если хотя бы один не установлен возвращает 1.

Оффлайн Tolik_

  • Автор темы
  • Активист
  • *
  • Сообщений: 335
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #10 : 04 Октября 2012, 14:07:09 »
Цитировать
если все перечисленный пакеты установлены возвращает 0.
если хотя бы один не установлен возвращает 1.
блин сам не пойму где грабли если так
#!/bin/bash
TRUE=0
FALSE=1
function checkPKGinst() {
list=" `dpkg -l | sed 's|.\{4\}||;s| .*||'` "
until [ -z "$1" ]; do check=`grep -c " $1 " <<< $list`
if [ $check -eq 0 ]; then return $FALSE; fi
shift
done
}
p1="vlc mencoder ttt"
checkPKGinst $p1
echo "$?"
checkPKGinst "firefox"
echo "$?"
то все работает если брать мою процедуру - нифига не фурычит. Под спойлером кусок кода может где ошибка посмотри
(Нажмите, чтобы показать/скрыть)

вот кусок вывода с теминала с отладочными командами echo $@ и $1
(Нажмите, чтобы показать/скрыть)
и что еще более странное, почему ни разу не сработала until
содержание файла listDPKG.txt
(Нажмите, чтобы показать/скрыть)
« Последнее редактирование: 04 Октября 2012, 14:18:10 от Tolik_ »

Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #11 : 04 Октября 2012, 14:28:12 »
можно еще вот так получить список:
dpkg --get-selections | grep 'install$' | cut -f1тогда там не будет лишнего мусора в начале.

Пользователь решил продолжить мысль 04 Октября 2012, 14:33:17:
Я загонял весь список в переменную, в итоге в ней все идет в одну строку с разделителями пробелами. Если использовать файл, то там каждый пакет на своей строке и искать в нем нужно соответственно.

Пользователь решил продолжить мысль 04 Октября 2012, 14:38:09:
Нельзя менять $1 на другую переменную, я в цикле использую только $1, значения находящиеся в $2 и далее, постепенно присваиваются переменной $1 при использовании команды shift.

Пользователь решил продолжить мысль 04 Октября 2012, 14:43:37:
Т.е. примерно так:
function checkPKGinst() {
echo "Warning! parN=$# par1=$1"
until [ -z "$1" ]; do
 check=`grep -c "^$1$" $SCRIPTDIR/listDPKG.txt`
    if [ $check -eq 0 ]; then return $FALSE; fi
echo "Warning! par=$1"
    shift
 done
return $TRUE
}
« Последнее редактирование: 04 Октября 2012, 14:43:37 от Vitsliputsli »

Оффлайн Tolik_

  • Автор темы
  • Активист
  • *
  • Сообщений: 335
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #12 : 04 Октября 2012, 17:08:30 »
Ну кое что понятно. Такой вариант частично заработал
function chPKGinst()
{
echo "Warning! parN=$@ par1=$1"
until [ -z "$1" ]; do
 check=`grep -c "^$1$" $SCRIPTDIR/listDPKG.txt`
    if [ $check -eq 0 ]; then return $FALSE; fi
    shift
 done
return $TRUE
}

Но остался момент который я совсем не понял. В предыдущем посте я на выхлопе терминала жирным текстом показал, что в функцию передаются не 3 аргумента, а один но вида "pkg1 pkg2 pkg3". И shift тут работать не будет, вернее функция полностью выдаст неверный результат.
Где тут ошибочка кроется?
Может то, что список пакетов в одной строке?
Но вызываю функцию checkPKGinst $ListPkg в надежде, что интерпретатор заменит все это на
checkPKGinst pkg1 pkg2 pkg3, а меняет на checkPKGinst "pkg1 pkg2 pkg3". Как тут по другому поступить и вызвать ф-ю.
« Последнее редактирование: 04 Октября 2012, 17:20:31 от Tolik_ »

Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #13 : 04 Октября 2012, 18:13:24 »
Значит что-то не то в $ListPkg, проверьте что туда записывается и в каком виде.

Оффлайн Tolik_

  • Автор темы
  • Активист
  • *
  • Сообщений: 335
    • Просмотр профиля
Re: Помогите усовершенствовать скрипт...
« Ответ #14 : 04 Октября 2012, 19:31:25 »
Цитировать
Значит что-то не то в $ListPkg, проверьте что туда записывается и в каком виде.
А че там не так. Там все просто, сначала разбирается в цикле построчно файл на поля. Потом уже идет анализ содержимого строки и выполнение определенных действий. Так вот ListPkg это часть строки файла со списком пакетов. По сути это строковая переменная. В принципе я понял. Тут проще всего переделать checkPKGinst
В качестве параметра 1 получаем строку. А дальше
ListPKG=$1
IFS=" "
set -- $ListPKG
until [ -z "$1" ]; do
    check=`grep -c "^$1$" $SCRIPTDIR/listDPKG.txt`
    if [ $check -eq 0 ]; then return $FALSE; fi
    shift
done
так я думаю можно выйти с положения?
« Последнее редактирование: 04 Октября 2012, 19:32:59 от Tolik_ »

 

Страница сгенерирована за 0.02 секунд. Запросов: 21.