Eu queria simplesmente calcular o comprimento de uma string (que é o valor do hash). Então, eu abri o terminal e fiz isso:
$ apropos length
que me devolveu um monte de comandos / funções tendo (3)
ou (3ssl)
acrescentado no final deles. Agora, homem, homem, nos fornece informações sobre o que isso section numbers
significa.
3 Library calls (functions within program libraries)
Por curiosidade, tentei com todos esses comandos (na esperança de que pelo menos um funcionasse)
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
e não obteve nada além do mesmo erro para cada comando
$ strnlen HelloWorld
$ strnlen: command not found
Bem, eu sei como encontrar o comprimento de corda em shell usando wc -m
, expr length
e outras soluções alternativas.
Mas eu tenho 2 perguntas aqui:
- Como usar qualquer
library calls (3)
dentro do shell? - Como calcular o comprimento da string usando apenas chamadas de biblioteca e não outros comandos?
NOTA: A pergunta se concentra em geral library calls
e seu uso no shell. Isso torna a primeira pergunta mais importante para responder.
Respostas:
Você provavelmente não deveria fazer isso, mas pode. A resposta de Kusalananda é melhor para a tarefa em questão e explica a questão. Como você perguntou especificamente como usar qualquer chamada de biblioteca dentro do terminal, aqui estão algumas maneiras ...
O Tiny C Compiler (
tcc
) suporta um-run
sinalizador que permite (com efeito) interpretar o código C escrevendo um pequeno programa, para que você possa usar qualquer chamada de biblioteca dentro do terminal através de uma única chamada.Você pode executar a
strnlen
função assim:Isso usa a substituição de processo do Bash, zsh e outros shells para fornecer
tcc
um arquivo para ler que parece conter os resultados de todos osecho
s; existem outras opções.Você pode criar uma função para gerar isso para você:
(Eu usei
strlen
aqui para que seja uma função unária string-> int - você precisaria de uma função separada para cada tipo de retorno e aridade diferente).Outra opção é o
ctypes.sh
plugin Bash de Tavis Ormandy, que encerradlopen
edlsym
. Esta é provavelmente a aproximação mais próxima do que você estava tentando. Você pode usar, por exemplo:e chamará a função conforme o esperado.
Essa é a maneira mais direta de fazê-lo "a partir do terminal", mas é improvável que seja algo que seus pacotes de distribuição instalem, então você teria que instalá-lo manualmente (o que não é trivial). Aqui estão algumas citações
ctypes.sh
informativas do próprio site para dar uma impressão geral de como as pessoas se sentem ao fazer isso:Pode haver ferramentas semelhantes para outras conchas, mas eu não as conheço. Em teoria, não há razão para que não possa haver um comando independente que faça isso exatamente nos casos simples, mas estou um pouco surpreso por não ter conseguido encontrar um ...
... então eu fiz um!
dlcall
permite chamar funções de biblioteca na linha de comando :Ele suporta um conjunto limitado de protótipos de função, atualmente não é muito confiável ou resistente, mas agora existe.
Você também pode usar, por exemplo, Python e
python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world
, mas certamente não é a maneira mais fácil de fazer isso. Perl, Ruby e outros idiomas têm recursos semelhantes que você pode usar.Portanto, as respostas para suas perguntas são:
Em suma, você quase certamente estará melhor fazendo isso de qualquer outra maneira.
fonte
O
apropos
comando é útil de várias maneiras, mas também oferece muitos "lixo". A maioria das coisas que você lista são rotinas da biblioteca C (é para isso que serve a seção 3 do manual), que você não pode usar diretamente do shell.Para usá-los, você teria que escrever o programa C que os chama. Isso está fora do intervalo de tópicos cobertos por este site específico (estaria no tópico StackOverflow ).
Estas são, portanto, as respostas para suas perguntas:
Eu sei que você sabe disso, mas por uma questão de integridade: No shell, se você tiver uma string em uma variável
string
, poderá fazerIsso será impresso
Length of string "hello world" is 11
no terminal de onde11
vem a${#string}
qual se expande para o comprimento da string$string
.Internamente, o shell pode muito bem estar usando uma das chamadas de biblioteca listadas para fazer o cálculo do comprimento.
Essa é a maneira mais eficiente de obter o comprimento de uma string armazenada em uma variável do shell, no shell.
Observe também que
${#string}
é uma expansão de parâmetro do shell POSIX , portanto é portátil entre todos os shells que reivindicam qualquer grau de conformidade com o POSIX.fonte
printf
aqui. Se você quiser imprimi-lo como parte da frase, essa pode ser a melhor maneira. Mas a resposta para a pergunta "como obtenho o comprimento de uma string?" é a${#string}
parte, não a printf. Você pode fazer isso apenasecho ${#string}
se quiser apenas produzir o comprimento ou atribuí-lo a outra variável comstring_length=${#string}
ou o que quiser. printf não é realmente relevanteprintf
que eu adicionar algo diferente do que simplesmente dizer "use${#string}
" (que é evidente a partir do exemplo).Eu não faria isso apenas
strlen()
, mas é um truque útil para experimentar o código C às vezes.Aqui
gdb
está o depurador GNU, e normalmente seria necessário um nome de programa para depurar depois dele. Como não temos nenhum, este exemplo se dedica a depurar. Em seguida,start
inicia o programa e, depois disso,gdb
pode ser usado para executar código C arbitrário.fonte
Uma ferramenta que pode ser usada para chamar interativamente funções em bibliotecas compartilhadas: a "Coleção Witcher Compiler". https://github.com/endrazine/wcc
Na página do GitHub:
fonte