A portable solution to achieve what you want consists in replacing the contents of file b.sh with:
#!/usr/bin/env bash
# (file b.sh)
srcdir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )
source "$srcdir/c.sh"
As a side remark, note that it is maybe unnecessary to source the files at stake: it is especially useful if you need to export in the ambient shell session the variables defined in c.sh. Otherwise (if you just need to run c.sh as a standalone script) you may want to replace the script above with:
#!/usr/bin/env bash
# (file b.sh)
srcdir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )
"$srcdir/c.sh"
and at the same time:
- add a shebang such as
#!/usr/bin/env bash or #!/bin/bash at the beginning of c.sh
- set the executable bit of
c.sh by doing chmod a+x c.sh
.stands for the folder you're in when calling it. You can userealpathanddirnameto get the absolute path to your file and create the relative path you need for your script. If you're on Mac os, trybrew install coreutilsto getrealpathcommand. Hope it helpsa.sh. It should export a variable likeADIRthat contains its installation location; then everything else uses dynamic absolute paths like$ADIR/stuff/b.sh.