How to execute library commands from the shell?












25














I wanted to simply calculate the length of a string (that is hash value). So, I opened terminal and did this:



$ apropos length


that returned me with a bunch of commands/functions having (3) or (3ssl) appended at the end of them. Now man man gives us information about what these section numbers mean.



3   Library calls (functions within program libraries)


Out of curiosity, I just tried with all these commands (in hope at least one would work)



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


and got nothing but same error for every command



$ strnlen HelloWorld 
$ strnlen: command not found


Well, I know how to find length of string in shell using wc -m , expr length and other workarounds.



But, I have 2 questions here :




  1. How to use any library calls (3) inside the shell?

  2. How to calculate string length using just library calls and not other commands?


NOTE : Question focuses in general library calls and their usage in the shell. That makes first question more important to answer.










share|improve this question
























  • stackoverflow.com/q/49719554/841108 is a near duplicate
    – Basile Starynkevitch
    Apr 8 at 17:01








  • 4




    Basically, though Michael's answer is a great hack, the straightforward answer is: you don't. Library calls are not related to the shell. They are used for writing programs in C language. — More generally, when reading manpages, unless you're coding a program, just ignore sections 2, 3 and 9.
    – spectras
    Apr 8 at 21:04












  • Off Topic, but OpenVMS has "lexical" functions which are shell interfaces to a great deal of system library functions.
    – RonJohn
    Apr 9 at 0:06
















25














I wanted to simply calculate the length of a string (that is hash value). So, I opened terminal and did this:



$ apropos length


that returned me with a bunch of commands/functions having (3) or (3ssl) appended at the end of them. Now man man gives us information about what these section numbers mean.



3   Library calls (functions within program libraries)


Out of curiosity, I just tried with all these commands (in hope at least one would work)



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


and got nothing but same error for every command



$ strnlen HelloWorld 
$ strnlen: command not found


Well, I know how to find length of string in shell using wc -m , expr length and other workarounds.



But, I have 2 questions here :




  1. How to use any library calls (3) inside the shell?

  2. How to calculate string length using just library calls and not other commands?


NOTE : Question focuses in general library calls and their usage in the shell. That makes first question more important to answer.










share|improve this question
























  • stackoverflow.com/q/49719554/841108 is a near duplicate
    – Basile Starynkevitch
    Apr 8 at 17:01








  • 4




    Basically, though Michael's answer is a great hack, the straightforward answer is: you don't. Library calls are not related to the shell. They are used for writing programs in C language. — More generally, when reading manpages, unless you're coding a program, just ignore sections 2, 3 and 9.
    – spectras
    Apr 8 at 21:04












  • Off Topic, but OpenVMS has "lexical" functions which are shell interfaces to a great deal of system library functions.
    – RonJohn
    Apr 9 at 0:06














25












25








25


3





I wanted to simply calculate the length of a string (that is hash value). So, I opened terminal and did this:



$ apropos length


that returned me with a bunch of commands/functions having (3) or (3ssl) appended at the end of them. Now man man gives us information about what these section numbers mean.



3   Library calls (functions within program libraries)


Out of curiosity, I just tried with all these commands (in hope at least one would work)



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


and got nothing but same error for every command



$ strnlen HelloWorld 
$ strnlen: command not found


Well, I know how to find length of string in shell using wc -m , expr length and other workarounds.



But, I have 2 questions here :




  1. How to use any library calls (3) inside the shell?

  2. How to calculate string length using just library calls and not other commands?


NOTE : Question focuses in general library calls and their usage in the shell. That makes first question more important to answer.










share|improve this question















I wanted to simply calculate the length of a string (that is hash value). So, I opened terminal and did this:



$ apropos length


that returned me with a bunch of commands/functions having (3) or (3ssl) appended at the end of them. Now man man gives us information about what these section numbers mean.



3   Library calls (functions within program libraries)


Out of curiosity, I just tried with all these commands (in hope at least one would work)



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


and got nothing but same error for every command



$ strnlen HelloWorld 
$ strnlen: command not found


Well, I know how to find length of string in shell using wc -m , expr length and other workarounds.



But, I have 2 questions here :




  1. How to use any library calls (3) inside the shell?

  2. How to calculate string length using just library calls and not other commands?


NOTE : Question focuses in general library calls and their usage in the shell. That makes first question more important to answer.







shell libraries






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 16 at 4:24









Rui F Ribeiro

38.9k1479129




38.9k1479129










asked Apr 8 at 8:15









C0deDaedalus

450412




450412












  • stackoverflow.com/q/49719554/841108 is a near duplicate
    – Basile Starynkevitch
    Apr 8 at 17:01








  • 4




    Basically, though Michael's answer is a great hack, the straightforward answer is: you don't. Library calls are not related to the shell. They are used for writing programs in C language. — More generally, when reading manpages, unless you're coding a program, just ignore sections 2, 3 and 9.
    – spectras
    Apr 8 at 21:04












  • Off Topic, but OpenVMS has "lexical" functions which are shell interfaces to a great deal of system library functions.
    – RonJohn
    Apr 9 at 0:06


















  • stackoverflow.com/q/49719554/841108 is a near duplicate
    – Basile Starynkevitch
    Apr 8 at 17:01








  • 4




    Basically, though Michael's answer is a great hack, the straightforward answer is: you don't. Library calls are not related to the shell. They are used for writing programs in C language. — More generally, when reading manpages, unless you're coding a program, just ignore sections 2, 3 and 9.
    – spectras
    Apr 8 at 21:04












  • Off Topic, but OpenVMS has "lexical" functions which are shell interfaces to a great deal of system library functions.
    – RonJohn
    Apr 9 at 0:06
















