0

I have the following script in a sh file running in the host:

printf '\n\n=== Installing asdf ...\n\n'
docker container exec "$CONTAINER_NAME" sh -c 'git clone https://github.com/asdf-vm/asdf.git /root/.asdf --branch v0.10.2'
docker container exec "$CONTAINER_NAME" sh -c 'echo ''. /root/.asdf/asdf.sh'' >> /root/.bashrc'
docker container exec "$CONTAINER_NAME" sh -c 'echo ''. /root/.asdf/completions/asdf.bash'' >> /root/.bashrc'

printf '\n\n=== Installing node/npm using asdf ...\n\n'
NODEJS_VERSION='17.9.0'
docker container exec "$CONTAINER_NAME" sh -c 'asdf plugin add nodejs'
docker container exec "$CONTAINER_NAME" sh -c "asdf install nodejs $NODEJS_VERSION"
docker container exec "$CONTAINER_NAME" sh -c "asdf global nodejs $NODEJS_VERSION"

When asdf plugin add nodejs line is executed I get the following error:

sh: 1: asdf: not found

The whole issue is happening because $PATH is not being updated after the installation of asdf. I tried:

  1. to reload .bashrc/.profile after installing asdf
docker container exec "$CONTAINER_NAME" sh -c '. /root/.bashrc'
  1. to restart the container:
docker "$CONTAINER_NAME" restart

The (not so) weird thing is when I get into the container I can use asdf because, as expected, $PATH contains the path to asdf folders.

Does anybody knows what I am missing here?

Saulo
  • 499
  • 1
  • 4
  • 16
  • 1
    When you double up single quotes they cancel each other out. `echo ''foo bar''` is exactly the same as just `echo foo bar` with no quotes at all. If you want to have literal single quotes inside syntactic single quotes, you need to end the single-quoted context, switch to a double-quoted context, add a single quote inside the double quotes, then switch back. It looks like this: `echo 'these words are '"'"'quoted'"'"' properly'` – Charles Duffy Sep 04 '22 at 17:39
  • 1
    Anyhow -- `.bashrc` isn't used in noninteractive shells. It's completely normal that changes you make to it won't change how scripts execute. – Charles Duffy Sep 04 '22 at 17:41

1 Answers1

3

Each exec runs a new process which loses all its settings when it terminates. You need to start a new Bash shell with the correct options to read .bashrc ... or just give up on trying to use its interactive features for noninteractive scripts, and instead put these commands in a script, and then simply run it.

docker container exec "$container_name" bash '
printf "%s\n" "=== Installing asdf ..."
git clone https://github.com/asdf-vm/asdf.git /root/.asdf --branch v0.10.2
. /root/.asdf/asdf.sh
# . /root/.asdf/completions/asdf.bash

printf "%s\n" "=== Installing node/npm using asdf ..."
nodejs_version="17.9.0"
asdf plugin add nodejs
asdf install nodejs "$nodejs_version"
asdf global nodejs "$nodejs_version"'

I could not bring myself to keep all the newlines in your diagnostic messages.

Tangentially see also Correct Bash and shell script variable capitalization which explains why I changed the variables with the container name and the Node version to lower case.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Nothing here seems to require Bash but perhaps the file you source contains some Bash-only stuff...? Otherwise probably prefer `sh` – tripleee Sep 04 '22 at 17:26
  • "you need to start a new Bash shell with the correct options to read .bashrc" what would be this correct options? How could I do that? – Saulo Sep 05 '22 at 06:20
  • The Bash man page has the excruciating details, but in brief, I would recommend against that in favor of using a script, as already outlined in this answer. – tripleee Sep 05 '22 at 06:27
  • I tried to move it into a script but the `source` command still doesn't work. I've created [another question](https://stackoverflow.com/questions/73605322/how-to-make-source-command-work-in-a-script-executed-by-docker-exec) to address specifically this matter. Anyhow, thank you for your help so far. I really appreciate it. – Saulo Sep 05 '22 at 06:34