skip to Main Content

I have the following Dockerfile

FROM python:3.9-slim-buster

## DO SOMETHING HERE

RUN /bin/bash -c shopt -s extglob && rm -rfv !(".env")

I am getting

Step 42/49 : RUN /bin/bash -c shopt -s extglob && rm -rfv !(".env")
 ---> Running in 5b4ceacb1908
/bin/sh: 1: Syntax error: "(" unexpected

HOw to run this command. I need this

3

Answers


  1. /bin/bash seems to work for "shopt -s extglob" part but not the other. Separate the lines like this:

     RUN /bin/bash -c shopt -s extglob  
     RUN /bin/bash -c rm -rfv !(".env")
    

    or

    RUN /bin/bash -c "shopt -s extglob && rm -rfv !(".env")"
    
    Login or Signup to reply.
  2. I’d recommend avoiding bash-specific syntax wherever possible.

    In this case, the bash-specific glob pattern !(.env) means "every file except .env. So you can accomplish this specific task by moving .env out of the way, deleting the whole directory, recreating it, and moving .env back; all without worrying about which shell expansion objects are set.

    RUN cd .. 
     && mv the_dir/.env . 
     && rm -rf the_dir 
     && mkdir the_dir 
     && mv .env the_dir
    

    You also might consider whether you need a broad rm -rf at all. Because of Docker’s layer system, the previous content of the directory is still "in the image". If you use a multi-stage build then the later stage will start from a clean slate, and you can COPY in whatever you need.

    FROM python:3.9-slim-buster AS build
    ...
    FROM python:3.9-slim-buster
    WORKDIR /app
    COPY .env .
    COPY --from=build ...
    
    Login or Signup to reply.
  3. Every RUN line in your Dockerfile will launch a new container with a separate shell. The extglob shell option must be set before a line of input is parsed by the shell, so one way to go about this is to launch the shell with that option enabled:

    RUN /bin/bash -O extglob -c 'rm -rfv !(".env")'
    

    The main caveat is that you have to quote the command line as a string.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search