Linux load library command line

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:

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) 
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 
$ strnlen HelloWorld $ strnlen: command not found 
  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.

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.

Off Topic, but OpenVMS has «lexical» functions which are shell interfaces to a great deal of system library functions.

4 Answers 4

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 '; echo '#include '; echo 'void main(int argc, char **argv) ') "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 '; echo '#include '; echo 'void main(int argc, char **argv) ') "$*" > $ 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:

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.

$ 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.

«dlcall» reminds me of (not quite identical) Windows «rundll»: support.microsoft.com/en-gb/help/164787/…

@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.

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:

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 %d\n' "$string" "$" 

This will print Length of string «hello world» is 11 in the terminal where the 11 comes from $ 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 $ 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 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 $ part, not the printf. You can just echo $ if you just want to output just the length, or assign it to another variable with string_length=$ or whatever you want. printf is not really relevant

@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 $ » (which is self evident from the example).

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.

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.

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

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 

Источник

How to install libraries manually in Linux

I have already written an article with step by step instructions to load modules from kernel during boot stage and also a guide to blacklist any module during boot up stage.
Shared libraries relies heavily on concept of libraries. These are the collection of software that are re used by other programs. This avoids having to rewrite the code for functions that are used repeatedly.
Software libraries can be linked in two ways:

Statically

These are compiled together with a program to produce a single piece of executable code. this can have advantage of producing executable code that runs quickly. However this disadvantage is that the resulting code tends to be long and so uses large amount of system resources.

Dynamically

These are also shared libraries and are loaded into memory as they are needed. This means that the code compiled with dynamically linked libraries has a smaller memory footprint then if it were linked statically.
Shared libraries are frequently updated. Installing new libraries means that you need to maintain the software that depends on these libraries. We do this in order to avoid or resolve dependencies and conflicts.
To list the shared libraries

# ldd /bin/ls linux-vdso.so.1 => (0x00007fffa9bff000) libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003f64600000) librt.so.1 => /lib64/librt.so.1 (0x0000003f63600000) libcap.so.2 => /lib64/libcap.so.2 (0x0000003f66e00000) libacl.so.1 => /lib64/libacl.so.1 (0x0000003f6da00000) libc.so.6 => /lib64/libc.so.6 (0x0000003f62e00000) libdl.so.2 => /lib64/libdl.so.2 (0x0000003f62a00000) /lib64/ld-linux-x86-64.so.2 (0x0000003f62600000) libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003f63200000) libattr.so.1 => /lib64/libattr.so.1 (0x0000003f73200000)

Install a library manually

To install a library file you need to copy the file inside /usr/lib and then run ldconfig (as root). It will install any new library in that directory

ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf , and in the trusted directories ( /lib and /usr/lib ). The cache is used by the run-time linker, ld.so or ld-linux.so . ldconfig checks the header and filenames of the libraries it encounters when determining which versions should have their links updated.
ldconfig will attempt to deduce the type of ELF libs (i.e., libc5 or libc6/glibc ) based on what C libs, if any, the library was linked against.

If you install library in a non standard directory you need to add this path LD_LIBRARY_PATH for Red Hat Linux and SHLIB_PATH for HP-UX

You can add the path using the below command (path has to be added instead of /usr/lib followed by a colon «:»)
For Red Hat Linux

# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib:/usr/local/lib

For HP-UX (Unix)

# export SHLIB_PATH=$SHLIB_PATH:/usr/lib:/usr/local/lib

For making these changes permanent add these path in .bash_profile you must set environment (PATH) variable permanently in Linux
References
ldconfig man page

Leave a Comment Cancel reply

Recent Posts

Источник

Читайте также:  Linux cat grep to file
Оцените статью
Adblock
detector