0

I am trying to create a symbolic-link by using:

$ ln -s path/to/foo.sh ~/.local/bin/bar

In the path where foo.sh is executed there is another file, named foo.

The following bash-script executes successfully when launched directly from the terminal (i.e. $ ./foo.sh), however, when I use the symbolic-link bar, it throws an error:

# foo.sh

  1 #!/usr/bin/env bash
  2  appname=`basename $0 | sed s,\.sh$,,`
  3 
  4  dirname=`dirname $0`
  5  tmp="${dirname#?}"
  6 
  7  if [ "${dirname%$tmp}" != "/" ]; then
  8  dirname=$PWD/$dirname
  9  fi
 10  LD_LIBRARY_PATH=$dirname
 11  export LD_LIBRARY_PATH
 12  $dirname/$appname $*

I don't understand why i get the following error, when I try to launch, script above from the symbolic link bar:

bash: warning: shell level (1000) too high, resetting to 1

6
  • Your question makes it sound like it happens only when launching it from the symlink. Does the error still show up when running it directly? – Daniel B Jul 4 '20 at 15:55
  • Hey Daniel, thanks for the quick reply. The error does not show up when running the application directly. It only happens when launching it from the symlink. – monoidog Jul 4 '20 at 15:56
  • Your script trims .sh so running it from foo.sh gets you "No such file...", but then you run it as foo nothing get trimmed and you get an infinite loop. – bac0n Jul 4 '20 at 21:26
  • @bac0n, I updated the question to clarify the issue. The .sh gets trimmed because there is another file with the same name (without the .sh) in the execution directory. Btw, this is not my script, so I'm trying to figure out why I cannot launch such script from a symbolic-link – monoidog Jul 4 '20 at 23:56
  • 1
    the comment still applies ... if you run ./bar you will end up executing $dirname/$appname $* ./bar again. (if you name the link bar.sh it will exec bar), the script by it self doesnt make sense... maybe if you describe what you intend to do there may be a better solution – bac0n Jul 5 '20 at 5:53
0

Resolve symlink before processing the file.

foo.sh

#!/bin/bash

# Mark variable for export.
declare -xi LVL

# Resolve absolute pathname.
filename=$(realpath "$0")

# Strip .sh suffix from file and check for exec bit.
((LVL++ < 1)) && [[ -x "${filename%.sh}" ]] || exit 1

export LD_LIBRARY_PATH="${filename%/*}"

# Run it!
"${filename%.sh}" "$@"

foo

#!/bin/bash
echo "$@"

Now we can create a symlink:

$ ln -s /path/to/foo.sh bar

Regardless of the symlink's name, it is the file foo that will be executed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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