stackoverflow.com/q/49719554/841108 is a near duplicate
– Basile Starynkevitch
Apr 8 at 17:01






stackoverflow.com/q/49719554/841108 is a near duplicate
– Basile Starynkevitch
Apr 8 at 17:01






4




4




Basically, though Michael's answer is a great hack, the straightforward answer is: you don't. Library calls are not related to the shell. They are used for writing programs in C language. — More generally, when reading manpages, unless you're coding a program, just ignore sections 2, 3 and 9.
– spectras
Apr 8 at 21:04






Basically, though Michael's answer is a great hack, the straightforward answer is: you don't. Library calls are not related to the shell. They are used for writing programs in C language. — More generally, when reading manpages, unless you're coding a program, just ignore sections 2, 3 and 9.
– spectras
Apr 8 at 21:04














Off Topic, but OpenVMS has "lexical" functions which are shell interfaces to a great deal of system library functions.
– RonJohn
Apr 9 at 0:06




Off Topic, but OpenVMS has "lexical" functions which are shell interfaces to a great deal of system library functions.
– RonJohn
Apr 9 at 0:06










4 Answers
4






active

oldest

votes


















38














You probably shouldn't do this, but you can. Kusalananda's answer is better for the task at hand and explains the issue. Since you did ask specifically how to use any library calls inside the terminal, though, here's a few ways...





The Tiny C Compiler (tcc) supports a -run flag that lets you (in effect) interpret C code by writing a small program, so you can use any library calls inside the terminal through a single invocation of that.



You can run the strnlen function like this:



$ tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", strnlen(argv[1], 1024));}') "Hello world"
11


This uses process substitution from Bash, zsh, and other shells to give tcc a file to read that appears to contain the results of all the echos; there are other options.



You could make a function to generate this for you:



call_library_function_s_i() {
func=$1
shift
tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", '$func'(argv[1]));}') "$*"
}
$ call_library_function_s_i strlen hello world


