Search code examples
bashquotesstring-literals

Bash: String variable that includes literal single quotes


Just trying to get a mysqldump script working with a backup user password that contains spaces; if I had a choice, I'd just change it, but I don't.

Head is spinning trying to sort out the wonderful world of Bash and quotes, just need the following to execute...

mysql -u backupuser -p'This is a terrible password with spaces' -e ...

...but with a variable instead:

MYPASS="'This is a terrible password with spaces'" (<-- this, and about 9,307 variations I've tried do not work)

mysql -u backupuser -p$MYPASS -e ...


Solution

  • Passing the password via command line is considered insecure as other users could see the password in plain text either using ps afx or the /proc file system. I've recently wrote a blog post regarding this topic.

    However, to make the command just working it needs double quotes " around $MYPASS to prevent bash from interpreting the space-sepearated password as multiple args:

    MYPASS="foo bar password"
    mysql -u backupuser -p"$MYPASS" -e ...
    

    But I would highly recommend a solution like the following, which uses expect to pass the password to mysqldump:

    #!/bin/bash
    
    # mysql credentials and connection data
    db_host="localhost"
    db_name="testdb"
    db_user="jon"
    db_pass="secret"
    
    # I'm using a here-document to pass commands to expect. 
    # (the commands could be stored in a file as well)
    expect <<EOF
    # disable command output
    log_user 0
    # start the mysqldump process
    spawn mysqldump -h$db_host -u$db_user -p $db_name
    # wait for the password prompt
    expect "password:"
    # send the password (mind the \r)
    send "$db_pass\r"
    # enable output again
    log_user 1
    # echo all outout until the end
    expect eof
    EOF
    

    expect will pass the password in a way like a human user would do: It writes it to stdin of mysqldump after being prompted for it. If you make sure that other users cannot access the except script, they'll have no option to see the password in plain text.