0

Folder structure:

#root
|- deployment
|  |- start-dev.sh
|  |- docker-compose.yml
|  |- // other files including app.Dockerfile and anything else I need
|- // everything else

Initial start-dev.sh

#!/bin/sh

docker-compose -p my-container up -d
docker-compose -p my-container exec app bash

Working state

In VS Code (opened as WSL2 remote) integrated terminal I would type

cd deployment
./start-dev.sh

and deployment is successful.

If instead, I tried just deployment/start-dev.sh it fails, since there's no docker-compose.yml in the current directory.

Desire

I want

deployment/start-dev.sh

to work.

Non-solution

The following fails since dirname is not available in my case.

#!/bin/sh

BASEDIR=$(dirname $0)

docker-compose -f "${BASEDIR}/docker-compose.yml" -p my-container up -d
docker-compose -f "${BASEDIR}/docker-compose.yml" -p my-container exec app bash

Solution 1 for start-dev.sh

#!/bin/bash

BASEDIR=$(dirname $0)

docker-compose -f "${BASEDIR}/docker-compose.yml" -p my-container up -d
docker-compose -f "${BASEDIR}/docker-compose.yml" -p my-container exec app bash

Question

How do I convert Solution 1 to be a sh script instead of bash, if dirname is not available in sh?

s3c
  • 1,481
  • 19
  • 28
  • 1
    Since you are asking for a solution for _sh_, and post the bash example only for illustration, I suggest that you remove the _bash_ tag from your question. – user1934428 Jun 16 '22 at 08:58
  • What is the expected outcome, if your script has been invoked via a symlink? Have a look [here](https://stackoverflow.com/questions/29832037/how-to-get-script-directory-in-posix-sh/29835459#29835459), which discusses the problem for various shells (also for sh) and presents a solution for symlinks too. In this link, it also explains under what condition $0 does **not** contain the path to the script. – user1934428 Jun 16 '22 at 09:02

2 Answers2

0

Solution 2

#!/bin/sh

a="/$0"; a=${a%/*}; a=${a#/}; a=${a:-.}; BASEDIR=$(cd "$a"; pwd)

docker-compose -f "${BASEDIR}/docker-compose.yml" -p my-container up -d
docker-compose -f "${BASEDIR}/docker-compose.yml" -p my-container exec app bash
s3c
  • 1,481
  • 19
  • 28
-1

Change the very first line of the script to use #!/bin/sh as the interpreter. You don't need to change anything else.

In particular, the POSIX.1 specification includes dirname and $(command) substitution, so you're not using anything that's not a POSIX shell feature. I'd expect this script to work in minimal but standard-conforming shells like BusyBox's, and so in turn to work in any Docker image that includes a shell.

There are other recipes too, though they do typically rely on dirname(1). See for example How can I set the current working directory to the directory of the script in Bash?, which includes non-bash-specific answers.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • I tried just that, but `dirname` was not supported, so I found the other solution. Thank you though – s3c Jun 16 '22 at 14:24
  • It's not a shell built-in (on my MacOS host there is a `/usr/bin/dirname` binary) so changing shells to a standards-conforming shell shouldn't make a difference here. – David Maze Jun 16 '22 at 15:23
  • That's nice, but in my case there is not `/usr/bin/dirname` (Windows with WSL2, Docker, Ubuntu), so I needed a different solution, while not changing to `#!/bin/bash`. Also I already posted a solution with `dirname` in the question myself. Thanks anyway. – s3c Jun 22 '22 at 07:25