Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?
share|improve this question
    
Is it a backslash before that second backtick? –  Sukminder Apr 24 '13 at 2:06
    
@Sukminder. Good catch. Thanks. I had problems typing embedding the command within a code block in the post. –  user815423426 Apr 24 '13 at 3:00
add comment

1 Answer

up vote 2 down vote accepted

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" "$@"
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.