Ich wollte einfach die Länge eines Strings berechnen (das ist ein Hash-Wert). Also öffnete ich das Terminal und tat dies:
$ apropos length
das zurückgegeben mich mit einem Bündel von Befehlen / Funktionen haben , (3)
oder (3ssl)
am Ende von ihnen angehängt. Nun gibt uns der Mensch Auskunft darüber, was diese section numbers
bedeuten.
3 Library calls (functions within program libraries)
Aus Neugier habe ich es nur mit all diesen Befehlen versucht (in der Hoffnung, dass mindestens einer funktionieren würde)
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
und bekam nichts als den gleichen Fehler für jeden Befehl
$ strnlen HelloWorld
$ strnlen: command not found
Nun, ich weiß , wie die Länge der Zeichenfolge in der Schale finden verwenden wc -m
, expr length
und anderen Abhilfen.
Aber ich habe hier 2 Fragen:
- Wie benutzt man jede
library calls (3)
im Inneren der Schale? - Wie berechnet man die Länge eines Strings nur mit Bibliotheksaufrufen und nicht mit anderen Befehlen?
HINWEIS: Fragenschwerpunkte im Allgemeinen library calls
und deren Verwendung in der Shell. Das macht die Beantwortung der ersten Frage wichtiger.
Antworten:
Sie sollten das wahrscheinlich nicht tun, aber Sie können. Kusalanandas Antwort ist besser für die anstehende Aufgabe und erklärt das Problem. Da Sie genau haben fragen , wie zu verwenden , alle innerhalb des Terminals Bibliothek Anrufe, aber hier ein paar Möglichkeiten , ...
Der Tiny C Compiler (
tcc
) unterstützt eine-run
Flagge , die Sie (in der Tat) interpretieren C - Code kann durch ein kleines Programm zu schreiben, so dass Sie kann keine Bibliothek Anrufe innerhalb des Terminals durch einen einzigen Aufruf verwendet diese .Sie können die
strnlen
Funktion folgendermaßen ausführen :Hierbei wird die Prozessersetzung aus Bash, zsh und anderen Shells verwendet, um
tcc
eine zu lesende Datei zu erstellen, die die Ergebnisse allerecho
s zu enthalten scheint . es gibt andere Möglichkeiten.Sie könnten eine Funktion erstellen, um dies für Sie zu generieren:
(Ich habe
strlen
hier verwendet , damit es eine unäre Funktionszeichenfolge ist-> int - Sie benötigen eine separate Funktion für jeden unterschiedlichen arity- und return-Typ.)Eine weitere Option ist die
ctypes.sh
Bash - Plugin von Tavis Ormandy, die einpacktdlopen
unddlsym
. Dies ist wahrscheinlich die beste Annäherung an das, was Sie versucht haben. Sie können zum Beispiel verwenden:und es wird die Funktion wie erwartet aufrufen.
Dies ist der direkteste Weg, dies "vom Terminal aus" zu tun, aber es ist unwahrscheinlich, dass Ihre Distributionspakete installiert werden, sodass Sie es manuell installieren müssen (was nicht trivial ist). Hier sind einige informative Zitate von
ctypes.sh
der eigenen Website , um einen allgemeinen Eindruck davon zu vermitteln, wie sich die Leute dabei fühlen:Es mag ähnliche Werkzeuge für andere Shells geben, aber ich weiß nichts darüber. Theoretisch gibt es keinen Grund, warum es keinen eigenständigen Befehl geben könnte, der dies genau für die einfachen Fälle ausführt, aber ich bin etwas überrascht, dass ich keinen finden konnte ...
... also habe ich eins gemacht!
dlcall
Ermöglicht den Aufruf von Bibliotheksfunktionen über die Befehlszeile :Es unterstützt eine begrenzte Anzahl von Funktionsprototypen, ist derzeit nicht besonders zuverlässig und belastbar, existiert aber jetzt.
Sie könnten zum Beispiel auch Python und verwenden
python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world
, aber es ist sicherlich nicht der einfachste Weg, dies zu tun. Perl, Ruby und andere Sprachen verfügen über ähnliche Funktionen, die Sie verwenden können.Die Antworten auf Ihre Fragen lauten also:
Alles in allem sind Sie mit ziemlicher Sicherheit besser dran, wenn Sie dies auf andere Weise tun.
quelle
Der
apropos
Befehl ist in vielerlei Hinsicht nützlich, aber es gibt Ihnen auch viel "Müll". Die meisten Dinge, die Sie auflisten, sind C-Bibliotheksroutinen (dazu dient Abschnitt 3 des Handbuchs), die Sie nicht direkt über die Shell verwenden können.Um sie zu verwenden, müssten Sie ein C-Programm schreiben, das sie aufruft. Dies liegt außerhalb des Themenspektrums, das von dieser speziellen Site abgedeckt wird (es würde sich um ein Thema bei StackOverflow handeln ).
Dies sind also die Antworten auf Ihre Fragen:
Ich weiß, dass Sie das wissen, aber der Vollständigkeit halber: Wenn Sie in der Shell eine Zeichenfolge in einer Variablen haben
string
, können Sie dies tunDies wird
Length of string "hello world" is 11
in dem Terminal gedruckt, in dem das11
kommt, von${#string}
dem die Länge der Zeichenfolge in erweitert wird$string
.Intern verwendet die Shell möglicherweise einen der von Ihnen aufgelisteten Bibliotheksaufrufe, um ihre Längenberechnung durchzuführen.
Dies ist die effizienteste Methode, um die Länge einer Zeichenfolge abzurufen, die in einer Shell-Variablen in der Shell gespeichert ist.
Beachten Sie auch, dass
${#string}
es sich um eine POSIX-Shell-Parametererweiterung handelt. Sie kann daher zwischen allen Shells übertragen werden, die einen beliebigen Grad an POSIX-Konformität beanspruchen.quelle
printf
werden. Wenn Sie es als Teil eines Satzes ausdrucken möchten, ist dies möglicherweise der beste Weg. Aber die Antwort auf die Frage "Wie bekomme ich die Länge einer Zeichenfolge?" ist das${#string}
Teil, nicht das printf. Sie können nur,echo ${#string}
wenn Sie nur die Länge ausgeben möchten, oder es mit einer anderen Variablen zuweisenstring_length=${#string}
oder was auch immer Sie möchten. printf ist nicht wirklich relevantprintf
füge ich etwas anderes hinzu, als nur "use${#string}
" zu sagen (was aus dem Beispiel klar hervorgeht).Ich würde das nicht einfach so machen
strlen()
, aber es ist manchmal ein nützlicher Trick, um C-Code auszuprobieren.Hier
gdb
ist der GNU-Debugger, nach dem normalerweise ein Programmname zum Debuggen benötigt wird. Da wir keine haben, gibt sich dieses Beispiel zum Debuggen. Dannstart
wird das Programm gestartet und danachgdb
verwendet werden kann beliebigen C - Code auszuführen.quelle
Ein Tool, mit dem Funktionen in gemeinsam genutzten Bibliotheken interaktiv aufgerufen werden können: die "Witchcraft Compiler Collection". https://github.com/endrazine/wcc
Von der GitHub Seite:
quelle