3

I just downloaded a tar file that is supposed to include everything required to run a program that we can call some_binary. I extracted it's contents, and I see the following:

  • A binary (let's call it some_binary)
  • A lib folder with various dynamic libraries (.so files) such as /lib/ld-linux-x86-64.so
  • and a shell script called some_binary.sh

The script has the following contents:

#!/bin/bash
`dirname "$0"`/lib/ld-linux-x86-64.so.2   `dirname "$0"`/some_binary "$@"

and running it as ./some_binary.sh some arguments seems to run ./some_binary correctly. Oddly enough, running the following script:

#!/bin/bash
LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
./some_binary "$@"

as ./my_script.sh some arguments does not work. It results in relocation errors (undefined symbols), presumably from incorrectly loading the libraries under ./lib

Moreover, running the following two statements from the command line results in segmentation fault:

> LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH
> ./some_binary some arguments

With this, my questions are:

  1. What does the first script do?
  2. Why do I get different results across these three attempts? and why can't I just add $pwd/lib to LD_LIBRARY_PATH and then run some_binary directly?
2
  • Is it a backslash before that second backtick?
    – Runium
    Apr 24, 2013 at 2:06
  • @Sukminder. Good catch. Thanks. I had problems typing embedding the command within a code block in the post. Apr 24, 2013 at 3:00

1 Answer 1

3

The program comes with its own dynamic loader. It's quite rare for programs to need their own dynamic loader: usually the one on your system will work too. This may be necessary if the program was linked against a standard library other than GNU libc or if it was linked against a GNU libc compiled with strange settings.

It may be enough to tell the loader where to find the program's preferred libraries. Your attempt almost does that, but not quite. If LD_LIBRARY_PATH is not already in the environment, then the assignment LD_LIBRARY_PATH=$CWD/LIB:$LD_LIBRARY_PATH only defines a shell variable, not an environment variable, so the program doesn't see a thing. Furthermore, $CWD usually expands to the empty string, you probably meant $PWD or better $(dirname "$0") (i.e. the directory containing the script). Also beware that you used lib and LIB inconsistently in your question. Try

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
exec "$(dirname "$0")/some_binary" "$@"

or better, to avoid having an empty entry at the end of LD_LIBRARY_PATH if it wasn't defined before (this can be bad because an empty entry stands for the current directory, though at the end of the path it's only harmful if a library isn't found where it should be):

#!/bin/sh
export LD_LIBRARY_PATH="$(dirname "$0")/lib:$LD_LIBRARY_PATH"
case "$LD_LIBRARY_PATH" in *:) LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:};; esac
exec "$(dirname "$0")/some_binary" "$@"
3

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .