How to execute a MySQL command from a shell script?

前端 未结 14 1145
生来不讨喜
生来不讨喜 2020-11-28 01:28

How can I execute an SQL command through a shell script so that I can make it automated?

I want to restore data I have collected in a SQL file using a shell script.

相关标签:
14条回答
  • 2020-11-28 01:53

    To "automate" the process of importing the generated .sql file, while avoiding all the traps that can be hidden in trying to pass files through stdin and stdout, just tell MySQL to execute the generated .sql file using the SOURCE command in MySQL.

    The syntax in the short, but excellent, answer, from Kshitij Sood, gives the best starting point. In short, modify the OP's command according to Kshitij Sood's syntax and replace the commands in that with the SOURCE command:

    #!/bin/bash
    mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
    SOURCE ds_fbidx.sql"
    

    If the database name is included in the generated .sql file, it can be dropped from the command.

    The presumption here is that the generated file is valid as an .sql file on its own. By not having the file redirected, piped, or in any other manner handled by the shell, there is no issue with needing to escape any of the characters in the generated output because of the shell. The rules with respect to what needs to be escaped in an .sql file, of course, still apply.

    How to deal with the security issues around the password on the command line, or in a my.cnf file, etc., has been well addressed in other answers, with some excellent suggestions. My favorite answer, from Danny, covers that, including how to handle the issue when dealing with cron jobs, or anything else.


    To address a comment (question?) on the short answer I mentioned: No, it cannot be used with a HEREDOC syntax, as that shell command is given. HEREDOC can be used in the redirection version syntax, (without the -Bse option), since I/O redirection is what HEREDOC is built around. If you need the functionality of HEREDOC, it would be better to use it in the creation of a .sql file, even if it's a temporary one, and use that file as the "command" to execute with the MySQL batch line.

    #!/bin/bash
    cat >temp.sql <<SQL_STATEMENTS
    ...
    SELECT \`column_name\` FROM \`table_name\` WHERE \`column_name\`='$shell_variable';
    ...
    SQL_STATEMENTS
    mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
    rm -f temp.sql
    

    Bear in mind that because of shell expansion you can use shell and environment variables within the HEREDOC. The down-side is that you must escape each and every backtick. MySQL uses them as the delimiters for identifiers but the shell, which gets the string first, uses them as executable command delimiters. Miss the escape on a single backtick of the MySQL commands, and the whole thing explodes with errors. The whole issue can be solved by using a quoted LimitString for the HEREDOC:

    #!/bin/bash
    cat >temp.sql <<'SQL_STATEMENTS'
    ...
    SELECT `column_name` FROM `table_name` WHERE `column_name`='constant_value';
    ...
    SQL_STATEMENTS
    mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
    rm -f temp.sql
    

    Removing shell expansion that way eliminates the need to escape the backticks, and other shell-special characters. It also removes the ability to use shell and environment variables within it. That pretty much removes the benefits of using a HEREDOC inside the shell script to begin with.

    The other option is to use the multi-line quoted strings allowed in Bash with the batch syntax version (with the -Bse). I don't know other shells, so I cannot say if they work therein as well. You would need to use this for executing more than one .sql file with the SOURCE command anyway, since that is not terminated by a ; as other MySQL commands are, and only one is allowed per line. The multi-line string can be either single or double quoted, with the normal effects on shell expansion. It also has the same caveats as using the HEREDOC syntax does for backticks, etc.

    A potentially better solution would be to use a scripting language, Perl, Python, etc., to create the .sql file, as the OP did, and SOURCE that file using the simple command syntax at the top. The scripting languages are much better at string manipulation than the shell is, and most have in-built procedures to handle the quoting and escaping needed when dealing with MySQL.

    0 讨论(0)
  • 2020-11-28 01:57
    #!/bin/sh
    #Procedures = update
    #Scheduled at : Every 00.05 
    
    v_path=/etc/database_jobs
    v_cnt=0
    
    MAILTO="indd@abc.in joanson@abc.in sturt@abc.in"
    touch "$v_path/db_db_log.log"
    
    #test
    mysql -uusername -ppassword -h111.111.111.111 db_name -e "CALL functionName()" > $v_path/db_db_log.log 2>&1
    if [ "$?" -eq 0 ]
      then
       v_cnt=`expr $v_cnt + 1`
      mail -s "db Attendance Update has been run successfully" $MAILTO < $v_path/db_db_log.log
     else
       mail -s "Alert : db Attendance Update has been failed" $MAILTO < $v_path/db_db_log.log
       exit
    fi
    
    0 讨论(0)
  • 2020-11-28 01:58

    How to execute an SQL script, use this syntax:

    mysql --host= localhost --user=root --password=xxxxxx  -e "source dbscript.sql"
    

    If you use host as localhost you don't need to mention it. You can use this:

    mysql --user=root --password=xxxxxx  -e "source dbscript.sql"
    

    This should work for Windows and Linux.

    If the password content contains a ! (Exclamation mark) you should add a \ (backslash) in front of it.

    0 讨论(0)
  • 2020-11-28 01:58

    As stated before you can use -p to pass the password to the server.

    But I recommend this:

    mysql -h "hostaddress" -u "username" -p "database-name" < "sqlfile.sql"
    

    Notice the password is not there. It would then prompt your for the password. I would THEN type it in. So that your password doesn't get logged into the servers command line history.

    This is a basic security measure.

    If security is not a concern, I would just temporarily remove the password from the database user. Then after the import - re-add it.

    This way any other accounts you may have that share the same password would not be compromised.

    It also appears that in your shell script you are not waiting/checking to see if the file you are trying to import actually exists. The perl script may not be finished yet.

    0 讨论(0)
  • 2020-11-28 01:58
    mysql_config_editor set --login-path=storedPasswordKey --host=localhost --user=root --password
    

    How do I execute a command line with a secure password?? use the config editor!!!

    As of mysql 5.6.6 you can store the password in a config file and then execute cli commands like this....

    mysql --login-path=storedPasswordKey ....
    

    --login-path replaces variables... host, user AND password. excellent right!

    0 讨论(0)
  • 2020-11-28 01:59

    Use this syntax:

    mysql -u $user -p$passsword -Bse "command1;command2;....;commandn"
    
    0 讨论(0)
提交回复
热议问题