How the shell with Docker executor is selected

I’m using shared runners on Gitlab.com page with a custom Docker image. It is based on Alpine which contains sh but also bash is installed in a later step.

How do I know, which shell the Docker executor is using for executing scripts from .gitlab-ci.yml file? Is that sh or bash?

This documentation (The Docker executor | GitLab) says that sh, bash and pwsh is supported. However if Docker image contains more of them, which has higher priority?

2 Likes

I would love to know this as well. I have a container which uses
ENTRYPOINT ["/bin/bash", "-l", "-c"]
and has bash installed, but still I cannot make it run using bash instead of sh.

I also set the shell option of the [[runners]] section to bash, to no avail.

I wasn’t able to find it in the documentation, but I have found that in the source code of Runner.
I wrote a post about it here: Shell conditions in Gitlab CI - DEV Community 👩‍💻👨‍💻

And here is the script which is responsible for selecting the shell.

Thank you for that.

Using one of my images, which has ENTRYPOINT ["/bin/bash", "-l", "-c"] and a working bash, I am still getting that GitLab executes scripts using sh:

image:
    name:my_image
    entrypoint: [ "/bin/bash", "-lc" ] # Just for good measure, force it

stages:
    - test

job:
    stage: test
    script:
        - '[ -x /bin/bash ] && echo BASH IS OK' # OK
        - '[ -x /bin/sh ]   && echo   SH IS OK' # OK
        - bash -c 'echo $0' # BASH
        - echo $0 # SH: why?

I am sincerely lost.
This does not happen with the image my image is based on: debian:bookworm-slim, to which I actually only add a couple of things and set the environment.

I even manually ran:

docker run --rm -it --entrypoint "sh" my_image -c 'if [ -x /usr/local/bin/bash ]; then
  echo exec /usr/local/bin/bash -l
  elif [ -x /usr/bin/bash ]; then
  echo exec /usr/bin/bash -l
  elif [ -x /bin/bash ]; then
  echo exec /bin/bash -l
  elif [ -x /usr/local/bin/sh ]; then
  echo exec /usr/local/bin/sh -l
  elif [ -x /usr/bin/sh ]; then
  echo exec /usr/bin/sh -l
  elif [ -x /bin/sh ]; then
  echo exec /bin/sh -l
  elif [ -x /busybox/sh ]; then
  echo exec /busybox/sh -l
  else
  echo shell not found
  exit 1
  fi'

and got exec /bin/bash -l in response!

Hello,

I am also having this problem. Could anyone at @gitlab please take a look at this? It’s been a year and a half since the original poster asked the question and I would expect some support within a week. It’s embarrassing to see these posts going unattended for YEARS.

Cheers.

You do realise this is a community forum right? There are no guarantees or expectations. If you have an expectation or require an SLA perhaps you should be paying for support? :wink:

Chances are the lack of reply means, that perhaps none of the community members have a solution for it, perhaps have missed the post and never seen it, aren’t bothered about changing the shell or something else.

Sadly, I also don’t know the answer, when I do CI/CD using the Docker executor, I’m not really that bothered about what the shell is - and generally to save on bloat, I don’t tend to install additional stuff that may or may not be needed when /bin/sh does everything I need. I realise other people have different requirements though.

The documentation seems to hint on how it has been done previously by setting the entrypoint for the image: Docker executor | GitLab although if that isn’t working for you, then there is obviously something not quite right either with the documentation or the method in attempting to run it simply doesn’t work.

I would suggest opening an issue here: Issues · GitLab.org / gitlab-runner · GitLab if one isn’t already open for it - that is probably the best way to get the problem fixed since Dev’s don’t really tend to look at a forum, then work on the issues assigned.