Сценарий на языке командного интерпретатора представляет собой текстовый файл со списком команд, подлежащих выполнению в пакетном режиме.
Достаточное количество программного обеспечения в системе написано на языке командного интерпретатора и представлено сценариями в каталогах /usr/bin и /bin.
Сценарии неотличимы от любых других программ и доступны пользователями как внешние команды, формируя таким образом «расширения», операционной системы.
Пользователи, расширяющие таким образом операционную систему за счет собственных сценариев, располагают их обычно в каталоге ∼/bin и наделяют правом исполнения.
Аналогично, «локальные» расширения, выполняемые системными администраторами для всех пользователей операционной системы, располагаются в /usr/local/bin.
В листинге ниже приведен сценарий ldr (loader requirements), обратный утилите ldd (loader dependencies); Если при помощи ldd можно увидеть библиотеки, от которых зависит заданная программа, то сценарий Idr, наоборот, показывает программу, использующую заданную библиотеку .
В сценарии объявлена функция usage, формирующая сообщение пользователю о правильных параметрах запуска сценария и использующаяся при некорректно заданных параметрах.
В соответствии с соглашениями о выводе сообщение об «ошибке» перенаправлено на поток stderr при помощи перенаправления потока stdin конструкцией [n]>&n. По соглашению о статусе завершения с «ошибкой» встроенная команда exit возвращает ненулевое значение.
Корректность параметра $1 — имени искомой библиотеки — проверяется на «пустоту» при помощи «красивой» формы [ команды test.
Сам сценарий выполняется следующим образом: сначала переменной ldpath присваивается список имен каталогов, используемых динамическим компоновщиком ld.so для поиска библиотек. Для этого из конфигурационных файлов компоновщика /etc/ld.so.conf.d/*.conf фильтруются строки, незакоммен-тированные символом #.
Затем, в зависимости от формы задания имени целевой библиотеки, переменной what присваивается имя ее файла.
Если библиотека была сразу задана абсолютным путевым именем своего файла, соответствующим шаблонному выражению /*/lib*.so.[0-9], то оно используется непосредственно.
Если библиотека была задана «предметным» именем name, то при помощи команды find организуется поиск абсолютного путевого имени файла библиотеки по шаблону libNAME.so.[0-9] в каталогах компоновщика ld.so, перечисленных в переменной $ldpath, а найденное имя присваивается переменной what.
Корректность результата «вычисления» имени файла библиотеки $what проверяется при помощи «красивой» формы [ команды test на предмет существования (-f) такого файла.
На очередном шаге сценария переменной where присваивается список каталогов (перечисленных в переменной окружения path), содержащих «доступные» пользователю исполняемые файлы программ.
Для этого при помощи транслитератора tr символы-разделители PATH-списка — двоеточия заменяются требуемыми символами-разделителями — пробелами.
Сценарий поиска программ, использующих указанную библиотеку
bender@ubuntu:~$ cd bin
bender@ubuntu: ~/bin$ cat ldr
#!/bin/sh
usage() {
echo «Usage: $(basename $0) name | /.. ./libnane.so.0» >&2
exit 1
}
[ -z «$1» ] && usage
ldpath=$(grep -h /etc/ld.so.conf.d/*.conf)
case $1 in
/*/lib*.so.[0-9]) what=$1;;
*) what=$(find $ldpath -name «lib$1.so.[0-9]» 2>/dev/null);;
esac
if ! [ -f «Swhat» ]
then
echo «Library $1 is not found in» $LDPATH»
usage
fi
where=$(printenv PATH | tr ‘:’ ‘ ‘)
find $where -type f |
xargs file -L |
grep ’:.*ELF’ |
cut -f 1 -d : |
while read exe
do
ldd $exe | grep -q $what && echo $exe
done
Целевая работа сценария выполняется одним конвейером в, в котором при помощи find ищутся регулярные файлы (-type f) в каталогах $where, список имен которых при помощи xargs передается для классификации file.
Построенный классификатор имя: класс фильтруется при помощи grep, из которого затем отделяются имена посредством cut.
Последняя команда конвейера— составной список while циклично перебирает имена файлов, считывая их встроенной командой read в переменную exe, где на каждой итерации цикла проверяется зависимость исполняемого файла $exe от заданной библиотеки.
Зависимость устанавливается по факту успешного завершения grep, определяющего только наличие (-q) в выводе ldd строки с именем путевого файла $what.
Утилита ldd и сценарий ldr
bender@ubuntu:~$ ldr gtk-3
/usr/sbin/unlty-greeter /usr/bin/gnome-session
/usr/games/sol
bender@ubuntu:~$ ldd /usr/games/sol
linux-gate.so.1 => (0xb76f6000)
libgtk-3.so.0 => /usr/lib/l386-linux-gnu/libgtk-3.so.0 (0xb6fd3000)
libexpat.so.1 => /lib/i386-linux-gnu/libexpat.so.1 (0xb62a0000)
bender@ubuntu:~$ ldr pthread | wc -l
991