How to execute library commands from the shell?
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 :
- How to use any
library calls (3)
inside the shell? - 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
add a comment |
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 :
- How to use any
library calls (3)
inside the shell? - 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
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
add a comment |
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 :
- How to use any
library calls (3)
inside the shell? - 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
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 :
- How to use any
library calls (3)
inside the shell? - 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
shell libraries
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
add a comment |
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
add a comment |
4 Answers
4
active
oldest
votes
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 echo
s; 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:
- Use one of the approaches above.
- 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.
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
add a comment |
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:
- You can't, they are C library routines.
- 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.
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 useprintf
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 justecho ${#string}
if you just want to output just the length, or assign it to another variable withstring_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 withprintf
I add something other than just saying "use${#string}
" (which is self evident from the example).
– Kusalananda
Apr 8 at 18:50
add a comment |
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.
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
add a comment |
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 theap_get_server_banner()
function within apache to retrieve its banner and displays it within thewsh
interpreter.
jonathan@blackbox:~$ wsh /usr/sbin/apache2
> a = ap_get_server_banner()
> print(a)
Apache/2.4.7
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 echo
s; 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:
- Use one of the approaches above.
- 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.
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
add a comment |
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 echo
s; 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:
- Use one of the approaches above.
- 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.
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
add a comment |
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 echo
s; 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:
- Use one of the approaches above.
- 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.
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 echo
s; 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:
- Use one of the approaches above.
- 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.
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
add a comment |
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
add a comment |
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:
- You can't, they are C library routines.
- 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.
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 useprintf
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 justecho ${#string}
if you just want to output just the length, or assign it to another variable withstring_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 withprintf
I add something other than just saying "use${#string}
" (which is self evident from the example).
– Kusalananda
Apr 8 at 18:50
add a comment |
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:
- You can't, they are C library routines.
- 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.
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 useprintf
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 justecho ${#string}
if you just want to output just the length, or assign it to another variable withstring_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 withprintf
I add something other than just saying "use${#string}
" (which is self evident from the example).
– Kusalananda
Apr 8 at 18:50
add a comment |
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:
- You can't, they are C library routines.
- 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.
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:
- You can't, they are C library routines.
- 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.
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 useprintf
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 justecho ${#string}
if you just want to output just the length, or assign it to another variable withstring_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 withprintf
I add something other than just saying "use${#string}
" (which is self evident from the example).
– Kusalananda
Apr 8 at 18:50
add a comment |
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 useprintf
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 justecho ${#string}
if you just want to output just the length, or assign it to another variable withstring_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 withprintf
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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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 theap_get_server_banner()
function within apache to retrieve its banner and displays it within thewsh
interpreter.
jonathan@blackbox:~$ wsh /usr/sbin/apache2
> a = ap_get_server_banner()
> print(a)
Apache/2.4.7
add a comment |
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 theap_get_server_banner()
function within apache to retrieve its banner and displays it within thewsh
interpreter.
jonathan@blackbox:~$ wsh /usr/sbin/apache2
> a = ap_get_server_banner()
> print(a)
Apache/2.4.7
add a comment |
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 theap_get_server_banner()
function within apache to retrieve its banner and displays it within thewsh
interpreter.
jonathan@blackbox:~$ wsh /usr/sbin/apache2
> a = ap_get_server_banner()
> print(a)
Apache/2.4.7
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 theap_get_server_banner()
function within apache to retrieve its banner and displays it within thewsh
interpreter.
jonathan@blackbox:~$ wsh /usr/sbin/apache2
> a = ap_get_server_banner()
> print(a)
Apache/2.4.7
answered Apr 9 at 15:03
Alex D
32339
32339
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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