Simplemente quería calcular la longitud de una cadena (que es el valor hash). Entonces, abrí la terminal e hice esto:
$ apropos length
eso me devolvió con un montón de comandos / funciones que tienen (3)
o (3ssl)
anexados al final de ellos. Ahora hombre hombre nos da información sobre lo que section numbers
significan.
3 Library calls (functions within program libraries)
Por curiosidad, acabo de probar con todos estos comandos (con la esperanza de que al menos uno funcione)
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
y obtuve nada más que el mismo error para cada comando
$ strnlen HelloWorld
$ strnlen: command not found
Bueno, sé cómo encontrar la longitud de la cadena en la cáscara utilizando wc -m
, expr length
y otras soluciones.
Pero, tengo 2 preguntas aquí:
- ¿Cómo usar alguno
library calls (3)
dentro del caparazón? - ¿Cómo calcular la longitud de la cadena usando solo llamadas de la biblioteca y no otros comandos?
NOTA: La pregunta se centra en general library calls
y su uso en el shell. Eso hace que la primera pregunta sea más importante de responder.
Respuestas:
Probablemente no deberías hacer esto, pero puedes. La respuesta de Kusalananda es mejor para la tarea en cuestión y explica el problema. Sin embargo, dado que usted preguntó específicamente cómo usar las llamadas a la biblioteca dentro del terminal, aquí hay algunas maneras ...
El Compilador Tiny C (
tcc
) admite un-run
indicador que le permite (en efecto) interpretar el código C escribiendo un pequeño programa, para que pueda usar cualquier llamada a la biblioteca dentro del terminal a través de una sola invocación de eso.Puede ejecutar la
strnlen
función de esta manera:Esto utiliza la sustitución de procesos de Bash, zsh y otros shells para proporcionar
tcc
un archivo para leer que parece contener los resultados de todos losecho
s; Hay otras opciones.Podría hacer una función para generar esto para usted:
(Lo he usado
strlen
aquí para que sea una función unaria string-> int: necesitaría una función separada para cada arity y tipo de retorno diferentes).Otra opción es el
ctypes.sh
complemento Bash de Tavis Ormandy, que finalizadlopen
ydlsym
. Esta es probablemente la aproximación más cercana a lo que estaba intentando. Puedes usar, por ejemplo:y llamará a la función como se esperaba.
Esta es la forma más directa de hacerlo "desde el terminal", pero es poco probable que sea algo que su distribución empaquete, por lo que tendría que instalarlo manualmente (lo cual no es trivial). Aquí hay algunas citas
ctypes.sh
informativas del propio sitio web para dar una impresión general de cómo se siente la gente al hacer esto:Puede haber herramientas similares para otros proyectiles, pero no los conozco. En teoría, no hay razón para que no haya un comando independiente que haga esto exactamente para los casos simples, pero estoy algo sorprendido de que no haya podido encontrar uno ...
... así que hice uno!
dlcall
le permite llamar a funciones de biblioteca desde la línea de comandos :Admite un conjunto limitado de prototipos de funciones, actualmente no es terriblemente confiable ni resistente, pero ahora existe.
También podría usar, por ejemplo, Python y
python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world
, pero ciertamente no es la forma más fácil de hacerlo. Perl, Ruby y otros idiomas tienen características similares que podrías usar.Entonces las respuestas a sus preguntas son:
Con todo, seguramente será mejor que hagas esto de otra manera.
fuente
El
apropos
comando es útil de muchas maneras, pero también le da mucha "basura". La mayoría de las cosas que enumera son rutinas de biblioteca C (para esto es para la sección 3 del manual), que no puede usar directamente desde el shell.Para usarlos, tendría que escribir un programa en C que los llame. Esto queda fuera del rango de temas cubiertos por este sitio en particular (sería sobre el tema en StackOverflow ).
Estas, por lo tanto, son las respuestas a sus preguntas:
Sé que sabes esto, pero por razones de integridad: en el shell, si tienes una cadena en una variable
string
, puedes hacerEsto se imprimirá
Length of string "hello world" is 11
en el terminal de donde11
viene el${#string}
que se expande a la longitud de la cadena$string
.Internamente, el shell puede estar usando una de las llamadas de la biblioteca que usted enumeró para hacer su cálculo de longitud.
Esta es la forma más eficiente de obtener la longitud de una cadena que se almacena en una variable de shell, en el shell.
Tenga en cuenta también que
${#string}
es una expansión de parámetros de shell POSIX , por lo tanto, es portátil entre todos los shells que afirman cualquier grado de cumplimiento POSIX.fuente
printf
aquí. Si desea imprimirlo como parte de la oración, entonces esa podría ser la mejor manera. Pero la respuesta a la pregunta "¿cómo obtengo la longitud de una cuerda?" es la${#string}
parte, no la printf. Puedeecho ${#string}
hacerlo solo si desea generar solo la longitud, o asignarlo a otra variable constring_length=${#string}
o lo que desee. printf no es realmente relevanteprintf
, agrego algo más que solo decir "usar${#string}
" (que es evidente por el ejemplo).No haría esto por solo
strlen()
, pero a veces es un truco útil para probar el código C.Aquí
gdb
está el depurador GNU, y normalmente se necesitaría un nombre de programa para depurarlo. Como no tenemos ninguno, este ejemplo lo da a sí mismo para depurar. Luegostart
inicia el programa, y luegogdb
puede usarse para ejecutar código C arbitrario.fuente
Una herramienta que se puede usar para llamar interactivamente funciones en bibliotecas compartidas: la "Colección del compilador de brujería". https://github.com/endrazine/wcc
Desde la página de GitHub:
fuente