0

I have the below folder structure

--/foo 

  --- /foo/bar 

     ---/foo/bar/bcp_main.sh 
    ---/foo/bar/bcp_core.sh
    ---/foo/bar/second_test.sh

Below is my shell script

second_test.sh

source   $(dirname "$0")/bcp_main.sh

bcp_main.sh

echo "In bcp_main.sh" 
source   $(dirname "$0")/bcp_core.sh
func1

bcp_core.sh

 source   $(dirname "$0")/bcp_query_test.sh

    get_date() {
      date --utc --date="$1" +"%Y-%m-%d"        # +"%Y-%m-%d %H:%M:%S"
    }
function func1 {  
   echo "Hello $1"
}

The source from second_test.sh is fine but source from bcp_main to bcp_core it says file not found

xxxxx@asj177 ~/Desktop/foo
$ ./bar/second_test.sh
In bcp_main.sh 
: No such file or directory./bar/bcp_core.sh
in bcp main
./bar/bcp_main.sh: line 23: func1: command not found 

I am trying to run this on MacOs , am I missing some thing here . The files have all the permissions .

arpit joshi
  • 1,987
  • 8
  • 36
  • 62
  • 2
    source does not change `$0`. Use `${BASH_SOURCE[0]}` instead. – anishsane Nov 21 '19 at 08:01
  • Now it gives ./bar/second_test.sh/bcp_main.sh: Not a directory – arpit joshi Nov 21 '19 at 08:03
  • 1
    Then just strip the erroneous part: `source $(dirname ${BASH_SOURCE[0]})/bcp_core.sh` – user1934428 Nov 21 '19 at 08:22
  • well I want to call func1 present in bcp_core.sh from bcp_main ,so for that I would need to souce bcp_core in bcp_main – arpit joshi Nov 21 '19 at 08:24
  • This works when I reconstruct this on Linux with `a.sh`, `b.sh`, `c.sh`, sourcing it as `a` -> `b` -> `c` and using a function in `a` that is defined in `c` (echo $0). Are you sure `bcp_core.sh` isn't misspelled? Try `ls bar/bcp_core.sh`. Also, use a shebang in every script if you haven't already. – Bayou Nov 21 '19 at 08:34
  • 1
    That error message makes me think that bcp_main.sh has DOS/Windows-style line endings. See: [Are shell scripts sensitive to encoding and line endings?](https://stackoverflow.com/questions/39527571/are-shell-scripts-sensitive-to-encoding-and-line-endings) – Gordon Davisson Nov 21 '19 at 09:31
  • "Also, use a shebang in every script if you haven't already" This is not needed if you are sourcing the file. shebang is used only when you are running the file as `/path/to/file.sh` or `./file.sh` – anishsane Nov 21 '19 at 09:35

1 Answers1

0
foo
`-- bar\ with\ space
    |-- bcp_core.sh
    |-- bcp_main.sh
    |-- bcp_query_test.sh
    `-- second_test.sh

bcp_core.sh

dir_name=$(cd  "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)
source "${dir_name}"/bcp_query_test.sh

get_date() {
  date --utc --date="$1" +"%Y-%m-%d"        # +"%Y-%m-%d %H:%M:%S"
}

function func1 {
   echo "Hello from bcp_core: $1"
}

bcp_main.sh

dir_name=$(cd  "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)
source "${dir_name}"/bcp_core.sh
func1 "I am passing this"

bcp_query_test.sh

dir_name=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)
echo "Hello from bcp_query_test.sh"

second_test.sh

dir_name=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)
source "${dir_name}"/bcp_main.sh

while inside foo

> source bar\ with\ space/second_test.sh
Hello from bcp_query_test.sh
Hello from bcp_core: I am passing this
> cd bar\ with\ space/
> source second_test.sh
Hello from bcp_query_test.sh
Hello from bcp_core: I am passing this

Why the dir_name

On Linux you can easily get full path of file with realpath. macOS doesn't provide realpath - you can play with brew to get it on board.

This is why we have to play with ${BASH_SOURCE[0]} and pwd to get the real path of the script, so we can really know where it is.

zsh/bash

Also, note that zsh - which is a default shell in macOS, since 10.15.1 - behaves way better in this context.

If you have simple script

echo $0
echo $(dirname $0)

it will behave differently in bash and zsh. In zsh it makes little bit more sense.

# bash
> source bar/simple.sh
bash
.

# zsh
> source bar/simple.sh
bar/simple.sh
bar
Oo.oO
  • 12,464
  • 3
  • 23
  • 45
  • 1
    Can you elaborate why `dir_name="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"` is necessary? – Bayou Nov 21 '19 at 08:41
  • @Bayou - you are right. It's not needed. If we don't care about explicit location of the file, we can skip this part. – Oo.oO Nov 21 '19 at 12:24
  • @Oo.oO I updated it but it says xxxxx@asj177 ~/Desktop/Foo $ source bar/second_test.sh : No such file or directoryop/Foo/bar : command not found in bcp main : command not found : command not found : command not found : command not found : command not found -bash: func1: command not found – arpit joshi Nov 21 '19 at 23:53
  • @arpitjoshi - maybe you have spaces somewhere in the path? In that case, make sure to play with `"` around the strings. – Oo.oO Nov 22 '19 at 07:07