Home > Software design >  Bash scripting with docker exec when using variables
Bash scripting with docker exec when using variables

Time:04-10

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?

CodePudding user response:

Bash variables are not expanded inside single-quotes.

$ foo=hello

$ echo '$foo'
$foo

$ echo "$foo"
hello

CodePudding user response:

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.

  • Related