skip to Main Content

I’m trying to create a Bash script based on variables. It works well when I’m using bash command line via docker image:

#docker exec app_mysql mysqldump --login-path=localroot masterdb | gzip > 1111111.sql.gz 

While I’m trying to reproduce the same via shell script by using variables it gives me nothing but just executes without any errors:

#!/bin/bash

DOCKER="docker exec app_mysql bash -c"
CONF_LOCAL_MYSQL_ROOT="--login-path=localroot"
LOCALDBNAME="masterdb"

$DOCKER '(mysqldump '$CONF_LOCAL_MYSQL_ROOT' '$LOCALDBNAME' | gzip > '${LOCALDBNAME}'_local_'${DATE}'.sql.gz)'

Where I’m wrong?

3

Answers


  1. Chosen as BEST ANSWER

    It looks like with the configuration above I've tried to reinvent the wheel. Anyway the solution was simple. I've just removed redundant data from my script. So right now it looks like:

    #!/bin/bash
    
    DOCKER="docker exec app_mysql mysql"
    CONF_LOCAL_MYSQL_ROOT="--login-path=localroot"
    LOCALDBNAME="masterdb"
    
    $DOCKER ${CONF_LOCAL_MYSQL_ROOT} ${LOCALDBNAME} | gzip > ${LOCALDBNAME}_local_${DATE}.sql.gz
    

  2. Bash variables are not expanded inside single-quotes.

    $ foo=hello
    
    $ echo '$foo'
    $foo
    
    $ echo "$foo"
    hello
    
    Login or Signup to reply.
  3. The quoting in your script is inconsistent and that’s probably causing some problems.

    I would not try to expand a multi-word variable as you’ve shown. Instead, if you want to have some sort of abstraction around the docker exec command, I’d use a shell function:

    dockerExec() {
      docker exec app_mysql "$@"
    }
    

    Your original docker exec command does not have a sh -c wrapper and I would not try to force one in here either; it does make the quoting significantly more complicated.

    I also might construct the output filename in a simple variable

    OUTFILE="${LOCALDBNAME}_local_${DATE}.sql.gz"
    

    Note that there are double quotes around the string as a whole, protecting against unexpected spaces, but no additional quotes within the string.

    Putting this all together, and removing unnecessary quotes, you’d get something like:

    #!/bin/sh
    
    CONTAINER=app_mysql
    CONF_LOCAL_MYSQL_ROOT="--login-path=localroot"
    LOCALDBNAME="masterdb"
    DATE="$(date +%Y%m%d)"
    OUTFILE="${LOCALDBNAME}_local_${DATE}.sql.gz"
    
    dockerExec() {
      docker exec "$CONTAINER" "$@"
    }
    
    dockerExec mysql "$CONF_LOCAL_MYSQL_ROOT" "$LOCALDBNAME" 
      | gzip 
      > "$OUTFILE"
    

    Further note that everything I’ve shown here is standard POSIX shell syntax without GNU bash extensions, and I’ve used a plain #!/bin/sh "shebang" line; this will work even in a minimal Debian or Alpine environment where either bash isn’t available or /bin/sh is a different shell.

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