Я хотел просто вычислить длину строки (это значение хеша). Итак, я открыл терминал и сделал это:
$ apropos length
это вернуло меня с кучей команд / функций, имеющих (3)
или (3ssl)
добавленных в конце их. Теперь человек мужчина дает нам информацию о том, что это section numbers
значит.
3 Library calls (functions within program libraries)
Из любопытства я просто попробовал все эти команды (в надежде, что хотя бы одна из них сработает)
strcspn (3) - get length of a prefix substring
strlen (3) - calculate the length of a string
strnlen (3) - determine the length of a fixed-size string
strspn (3) - get length of a prefix substring
wcslen (3) - determine the length of a wide-character string
wcsnlen (3) - determine the length of a fixed-size wide-character string
и получил только одну и ту же ошибку для каждой команды
$ strnlen HelloWorld
$ strnlen: command not found
Ну, я знаю , как найти длину строки в оболочке , используя wc -m
, expr length
и другие обходные пути.
Но у меня есть 2 вопроса здесь:
- Как использовать любой
library calls (3)
внутри оболочки? - Как рассчитать длину строки, используя только библиотечные вызовы, а не другие команды?
ПРИМЕЧАНИЕ: Вопрос в основном касается library calls
и их использования в оболочке. Это делает первый вопрос более важным для ответа.
Ответы:
Вы, вероятно, не должны этого делать, но можете. Ответ Кусалананды лучше для поставленной задачи и объясняет проблему. Поскольку вы действительно спросили, как использовать любые вызовы библиотеки внутри терминала, есть несколько способов ...
Tiny C Compiler (
tcc
) поддерживает-run
флаг , который позволяет вам (в действительности) истолковать C код, написав небольшую программу, так что вы можете использовать библиотечные вызовы внутри терминала через один вызов этого.Вы можете запустить
strnlen
функцию следующим образом:При этом используется подстановка процессов из Bash, zsh и других оболочек, чтобы дать
tcc
файл для чтения, который, кажется, содержит результаты всехecho
s; есть другие варианты.Вы можете сделать функцию для генерации этого для вас:
(Я использовал
strlen
здесь, чтобы это была унарная функция string-> int - вам понадобится отдельная функция для каждого отдельного арности и возвращаемого типа).Другим вариантом является плагин Bash по Tavis Орманди, который оборачивает и . Это, вероятно, самое близкое приближение к тому, что вы пытались. Вы можете использовать, например:
ctypes.sh
dlopen
dlsym
и он будет вызывать функцию, как и ожидалось.
Это самый прямой способ сделать это «из терминала», но вряд ли это что-то, что входит в ваши дистрибутивные пакеты, поэтому вам придется установить его вручную (что нетривиально). Вот некоторые информативные цитаты
ctypes.sh
с собственного веб-сайта, чтобы дать общее представление о том, как люди относятся к этому:Для других оболочек могут быть подобные инструменты, но я не знаю о них. В теории нет причин, по которым не может быть отдельной команды, которая бы делала это именно для простых случаев, но я несколько удивлен, что не смог найти ее ...
... так что я сделал один!
dlcall
позволяет вызывать библиотечные функции из командной строки :Он поддерживает ограниченный набор прототипов функций, в настоящее время он не очень надежный или отказоустойчивый, но теперь он существует.
Вы также можете использовать, например, Python и
python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world
, но это, конечно, не самый простой способ сделать это. Perl, Ruby и другие языки имеют схожие функции, которые вы можете использовать.Итак, ответы на ваши вопросы:
В общем, вам почти наверняка будет лучше сделать это любым другим способом.
источник
Команда
apropos
полезна во многих отношениях, но она также дает вам много «мусора». Большинство вещей, которые вы перечисляете, - это подпрограммы библиотеки C (для этого предназначен раздел 3 руководства), которые вы не можете использовать непосредственно из оболочки.Чтобы использовать их, вам нужно написать программу на C, которая их вызывает. Это выходит за пределы диапазона тем, охватываемых этим конкретным сайтом (это будет по теме в StackOverflow ).
Таким образом, это ответы на ваши вопросы:
Я знаю, что вы знаете это, но для полноты: в оболочке, если у вас есть строка в переменной
string
, вы можете сделатьЭто напечатает
Length of string "hello world" is 11
в терминале, откуда11
приходит,${#string}
который расширяется до длины строки в$string
.Внутренне оболочка вполне может использовать один из перечисленных вами библиотечных вызовов для расчета длины.
Это наиболее эффективный способ получить длину строки, которая хранится в переменной оболочки, в оболочке.
Обратите внимание также , что
${#string}
является расширительным параметром POSIX оболочки , поэтому переносит между всеми оболочками , которые утверждают , что какая - либо степень соответствия POSIX.источник
printf
. Если вы хотите распечатать его как часть предложения, то это может быть лучшим способом. Но ответ на вопрос "как мне получить длину строки?" это${#string}
часть, а не printf. Вы можете просто,echo ${#string}
если вы просто хотите вывести только длину, или назначить ее другой переменной с помощьюstring_length=${#string}
или что угодно. printf не очень актуаленprintf
я добавить что - то другое , чем просто сказать «использование${#string}
» (что само видно из примера).Я бы не стал делать это просто
strlen()
, но это полезный трюк для того, чтобы иногда попробовать C-код.Вот
gdb
отладчик GNU, и для его отладки обычно требуется имя программы. Поскольку у нас его нет, этот пример дает самому себя отлаживать. Затемstart
запускается программа, и после этогоgdb
ее можно использовать для выполнения произвольного кода Си.источник
Инструмент, который можно использовать для интерактивного вызова функций в общих библиотеках: «Коллекция компиляторов Witchcraft». https://github.com/endrazine/wcc
Со страницы GitHub:
источник