Chciałem po prostu obliczyć długość łańcucha (to jest wartość skrótu). Otworzyłem terminal i zrobiłem to:
$ apropos length
które zwróciło mi zestaw poleceń / funkcji posiadających (3)
lub (3ssl)
dołączonych na końcu. Teraz człowiek człowiek przekazuje nam informacje o ich section numbers
znaczeniu.
3 Library calls (functions within program libraries)
Z ciekawości właśnie wypróbowałem wszystkie te polecenia (mam nadzieję, że przynajmniej jedno zadziała)
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
i otrzymywał tylko ten sam błąd dla każdego polecenia
$ strnlen HelloWorld
$ strnlen: command not found
Dobrze wiem, jak znaleźć długość ciągu w powłoce użyciu wc -m
, expr length
oraz inne rozwiązania.
Ale mam tutaj 2 pytania:
- Jak korzystać z dowolnej
library calls (3)
powłoki? - Jak obliczyć długość łańcucha przy użyciu samych wywołań biblioteki, a nie innych poleceń?
UWAGA: Pytanie dotyczy ogólnie library calls
i ich użycia w powłoce. Dlatego ważniejsze jest udzielenie odpowiedzi na pierwsze pytanie.
Odpowiedzi:
Prawdopodobnie nie powinieneś tego robić, ale możesz. Odpowiedź Kusalanandy jest lepsza dla danego zadania i wyjaśnia problem. Ponieważ pytałam konkretnie jak używać żadnych połączeń biblioteki wewnątrz terminalu, chociaż, oto kilka sposobów ...
Tiny C Compiler (
tcc
) obsługuje-run
flagę , która pozwala (w efekcie) interpretowania kodu C pisząc mały program, dzięki czemu można korzystać z żadnych połączeń biblioteki wewnątrz terminala za pomocą jednego wywołania tego.Możesz uruchomić następującą
strnlen
funkcję:Używa podstawienia procesów z Bash, zsh i innych powłok, aby dać
tcc
plik do odczytu, który wydaje się zawierać wyniki wszystkichecho
s; są inne opcje.Możesz stworzyć funkcję, która wygeneruje to dla Ciebie:
(Użyłem
strlen
tutaj, aby była to jednoargumentowa funkcja string-> int - potrzebujesz osobnej funkcji dla każdego innego arity i typu zwracanego).Inną opcją jest Bash plugin przez Tavis Ormandy, który owija się i . Jest to prawdopodobnie najbliższe przybliżenie do tego, czego próbujesz. Możesz użyć na przykład:
ctypes.sh
dlopen
dlsym
i wywoła funkcję zgodnie z oczekiwaniami.
Jest to najbardziej bezpośredni sposób na zrobienie tego „z terminala”, ale jest mało prawdopodobne, aby był to pakiet twoich pakietów dystrybucyjnych, więc będziesz musiał zainstalować go ręcznie (co nie jest łatwe). Oto kilka ciekawych cytatów z
ctypes.sh
własnej strony internetowej, które dają ogólne wrażenie na temat tego, jak ludzie to robią:Mogą istnieć podobne narzędzia do innych powłok, ale nie wiem o nich. Teoretycznie nie ma powodu, aby nie istniało samodzielne polecenie, które zrobiłoby to dokładnie w prostych przypadkach, ale jestem nieco zaskoczony, że nie udało mi się znaleźć jednego ...
... więc zrobiłem jeden!
dlcall
pozwala wywoływać funkcje biblioteczne z wiersza poleceń :Obsługuje ograniczony zestaw prototypów funkcji, obecnie nie jest strasznie niezawodny ani odporny, ale teraz istnieje.
Możesz także użyć na przykład Pythona i
python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world
, ale z pewnością nie jest to najłatwiejszy sposób. Perl, Ruby i inne języki mają podobne funkcje, których możesz użyć.Odpowiedzi na twoje pytania to:
Podsumowując, prawie na pewno lepiej będzie robić to w jakikolwiek inny sposób.
źródło
apropos
Polecenie jest przydatne na wiele sposobów, ale to nie daje dużo „śmieci” też. Większość rzeczy, które wymieniasz, to procedury biblioteki C (do tego służy sekcja 3 instrukcji), których nie możesz używać bezpośrednio z powłoki.Aby z nich skorzystać, trzeba napisać program w języku C, który je wywołuje. To wykracza poza zakres tematów omawianych w tej konkretnej witrynie (byłoby na ten temat na StackOverflow ).
Oto zatem odpowiedzi na twoje pytania:
Wiem, że o tym wiesz, ale ze względu na kompletność: w powłoce, jeśli masz ciąg w zmiennej
string
, możesz to zrobićSpowoduje to wydrukowanie
Length of string "hello world" is 11
w terminalu, z którego11
pochodzi, z${#string}
którego rozwija się do długości łańcucha$string
.Wewnętrznie powłoka może z powodzeniem wykorzystywać jedno z wywołań biblioteki, które wymieniono w celu obliczenia długości.
Jest to najbardziej efektywny sposób na uzyskanie długości ciągu przechowywanego w zmiennej powłoki, w powłoce.
Zauważ też, że
${#string}
jest to rozszerzenie parametrów powłoki POSIX , dlatego jest przenośne między wszystkimi powłokami, które twierdzą, że są w jakimkolwiek stopniu zgodne z POSIX.źródło
printf
. Jeśli chcesz wydrukować go jako część zdania, może to być najlepszy sposób. Ale odpowiedź na pytanie „jak uzyskać długość łańcucha?” jest${#string}
częścią, a nie printf. Możesz po prostu,echo ${#string}
jeśli chcesz wyprowadzić tylko długość lub przypisać ją do innej zmiennej za pomocąstring_length=${#string}
lub cokolwiek chcesz. printf nie jest tak naprawdę istotnyprintf
dodam coś innego niż po prostu powiedzieć „użytkowania${#string}
” (co jest oczywiste z przykładu).Nie zrobiłbym tego po prostu
strlen()
, ale czasami jest to przydatna sztuczka do wypróbowania kodu C.Oto
gdb
debuger GNU, który normalnie potrzebowałby nazwy programu do debugowania po nim. Ponieważ go nie mamy, ten przykład sam się debuguje. Następniestart
uruchamia program, a następniegdb
można go użyć do wykonania dowolnego kodu C.źródło
Narzędzie, które można wykorzystać do interaktywnego wywoływania funkcji we współdzielonych bibliotekach: „Witchcraft Compiler Collection”. https://github.com/endrazine/wcc
Ze strony GitHub:
źródło