Вы, вероятно, не должны этого делать, но можете. Ответ Кусалананды лучше для поставленной задачи и объясняет проблему. Поскольку вы действительно спросили, как использовать любые вызовы библиотеки внутри терминала, есть несколько способов ...
Tiny C Compiler ( tcc
) поддерживает -run
флаг , который позволяет вам (в действительности) истолковать C код, написав небольшую программу, так что вы можете использовать библиотечные вызовы внутри терминала через один вызов этого.
Вы можете запустить strnlen
функцию следующим образом:
$ tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%i\n", strnlen(argv[1], 1024));}') "Hello world"
11
При этом используется подстановка процессов из Bash, zsh и других оболочек, чтобы дать tcc
файл для чтения, который, кажется, содержит результаты всех echo
s; есть другие варианты.
Вы можете сделать функцию для генерации этого для вас:
call_library_function_s_i() {
func=$1
shift
tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%i\n", '$func'(argv[1]));}') "$*"
}
$ call_library_function_s_i strlen hello world
(Я использовал strlen
здесь, чтобы это была унарная функция string-> int - вам понадобится отдельная функция для каждого отдельного арности и возвращаемого типа).
Другим вариантом является плагин Bash по Tavis Орманди, который оборачивает и . Это, вероятно, самое близкое приближение к тому, что вы пытались. Вы можете использовать, например:ctypes.sh
dlopen
dlsym
$ dlcall -r uint64 strlen "hello world"
и он будет вызывать функцию, как и ожидалось.
Это самый прямой способ сделать это «из терминала», но вряд ли это что-то, что входит в ваши дистрибутивные пакеты, поэтому вам придется установить его вручную (что нетривиально). Вот некоторые информативные цитаты ctypes.sh
с собственного веб-сайта, чтобы дать общее представление о том, как люди относятся к этому:
- "это отвратительно"
- "Это должно прекратиться"
- "ты зашел слишком далеко с этим"
Для других оболочек могут быть подобные инструменты, но я не знаю о них. В теории нет причин, по которым не может быть отдельной команды, которая бы делала это именно для простых случаев, но я несколько удивлен, что не смог найти ее ...
... так что я сделал один! dlcall
позволяет вызывать библиотечные функции из командной строки :
$ dlcall strnlen "hello world" 6
$ dlcall sin 2.5
$ dlcall strchr "hello world" -c ' '
Он поддерживает ограниченный набор прототипов функций, в настоящее время он не очень надежный или отказоустойчивый, но теперь он существует.
Вы также можете использовать, например, Python иpython -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world
, но это, конечно, не самый простой способ сделать это. Perl, Ruby и другие языки имеют схожие функции, которые вы можете использовать.
Итак, ответы на ваши вопросы:
- Используйте один из подходов выше.
- Вы действительно должны использовать другую команду для начальной загрузки вам в библиотеку, или часть программного обеспечения , что крючки в вашу оболочку.
В общем, вам почти наверняка будет лучше сделать это любым другим способом.