Чтобы узнать, какие динамические библиотеки экспортируют какой символ в системе GNU, вы можете попробовать что-то вроде:
ldconfig -p |
sed -n 's/.* => //p' |
sort -u |
xargs -d '\n' nm --defined-only -oDg |
grep -w getpid
(в первом приближении; это можно улучшить, удалив дубликаты на уровне inode ).
Нечто подобное можно сделать со статическими библиотеками или любым ELF или другим объектом, поддерживаемым nm
, хотя вам может потребоваться адаптировать флаги и способ сбора списка файлов, в которых вы хотите выполнить поиск.
Однако здесь NLMSG_DATA
в верхнем регистре, скорее всего, является макросом препроцессора C.
$ grep -r NLMSG_DATA /usr/include
/usr/include/linux/netlink.h:#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
Для поиска определений в заголовках C вместо grep
вы можете использовать некоторые инструменты индексации кода, такие как ctags
, cscope
или gtags
, и проиндексировать весь /usr/include
.
Вы также можете получить процессор C pre -, чтобы расширить его:
printf '%s\n' '#include <linux/netlink.h>' 'please_describe[NLMSG_DATA(nlh)]' |
gcc -P -E -x c - | sed '/please_describe/,$!d'
please_describe[((void*)(((char*)nlh) + ((0) + ((int) ( ((sizeof(struct nlmsghdr))+4U -1) & ~(4U -1) )))))]
Таким образом, он просто возвращает указатель, смещенный относительно входного указателя на основе размера struct nlmsghdr
(, который можно определить с помощью компилятора C или символов отладки некоторого объекта, который использует этотstruct
).
Обратите внимание, что заголовки нужны не для запуска программного обеспечения, а только для их сборки, они не будут установлены по умолчанию для всех библиотек, поэтому вам может потребоваться установить некоторые пакеты xxx-dev
или xxx-devel
, чтобы добавить их.
Если у вас есть справочная страница для библиотечной функции (, здесь она не применима, так как это какой-то API ядра ), скорее всего, у вас также есть заголовочные файлы. Вы можете перейти от справочной страницы к пакету, а затем к заголовкам и библиотеке. Например, в Debian и производных для функции attr_setf
:
$ man -w attr_setf
/usr/share/man/man3/attr_set.3.gz
$ dpkg -S /usr/share/man/man3/attr_set.3.gz
libattr1-dev:amd64: /usr/share/man/man3/attr_set.3.gz
$ dpkg -L libattr1-dev | grep /include/
/usr/include/attr
/usr/include/attr/attributes.h
/usr/include/attr/error_context.h
/usr/include/attr/libattr.h
/usr/include/attr/xattr.h
Для библиотек вы можете предположить, что пакет libattr1
или использовать тот факт, что пакет -dev
будет зависеть от пакета времени выполнения:
$ apt-cache show libattr1-dev | grep Depends
Depends: libc6-dev | libc-dev, libattr1 (= 1:2.4.47-2build1)
$ dpkg -L libattr1 | grep /lib/
/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu/libattr.so.1.1.0
/lib/x86_64-linux-gnu/libattr.so.1
$ nm -Dg /lib/x86_64-linux-gnu/libattr.so.1 | grep attr_setf
00000000000016e0 T attr_setf
Если у вас нет справочной страницы, но вы знаете, что она существует,вы можете посмотреть -, какой пакет доступен из:
$ apt-file search -x 'man.*/attr_set\.\d'
libattr1-dev: /usr/share/man/man3/attr_set.3.gz
ncurses-doc: /usr/share/man/man3/attr_set.3ncurses.gz
Если вы используете bash
,тогда шаблон !(*high*)
будет соответствовать всем именам в текущем каталоге, которые не содержат строку high
, если установлена опция оболочки extglob
:
$ shopt -s extglob
$ ls
1 2 3 4-high
$ ls -d -- !(*high*)
1 2 3
Затем мы можем перебрать имена, соответствующие этому шаблону, переименовав каждое совпадающее имя:
shopt -s extglob nullglob
for name in !(*high*); do
[[ ! -f $name ]] && continue
mv -- "$name" "high-$name"
done
Здесь происходит то, что мы устанавливаем extglob
, а такжеnullglob
(заставляем шаблон подстановки исчезать, а не сохраняться, как -, если шаблон не соответствует )перед циклом. Вы также можете включить dotglob
, если хотите также переименовывать скрытые имена.
Затем цикл пропускает любое имя, которое не относится к обычному файлу (это может быть имя каталога, например ), а затем вставляет строку high-
перед именем с mv
.
Параметр --
в команде mv
позволяет избежать ошибочной интерпретации любых имен файлов, начинающихся с дефиса, как набора параметров.
Запуск на наборе тестовых файлов:
$ ls
1 2 3 4-high
Просто вставьте код сверху прямо в оболочку:
$ shopt -s extglob nullglob
$
$ for name in !(*high*); do
> [[ ! -f $name ]] && continue
>
> mv -- "$name" "high-$name"
> done
$ ls
4-high high-1 high-2 high-3
Вы также можете использовать утилиту Perl rename
следующим образом:
shopt -s extglob
rename -v 'if (-f) { s/^/high-/ }' -- !(*high*)
Это переместит проверку -f
цикла в первом варианте этого ответа на Perl, но по-прежнему будет использовать тот же шаблон подстановки имен файлов для выбора файлов для переименования. -f
переименование затрагивает только обычные файлы (без каталогов и т. д.)
Вариантом, который не зависит от расширенных шаблонов подстановки в оболочке, будет
rename -v 'if (-f && !/high/) { s/^/high-/ }' -- *
Это просто проверяет, содержит ли имя уже строку high
внутри вызова rename
, и пропускает переименование файла, если оно происходит. Глоб *
выбирает все файлы в текущем каталоге (, кроме скрытых ).
Если у вас есть GNU Parallel:
parallel mv {} '{= /high/ or $_="high$_" =}' ::: *
Сzsh
:
autoload zmv # best in ~/.zshrc
zmv '^*high*' 'high-$f'
С корпусом -нечувствительное согласование:
zmv '^*(#i)high*' 'high-$f'