(I've used strlen here so that it's a unary function string->int - you'd need a separate function for each different arity and return type).





Another option is the ctypes.sh Bash plugin by Tavis Ormandy, which wraps up dlopen and dlsym. This is probably the closest approximation to what you were trying. You can use, for example:



$ dlcall -r uint64 strlen "hello world"


and it will call the function as expected.



This is the most direct way to do it "from the terminal", but it's unlikely to be something your distribution packages up so you'd have to install it manually (which is nontrivial). Here are some informative quotes from ctypes.sh's own website to give a general impression of how people feel about doing this:





  • "that's disgusting"

  • "this has got to stop"

  • "you've gone too far with this"




There may be similar tools for other shells, but I don't know about them. In theory there's no reason there couldn't be a standalone command that did this exactly for the simple cases, but I'm somewhat surprised I haven't been able to find one...





... so I made one! dlcall lets you call library functions from the command line:



$ dlcall strnlen "hello world" 6
$ dlcall sin 2.5
$ dlcall strchr "hello world" -c ' '


It supports a limited set of function prototypes, it's not terribly reliable or resilient currently, but it now exists.





You could also use, for example, Python and python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world, but it's certainly not the easiest way to go about it. Perl, Ruby, and other languages have similar features you could use.





So the answers to your questions are:




  1. Use one of the approaches above.

  2. You do need to use another command to bootstrap you into the library, or a piece of software that hooks into your shell.


All in all, you'll almost certainly be better off doing this any other way.






share|improve this answer



















  • 2




    "dlcall" reminds me of (not quite identical) Windows "rundll": support.microsoft.com/en-gb/help/164787/…
    – pjc50
    Apr 9 at 22:03






  • 1




    @pjc50: Public service announcement: rundll32 is not a general purpose tool for calling arbitrary functions. It can only be used to call functions with a given signature. Also, it's not terribly future-proof.
    – Kevin
    Apr 10 at 0:47



















29














The apropos command is useful in many ways, but it does give you a lot of "junk" too. Most of the things that you list are C library routines (this is what section 3 of the manual is for), which you can not use directly from the shell.



To use them, you would have to write C program that calls them. This falls outside of the range of topics covered by this particular site (it would be on topic at StackOverflow).



These, thus, are the answers to your questions:




  1. You can't, they are C library routines.

  2. You can't, unless you write a C program.


I know you know this, but for the sake of completeness: In the shell, if you have a string in a variable string, you may do



string='hello world'
printf 'Length of string "%s" is %dn' "$string" "${#string}"


This will print Length of string "hello world" is 11 in the terminal where the 11 comes from ${#string} which expands to the length of the string in $string.



Internally, the shell may well be using one of the library calls that you listed to do its length calculation.



This is the most efficient way to get the length of a string that is stored in a shell variable, in the shell.



Note too that ${#string} is a POSIX shell parameter expansion, it is therefore portable between all shells that claim any degree of POSIX compliance.






share|improve this answer























  • The parts about the library functions are a good explanation, but the rest of this answer is a bit misleading. OP says "I wanted to simply calculate the length of a string" There's no need to use printf here. If you want to print it out as part of sentence then that might be the best way. But the answer to the question of "how do I get the length of a string?" is the ${#string} part, not the printf. You can just echo ${#string} if you just want to output just the length, or assign it to another variable with string_length=${#string} or whatever you want. printf is not really relevant
    – Adam
    Apr 8 at 18:24






  • 1




    @Adam I have made small modifications to the answer. I think it's pretty clear how to get the length of the string and the user has already said they know how to do it. By using the length of the string with printf I add something other than just saying "use ${#string}" (which is self evident from the example).
    – Kusalananda
    Apr 8 at 18:50





















15














I wouldn't do this for just strlen(), but it is a useful trick for trying out C code sometimes.




user@host:~$ gdb gdb
(gdb) start
Temporary breakpoint 1, ... in main ()
(gdb) print strlen("foobar")
$1 = 6


Here gdb is the GNU debugger, and it would normally take a program name to debug after it. Because we have none, this example gives it itself to debug. Then start starts the program, and after that gdb can be used to execute arbitrary C code.






share|improve this answer

















  • 2




    Nice trick, to use gdb. Yet gdb is part of developer tools, and if you want to use library function, you better prepare to learn to use developer tools.
    – Dudi Boy
    Apr 8 at 19:02



















4














A tool which can be used to interactively call functions in shared libraries: the "Witchcraft Compiler Collection". https://github.com/endrazine/wcc



From the GitHub page:




wsh : The Witchcraft shell



The witchcraft shell accepts ELF shared libraries, ELF ET_DYN executables and Witchcraft Shell Scripts written in Punk-C as an input. It loads all the executables in its own address space and makes their API available for programming in its embedded interpreter. This provides for binaries functionalities similar to those provided via reflection on languages like Java.



Example usage of wsh
The following command loads the /usr/sbin/apache2 executable within wsh, calls the ap_get_server_banner() function within apache to retrieve its banner and displays it within the wsh interpreter.




jonathan@blackbox:~$ wsh /usr/sbin/apache2
> a = ap_get_server_banner()
> print(a)
Apache/2.4.7





share|improve this answer





















    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "106"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f436305%2fhow-to-execute-library-commands-from-the-shell%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    38














    You probably shouldn't do this, but you can. Kusalananda's answer is better for the task at hand and explains the issue. Since you did ask specifically how to use any library calls inside the terminal, though, here's a few ways...





    The Tiny C Compiler (tcc) supports a -run flag that lets you (in effect) interpret C code by writing a small program, so you can use any library calls inside the terminal through a single invocation of that.



    You can run the strnlen function like this:



    $ tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", strnlen(argv[1], 1024));}') "Hello world"
    11


    This uses process substitution from Bash, zsh, and other shells to give tcc a file to read that appears to contain the results of all the echos; there are other options.



    You could make a function to generate this for you:



    call_library_function_s_i() {
    func=$1
    shift
    tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", '$func'(argv[1]));}') "$*"
    }
    $ call_library_function_s_i strlen hello world


    (I've used strlen here so that it's a unary function string->int - you'd need a separate function for each different arity and return type).





    Another option is the ctypes.sh Bash plugin by Tavis Ormandy, which wraps up dlopen and dlsym. This is probably the closest approximation to what you were trying. You can use, for example:



    $ dlcall -r uint64 strlen "hello world"


    and it will call the function as expected.



    This is the most direct way to do it "from the terminal", but it's unlikely to be something your distribution packages up so you'd have to install it manually (which is nontrivial). Here are some informative quotes from ctypes.sh's own website to give a general impression of how people feel about doing this:





    • "that's disgusting"

    • "this has got to stop"

    • "you've gone too far with this"




    There may be similar tools for other shells, but I don't know about them. In theory there's no reason there couldn't be a standalone command that did this exactly for the simple cases, but I'm somewhat surprised I haven't been able to find one...





    ... so I made one! dlcall lets you call library functions from the command line:



    $ dlcall strnlen "hello world" 6
    $ dlcall sin 2.5
    $ dlcall strchr "hello world" -c ' '


    It supports a limited set of function prototypes, it's not terribly reliable or resilient currently, but it now exists.





    You could also use, for example, Python and python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world, but it's certainly not the easiest way to go about it. Perl, Ruby, and other languages have similar features you could use.





    So the answers to your questions are:




    1. Use one of the approaches above.

    2. You do need to use another command to bootstrap you into the library, or a piece of software that hooks into your shell.


    All in all, you'll almost certainly be better off doing this any other way.






    share|improve this answer



















    • 2




      "dlcall" reminds me of (not quite identical) Windows "rundll": support.microsoft.com/en-gb/help/164787/…
      – pjc50
      Apr 9 at 22:03






    • 1




      @pjc50: Public service announcement: rundll32 is not a general purpose tool for calling arbitrary functions. It can only be used to call functions with a given signature. Also, it's not terribly future-proof.
      – Kevin
      Apr 10 at 0:47
















    38














    You probably shouldn't do this, but you can. Kusalananda's answer is better for the task at hand and explains the issue. Since you did ask specifically how to use any library calls inside the terminal, though, here's a few ways...





    The Tiny C Compiler (tcc) supports a -run flag that lets you (in effect) interpret C code by writing a small program, so you can use any library calls inside the terminal through a single invocation of that.



    You can run the strnlen function like this:



    $ tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", strnlen(argv[1], 1024));}') "Hello world"
    11


    This uses process substitution from Bash, zsh, and other shells to give tcc a file to read that appears to contain the results of all the echos; there are other options.



    You could make a function to generate this for you:



    call_library_function_s_i() {
    func=$1
    shift
    tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", '$func'(argv[1]));}') "$*"
    }
    $ call_library_function_s_i strlen hello world


    (I've used strlen here so that it's a unary function string->int - you'd need a separate function for each different arity and return type).





    Another option is the ctypes.sh Bash plugin by Tavis Ormandy, which wraps up dlopen and dlsym. This is probably the closest approximation to what you were trying. You can use, for example:



    $ dlcall -r uint64 strlen "hello world"


    and it will call the function as expected.



    This is the most direct way to do it "from the terminal", but it's unlikely to be something your distribution packages up so you'd have to install it manually (which is nontrivial). Here are some informative quotes from ctypes.sh's own website to give a general impression of how people feel about doing this:





    • "that's disgusting"

    • "this has got to stop"

    • "you've gone too far with this"




    There may be similar tools for other shells, but I don't know about them. In theory there's no reason there couldn't be a standalone command that did this exactly for the simple cases, but I'm somewhat surprised I haven't been able to find one...





    ... so I made one! dlcall lets you call library functions from the command line:



    $ dlcall strnlen "hello world" 6
    $ dlcall sin 2.5
    $ dlcall strchr "hello world" -c ' '


    It supports a limited set of function prototypes, it's not terribly reliable or resilient currently, but it now exists.





    You could also use, for example, Python and python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world, but it's certainly not the easiest way to go about it. Perl, Ruby, and other languages have similar features you could use.





    So the answers to your questions are:




    1. Use one of the approaches above.

    2. You do need to use another command to bootstrap you into the library, or a piece of software that hooks into your shell.


    All in all, you'll almost certainly be better off doing this any other way.






    share|improve this answer



















    • 2




      "dlcall" reminds me of (not quite identical) Windows "rundll": support.microsoft.com/en-gb/help/164787/…
      – pjc50
      Apr 9 at 22:03






    • 1




      @pjc50: Public service announcement: rundll32 is not a general purpose tool for calling arbitrary functions. It can only be used to call functions with a given signature. Also, it's not terribly future-proof.
      – Kevin
      Apr 10 at 0:47














    38












    38








    38






    You probably shouldn't do this, but you can. Kusalananda's answer is better for the task at hand and explains the issue. Since you did ask specifically how to use any library calls inside the terminal, though, here's a few ways...





    The Tiny C Compiler (tcc) supports a -run flag that lets you (in effect) interpret C code by writing a small program, so you can use any library calls inside the terminal through a single invocation of that.



    You can run the strnlen function like this:



    $ tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", strnlen(argv[1], 1024));}') "Hello world"
    11


    This uses process substitution from Bash, zsh, and other shells to give tcc a file to read that appears to contain the results of all the echos; there are other options.



    You could make a function to generate this for you:



    call_library_function_s_i() {
    func=$1
    shift
    tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", '$func'(argv[1]));}') "$*"
    }
    $ call_library_function_s_i strlen hello world


    (I've used strlen here so that it's a unary function string->int - you'd need a separate function for each different arity and return type).





    Another option is the ctypes.sh Bash plugin by Tavis Ormandy, which wraps up dlopen and dlsym. This is probably the closest approximation to what you were trying. You can use, for example:



    $ dlcall -r uint64 strlen "hello world"


    and it will call the function as expected.



    This is the most direct way to do it "from the terminal", but it's unlikely to be something your distribution packages up so you'd have to install it manually (which is nontrivial). Here are some informative quotes from ctypes.sh's own website to give a general impression of how people feel about doing this:





    • "that's disgusting"

    • "this has got to stop"

    • "you've gone too far with this"




    There may be similar tools for other shells, but I don't know about them. In theory there's no reason there couldn't be a standalone command that did this exactly for the simple cases, but I'm somewhat surprised I haven't been able to find one...





    ... so I made one! dlcall lets you call library functions from the command line:



    $ dlcall strnlen "hello world" 6
    $ dlcall sin 2.5
    $ dlcall strchr "hello world" -c ' '


    It supports a limited set of function prototypes, it's not terribly reliable or resilient currently, but it now exists.





    You could also use, for example, Python and python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world, but it's certainly not the easiest way to go about it. Perl, Ruby, and other languages have similar features you could use.





    So the answers to your questions are:




    1. Use one of the approaches above.

    2. You do need to use another command to bootstrap you into the library, or a piece of software that hooks into your shell.


    All in all, you'll almost certainly be better off doing this any other way.






    share|improve this answer














    You probably shouldn't do this, but you can. Kusalananda's answer is better for the task at hand and explains the issue. Since you did ask specifically how to use any library calls inside the terminal, though, here's a few ways...





    The Tiny C Compiler (tcc) supports a -run flag that lets you (in effect) interpret C code by writing a small program, so you can use any library calls inside the terminal through a single invocation of that.



    You can run the strnlen function like this:



    $ tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", strnlen(argv[1], 1024));}') "Hello world"
    11


    This uses process substitution from Bash, zsh, and other shells to give tcc a file to read that appears to contain the results of all the echos; there are other options.



    You could make a function to generate this for you:



    call_library_function_s_i() {
    func=$1
    shift
    tcc -run <(echo '#include <stdio.h>'; echo '#include <string.h>'; echo 'void main(int argc, char **argv) {printf("%in", '$func'(argv[1]));}') "$*"
    }
    $ call_library_function_s_i strlen hello world


    (I've used strlen here so that it's a unary function string->int - you'd need a separate function for each different arity and return type).





    Another option is the ctypes.sh Bash plugin by Tavis Ormandy, which wraps up dlopen and dlsym. This is probably the closest approximation to what you were trying. You can use, for example:



    $ dlcall -r uint64 strlen "hello world"


    and it will call the function as expected.



    This is the most direct way to do it "from the terminal", but it's unlikely to be something your distribution packages up so you'd have to install it manually (which is nontrivial). Here are some informative quotes from ctypes.sh's own website to give a general impression of how people feel about doing this:





    • "that's disgusting"

    • "this has got to stop"

    • "you've gone too far with this"




    There may be similar tools for other shells, but I don't know about them. In theory there's no reason there couldn't be a standalone command that did this exactly for the simple cases, but I'm somewhat surprised I haven't been able to find one...





    ... so I made one! dlcall lets you call library functions from the command line:



    $ dlcall strnlen "hello world" 6
    $ dlcall sin 2.5
    $ dlcall strchr "hello world" -c ' '


    It supports a limited set of function prototypes, it's not terribly reliable or resilient currently, but it now exists.





    You could also use, for example, Python and python -c 'import ctypes; import sys; print(ctypes.cdll.LoadLibrary("libc.so.6").strlen(" ".join(sys.argv[1:])))' hello world, but it's certainly not the easiest way to go about it. Perl, Ruby, and other languages have similar features you could use.





    So the answers to your questions are:




    1. Use one of the approaches above.

    2. You do need to use another command to bootstrap you into the library, or a piece of software that hooks into your shell.


    All in all, you'll almost certainly be better off doing this any other way.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Apr 8 at 20:50

























    answered Apr 8 at 8:54









    Michael Homer

    45.6k8121160




    45.6k8121160








    • 2




      "dlcall" reminds me of (not quite identical) Windows "rundll": support.microsoft.com/en-gb/help/164787/…
      – pjc50
      Apr 9 at 22:03






    • 1




      @pjc50: Public service announcement: rundll32 is not a general purpose tool for calling arbitrary functions. It can only be used to call functions with a given signature. Also, it's not terribly future-proof.
      – Kevin
      Apr 10 at 0:47














    • 2




      "dlcall" reminds me of (not quite identical) Windows "rundll": support.microsoft.com/en-gb/help/164787/…
      – pjc50
      Apr 9 at 22:03






    • 1




      @pjc50: Public service announcement: rundll32 is not a general purpose tool for calling arbitrary functions. It can only be used to call functions with a given signature. Also, it's not terribly future-proof.
      – Kevin
      Apr 10 at 0:47








    2




    2




    "dlcall" reminds me of (not quite identical) Windows "rundll": support.microsoft.com/en-gb/help/164787/…
    – pjc50
    Apr 9 at 22:03




    "dlcall" reminds me of (not quite identical) Windows "rundll": support.microsoft.com/en-gb/help/164787/…
    – pjc50
    Apr 9 at 22:03




    1




    1




    @pjc50: Public service announcement: rundll32 is not a general purpose tool for calling arbitrary functions. It can only be used to call functions with a given signature. Also, it's not terribly future-proof.
    – Kevin
    Apr 10 at 0:47




    @pjc50: Public service announcement: rundll32 is not a general purpose tool for calling arbitrary functions. It can only be used to call functions with a given signature. Also, it's not terribly future-proof.
    – Kevin
    Apr 10 at 0:47













    29














    The apropos command is useful in many ways, but it does give you a lot of "junk" too. Most of the things that you list are C library routines (this is what section 3 of the manual is for), which you can not use directly from the shell.



    To use them, you would have to write C program that calls them. This falls outside of the range of topics covered by this particular site (it would be on topic at StackOverflow).



    These, thus, are the answers to your questions:




    1. You can't, they are C library routines.

    2. You can't, unless you write a C program.


    I know you know this, but for the sake of completeness: In the shell, if you have a string in a variable string, you may do



    string='hello world'
    printf 'Length of string "%s" is %dn' "$string" "${#string}"


    This will print Length of string "hello world" is 11 in the terminal where the 11 comes from ${#string} which expands to the length of the string in $string.



    Internally, the shell may well be using one of the library calls that you listed to do its length calculation.



    This is the most efficient way to get the length of a string that is stored in a shell variable, in the shell.



    Note too that ${#string} is a POSIX shell parameter expansion, it is therefore portable between all shells that claim any degree of POSIX compliance.






    share|improve this answer























    • The parts about the library functions are a good explanation, but the rest of this answer is a bit misleading. OP says "I wanted to simply calculate the length of a string" There's no need to use printf here. If you want to print it out as part of sentence then that might be the best way. But the answer to the question of "how do I get the length of a string?" is the ${#string} part, not the printf. You can just echo ${#string} if you just want to output just the length, or assign it to another variable with string_length=${#string} or whatever you want. printf is not really relevant
      – Adam
      Apr 8 at 18:24






    • 1




      @Adam I have made small modifications to the answer. I think it's pretty clear how to get the length of the string and the user has already said they know how to do it. By using the length of the string with printf I add something other than just saying "use ${#string}" (which is self evident from the example).
      – Kusalananda
      Apr 8 at 18:50


















    29














    The apropos command is useful in many ways, but it does give you a lot of "junk" too. Most of the things that you list are C library routines (this is what section 3 of the manual is for), which you can not use directly from the shell.



    To use them, you would have to write C program that calls them. This falls outside of the range of topics covered by this particular site (it would be on topic at StackOverflow).



    These, thus, are the answers to your questions:




    1. You can't, they are C library routines.

    2. You can't, unless you write a C program.


    I know you know this, but for the sake of completeness: In the shell, if you have a string in a variable string, you may do



    string='hello world'
    printf 'Length of string "%s" is %dn' "$string" "${#string}"


    This will print Length of string "hello world" is 11 in the terminal where the 11 comes from ${#string} which expands to the length of the string in $string.



    Internally, the shell may well be using one of the library calls that you listed to do its length calculation.



    This is the most efficient way to get the length of a string that is stored in a shell variable, in the shell.



    Note too that ${#string} is a POSIX shell parameter expansion, it is therefore portable between all shells that claim any degree of POSIX compliance.






    share|improve this answer























    • The parts about the library functions are a good explanation, but the rest of this answer is a bit misleading. OP says "I wanted to simply calculate the length of a string" There's no need to use printf here. If you want to print it out as part of sentence then that might be the best way. But the answer to the question of "how do I get the length of a string?" is the ${#string} part, not the printf. You can just echo ${#string} if you just want to output just the length, or assign it to another variable with string_length=${#string} or whatever you want. printf is not really relevant
      – Adam
      Apr 8 at 18:24






    • 1




      @Adam I have made small modifications to the answer. I think it's pretty clear how to get the length of the string and the user has already said they know how to do it. By using the length of the string with printf I add something other than just saying "use ${#string}" (which is self evident from the example).
      – Kusalananda
      Apr 8 at 18:50
















    29












    29








    29






    The apropos command is useful in many ways, but it does give you a lot of "junk" too. Most of the things that you list are C library routines (this is what section 3 of the manual is for), which you can not use directly from the shell.



    To use them, you would have to write C program that calls them. This falls outside of the range of topics covered by this particular site (it would be on topic at StackOverflow).



    These, thus, are the answers to your questions:




    1. You can't, they are C library routines.

    2. You can't, unless you write a C program.


    I know you know this, but for the sake of completeness: In the shell, if you have a string in a variable string, you may do



    string='hello world'
    printf 'Length of string "%s" is %dn' "$string" "${#string}"


    This will print Length of string "hello world" is 11 in the terminal where the 11 comes from ${#string} which expands to the length of the string in $string.



    Internally, the shell may well be using one of the library calls that you listed to do its length calculation.



    This is the most efficient way to get the length of a string that is stored in a shell variable, in the shell.



    Note too that ${#string} is a POSIX shell parameter expansion, it is therefore portable between all shells that claim any degree of POSIX compliance.






    share|improve this answer














    The apropos command is useful in many ways, but it does give you a lot of "junk" too. Most of the things that you list are C library routines (this is what section 3 of the manual is for), which you can not use directly from the shell.



    To use them, you would have to write C program that calls them. This falls outside of the range of topics covered by this particular site (it would be on topic at StackOverflow).



    These, thus, are the answers to your questions:




    1. You can't, they are C library routines.

    2. You can't, unless you write a C program.


    I know you know this, but for the sake of completeness: In the shell, if you have a string in a variable string, you may do



    string='hello world'
    printf 'Length of string "%s" is %dn' "$string" "${#string}"


    This will print Length of string "hello world" is 11 in the terminal where the 11 comes from ${#string} which expands to the length of the string in $string.



    Internally, the shell may well be using one of the library calls that you listed to do its length calculation.



    This is the most efficient way to get the length of a string that is stored in a shell variable, in the shell.



    Note too that ${#string} is a POSIX shell parameter expansion, it is therefore portable between all shells that claim any degree of POSIX compliance.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Apr 9 at 8:30

























    answered Apr 8 at 8:22









    Kusalananda

    121k16229372




    121k16229372












    • The parts about the library functions are a good explanation, but the rest of this answer is a bit misleading. OP says "I wanted to simply calculate the length of a string" There's no need to use printf here. If you want to print it out as part of sentence then that might be the best way. But the answer to the question of "how do I get the length of a string?" is the ${#string} part, not the printf. You can just echo ${#string} if you just want to output just the length, or assign it to another variable with string_length=${#string} or whatever you want. printf is not really relevant
      – Adam
      Apr 8 at 18:24






    • 1




      @Adam I have made small modifications to the answer. I think it's pretty clear how to get the length of the string and the user has already said they know how to do it. By using the length of the string with printf I add something other than just saying "use ${#string}" (which is self evident from the example).
      – Kusalananda
      Apr 8 at 18:50




















    • The parts about the library functions are a good explanation, but the rest of this answer is a bit misleading. OP says "I wanted to simply calculate the length of a string" There's no need to use printf here. If you want to print it out as part of sentence then that might be the best way. But the answer to the question of "how do I get the length of a string?" is the ${#string} part, not the printf. You can just echo ${#string} if you just want to output just the length, or assign it to another variable with string_length=${#string} or whatever you want. printf is not really relevant
      – Adam
      Apr 8 at 18:24






    • 1




      @Adam I have made small modifications to the answer. I think it's pretty clear how to get the length of the string and the user has already said they know how to do it. By using the length of the string with printf I add something other than just saying "use ${#string}" (which is self evident from the example).
      – Kusalananda
      Apr 8 at 18:50


















    The parts about the library functions are a good explanation, but the rest of this answer is a bit misleading. OP says "I wanted to simply calculate the length of a string" There's no need to use printf here. If you want to print it out as part of sentence then that might be the best way. But the answer to the question of "how do I get the length of a string?" is the ${#string} part, not the printf. You can just echo ${#string} if you just want to output just the length, or assign it to another variable with string_length=${#string} or whatever you want. printf is not really relevant
    – Adam
    Apr 8 at 18:24




    The parts about the library functions are a good explanation, but the rest of this answer is a bit misleading. OP says "I wanted to simply calculate the length of a string" There's no need to use printf here. If you want to print it out as part of sentence then that might be the best way. But the answer to the question of "how do I get the length of a string?" is the ${#string} part, not the printf. You can just echo ${#string} if you just want to output just the length, or assign it to another variable with string_length=${#string} or whatever you want. printf is not really relevant
    – Adam
    Apr 8 at 18:24




    1




    1




    @Adam I have made small modifications to the answer. I think it's pretty clear how to get the length of the string and the user has already said they know how to do it. By using the length of the string with printf I add something other than just saying "use ${#string}" (which is self evident from the example).
    – Kusalananda
    Apr 8 at 18:50






    @Adam I have made small modifications to the answer. I think it's pretty clear how to get the length of the string and the user has already said they know how to do it. By using the length of the string with printf I add something other than just saying "use ${#string}" (which is self evident from the example).
    – Kusalananda
    Apr 8 at 18:50













    15














    I wouldn't do this for just strlen(), but it is a useful trick for trying out C code sometimes.




    user@host:~$ gdb gdb
    (gdb) start
    Temporary breakpoint 1, ... in main ()
    (gdb) print strlen("foobar")
    $1 = 6


    Here gdb is the GNU debugger, and it would normally take a program name to debug after it. Because we have none, this example gives it itself to debug. Then start starts the program, and after that gdb can be used to execute arbitrary C code.






    share|improve this answer

















    • 2




      Nice trick, to use gdb. Yet gdb is part of developer tools, and if you want to use library function, you better prepare to learn to use developer tools.
      – Dudi Boy
      Apr 8 at 19:02
















    15














    I wouldn't do this for just strlen(), but it is a useful trick for trying out C code sometimes.




    user@host:~$ gdb gdb
    (gdb) start
    Temporary breakpoint 1, ... in main ()
    (gdb) print strlen("foobar")
    $1 = 6


    Here gdb is the GNU debugger, and it would normally take a program name to debug after it. Because we have none, this example gives it itself to debug. Then start starts the program, and after that gdb can be used to execute arbitrary C code.






    share|improve this answer

















    • 2




      Nice trick, to use gdb. Yet gdb is part of developer tools, and if you want to use library function, you better prepare to learn to use developer tools.
      – Dudi Boy
      Apr 8 at 19:02














    15












    15








    15






    I wouldn't do this for just strlen(), but it is a useful trick for trying out C code sometimes.




    user@host:~$ gdb gdb
    (gdb) start
    Temporary breakpoint 1, ... in main ()
    (gdb) print strlen("foobar")
    $1 = 6


    Here gdb is the GNU debugger, and it would normally take a program name to debug after it. Because we have none, this example gives it itself to debug. Then start starts the program, and after that gdb can be used to execute arbitrary C code.






    share|improve this answer












    I wouldn't do this for just strlen(), but it is a useful trick for trying out C code sometimes.




    user@host:~$ gdb gdb
    (gdb) start
    Temporary breakpoint 1, ... in main ()
    (gdb) print strlen("foobar")
    $1 = 6


    Here gdb is the GNU debugger, and it would normally take a program name to debug after it. Because we have none, this example gives it itself to debug. Then start starts the program, and after that gdb can be used to execute arbitrary C code.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Apr 8 at 16:12









    jpa

    56228




    56228








    • 2




      Nice trick, to use gdb. Yet gdb is part of developer tools, and if you want to use library function, you better prepare to learn to use developer tools.
      – Dudi Boy
      Apr 8 at 19:02














    • 2




      Nice trick, to use gdb. Yet gdb is part of developer tools, and if you want to use library function, you better prepare to learn to use developer tools.
      – Dudi Boy
      Apr 8 at 19:02








    2




    2




    Nice trick, to use gdb. Yet gdb is part of developer tools, and if you want to use library function, you better prepare to learn to use developer tools.
    – Dudi Boy
    Apr 8 at 19:02




    Nice trick, to use gdb. Yet gdb is part of developer tools, and if you want to use library function, you better prepare to learn to use developer tools.
    – Dudi Boy
    Apr 8 at 19:02











    4














    A tool which can be used to interactively call functions in shared libraries: the "Witchcraft Compiler Collection". https://github.com/endrazine/wcc



    From the GitHub page:




    wsh : The Witchcraft shell



    The witchcraft shell accepts ELF shared libraries, ELF ET_DYN executables and Witchcraft Shell Scripts written in Punk-C as an input. It loads all the executables in its own address space and makes their API available for programming in its embedded interpreter. This provides for binaries functionalities similar to those provided via reflection on languages like Java.



    Example usage of wsh
    The following command loads the /usr/sbin/apache2 executable within wsh, calls the ap_get_server_banner() function within apache to retrieve its banner and displays it within the wsh interpreter.




    jonathan@blackbox:~$ wsh /usr/sbin/apache2
    > a = ap_get_server_banner()
    > print(a)
    Apache/2.4.7





    share|improve this answer


























      4














      A tool which can be used to interactively call functions in shared libraries: the "Witchcraft Compiler Collection". https://github.com/endrazine/wcc



      From the GitHub page:




      wsh : The Witchcraft shell



      The witchcraft shell accepts ELF shared libraries, ELF ET_DYN executables and Witchcraft Shell Scripts written in Punk-C as an input. It loads all the executables in its own address space and makes their API available for programming in its embedded interpreter. This provides for binaries functionalities similar to those provided via reflection on languages like Java.



      Example usage of wsh
      The following command loads the /usr/sbin/apache2 executable within wsh, calls the ap_get_server_banner() function within apache to retrieve its banner and displays it within the wsh interpreter.




      jonathan@blackbox:~$ wsh /usr/sbin/apache2
      > a = ap_get_server_banner()
      > print(a)
      Apache/2.4.7





      share|improve this answer
























        4












        4








        4






        A tool which can be used to interactively call functions in shared libraries: the "Witchcraft Compiler Collection". https://github.com/endrazine/wcc



        From the GitHub page:




        wsh : The Witchcraft shell



        The witchcraft shell accepts ELF shared libraries, ELF ET_DYN executables and Witchcraft Shell Scripts written in Punk-C as an input. It loads all the executables in its own address space and makes their API available for programming in its embedded interpreter. This provides for binaries functionalities similar to those provided via reflection on languages like Java.



        Example usage of wsh
        The following command loads the /usr/sbin/apache2 executable within wsh, calls the ap_get_server_banner() function within apache to retrieve its banner and displays it within the wsh interpreter.




        jonathan@blackbox:~$ wsh /usr/sbin/apache2
        > a = ap_get_server_banner()
        > print(a)
        Apache/2.4.7





        share|improve this answer












        A tool which can be used to interactively call functions in shared libraries: the "Witchcraft Compiler Collection". https://github.com/endrazine/wcc



        From the GitHub page:




        wsh : The Witchcraft shell



        The witchcraft shell accepts ELF shared libraries, ELF ET_DYN executables and Witchcraft Shell Scripts written in Punk-C as an input. It loads all the executables in its own address space and makes their API available for programming in its embedded interpreter. This provides for binaries functionalities similar to those provided via reflection on languages like Java.



        Example usage of wsh
        The following command loads the /usr/sbin/apache2 executable within wsh, calls the ap_get_server_banner() function within apache to retrieve its banner and displays it within the wsh interpreter.




        jonathan@blackbox:~$ wsh /usr/sbin/apache2
        > a = ap_get_server_banner()
        > print(a)
        Apache/2.4.7






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Apr 9 at 15:03









        Alex D

        32339




        32339






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f436305%2fhow-to-execute-library-commands-from-the-shell%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Morgemoulin

            Scott Moir

            Souastre