title: mysqldump access denied when being used in bash script
body: <p>I am trying to create a bash script that uses <code>mysqldump</code> to create a backup of the database that is specified as parameter. However <code>mysqldump</code> fails with an <code>access denied</code> error. Using the same command directly (copying it to the shell an executing it) works without any problem.</p>
  
  <pre><code>#!/bin/bash
  
  # ... use parameters to get db name and password
  # build the mysqldump command and execute it...
  
  command="mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u ${database} -p'${pw}' --extended-insert ${database} | gzip &gt; ${path}"
  echo "$command"
  echo ""
  $command
  </code></pre>
  
  <p>This gives me the following output:</p>
  
  <pre><code>$ ./dbbak DBUSER DBNAME PASSWORD
  mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u DBUSER -p'PASSWORD' --extended-insert DBNAME | gzip &gt; /path/to/backup/backup.sql.gz
  
  Warning: Using a password on the command line interface can be insecure.
  -- Connecting to 127.0.0.3...
  mysqldump: Got error: 1045: Access denied for user 'DBUSER'@'localhost' (using password: YES) when trying to connect
  </code></pre>
  
  <p>As said before: When I copy the echoed <code>mysqldump</code> command and execute it directly, the backup works just fine.</p>
  
  <p>What is the problem here? Since the command is executed correctly when being used manually all parameters (password, username, etc.) seem to be correct. Additionally the bash script is executed with the same user account as the manual command. </p>
  
  <p><strong>So why does the manual execution work while the bash script fails?</strong></p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>As Jens pointed out in his comment, removing the quotes from the password will solve the problem. <code>...-p${pw}...</code> will work, <strong>BUT</strong> this will also lead to a new problem, if the password contains special characters like <code>$ &lt; &gt; ...</code></p>
  
  <p>I assume that the problem with the quotes is how bash parses the string. Meanwhile I found some docs that say, that it is a bad habit to store commands in variables and execute them. Instead one should execute commands directly. However the following does not work as well:</p>
  
  <pre><code>result=$(mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u ${database} -p'${pw}' --extended-insert ${database} | gzip &gt; ${path}) 
  </code></pre>
  
  <p>When executing this with <code>bash -x dbbak</code> the output shows the problem:</p>
  
  <pre><code>...
  ++ mysqldump -alv -h127.0.0.3 --default-character-set=utf8 -u DBUSER '-p'\''DBPASS'\''' --extended-insert DBNAME
  </code></pre>
  
  <p>While I do understand why the quotes around DBPASS are added (<code>'DBPASS' --&gt; \''DBPASS'\'), I do not understand why there are also quotes around</code>-p`.</p>
  
  <p>How do I get rid of these quotes when executing the command?</p>