ShellScript
MySQL

シェルスクリプトでSQL(mysql)を実行する

More than 1 year has passed since last update.

mysqlコマンドを実行

色々と解決してこの形に落ち着きました。
関数2つです。
1. DDL実行関数
2. 値一つだけSELECTして取得する関数

ソース

mymysql.sh
#!/bin/bash
# ################################################################################
#   MySQL
# ################################################################################

# test
MYSQL_ID='root'
MYSQL_PWD='root'
MYSQL_HOST='localhost'
MYSQL_SCHEMA='mysql'

# staging
# MYSQL_ID='scott'
# MYSQL_PWD='tiger'
# MYSQL_HOST='localhost'
# MYSQL_SCHEMA='test'

MYSQL_COMMAND_ARGS="-h ${MYSQL_HOST} -u${MYSQL_ID} -p${MYSQL_PWD} --database=${MYSQL_SCHEMA}"
MYSQL_IGNORE_WARNING='Warning: Using a password on the command line interface can be insecure.'

function MyEcho()
{
    echo "[`date '+%Y/%m/%d %T'`] $1"
}

# MySQL コマンドでSQL実行 -値を1つだけ取得
# argv1 : SQL
# return : $ret
function getValue()
{
    unset ret
    unset SQLGetValue
    SQLGetValue=$1

    RetValue=`echo "$SQLGetValue" | mysql ${MYSQL_COMMAND_ARGS} 2>&1`
    Ret=$?

    # ワーニング削除
    RetValue=${RetValue#$MYSQL_IGNORE_WARNING}

    if [ $Ret -gt 0 ]; then
        MyEcho "on error($Ret) $SQLGetValue"
        echo $RetValue
        return $Ret
    fi

    # 配列化
    ValueArray=(${RetValue//\r/ })
    # echo '*' ${ValueArray[*]}   # 返却内容
    # echo '0' ${ValueArray[0]}   # ID句
    # echo '1' ${ValueArray[1]}   # Value スペース分割される '2014-03-18 01:15:00' の場合は '2014-03-18'

    unset ValueArray[0]         # ID句を削除

    # cnt=0
    # for el in ${ValueArray[@]}; do
    #     let cnt++
    #     echo "$cnt : $el"
    # done
    # echo "ret : ${RetValue[1]}"

    ret="${ValueArray[*]}"
    return $Ret
}

# MySQL コマンドでSQL実行
# argv1 : SQL
function snedMySQLCommand()
{
    getValue "$1"
    return $?
}

使い方ソース

mymysql_test.sh
#!/bin/bash
. ./mymysql.sh
cd `dirname $0`

sql="SELECT name FROM mysql.help_keyword"
sql=$sql" ORDER BY help_keyword_id LIMIT 1"
getValue "$sql"
Ret=$?
if [ $Ret -gt 0 ]; then
    echo "on error($Ret) $sql"
else
    echo getValue return value:$ret
fi

snedMySQLCommand "CREATE DATABASE mytest"
Ret=$?
if [ $Ret -gt 0 ]; then
    echo "on error($Ret)"
else
    echo created database mytest
fi

実行結果

2度目のCREATE文発行でエラーを補足しています。
エラーログをちゃんと作れると後の人が楽になります。

ekaneko@bibian ~/work/mysql % bash ./mymysql_test.sh
getValue return value:JOIN
created database mytest
ekaneko@bibian ~/work/mysql % bash ./mymysql_test.sh
getValue return value:JOIN
[2014/05/23 13:16:07] on error(1) CREATE DATABASE mytest
ERROR 1007 (HY000) at line 1: Can't create database 'mytest'; database exists
on error(1)
ekaneko@bibian ~/work/mysql % 

解説

getValue()で値をリターンしたかったのですが、制約上無理だったのでグローバル変数 $ret を使ってます。
無理じゃなかったです。返却値をechoしコール元で出力取り込みすればグローバル変数に依存しない書き方が出来ました。
詳しくはこっち参照 > ShellScript - シェルスクリプトで日付と時間を大小判定 - Qiita http://qiita.com/TanukiTam/items/6572ea18c2de80ebf458

for do をもっと解析すればちゃんとしたhash表として返却出来るのですが、そこまで求めなかったので手抜きしてます。
ワーニング削除は aws - CentOS で実行してる時にパスワード入れちゃ駄目と出て邪魔だったので削ってます

コメントでいただいた情報

丸っとコメントを引用したかったのですがわかりませんでした。
ごめんなさい。

パス警告抑制

ngyuki さんありがとうです♪
パスワードをコマンドラインで入れた時の警告抑制を教えていただきました。
history コマンドで遡るとパスワード見えちゃうので、私もその方が良いと思います!

  1. 環境変数で指定する
echo "select 1 as one" | MYSQL_PWD=password mysql -u oreore
  1. my.conf オプション設定ファイルから読み込ませる

--defaults-extra-file を使用し設定ファイルを読ませると良いです。確かに。

< 参照 > MySQL :: MySQL 5.1 リファレンスマニュアル :: 3.3.2 オプションファイルの使用 http://dev.mysql.com/doc/refman/5.1/ja/option-files.html

umask 0077
echo -e "[client]\npassword = password" > my.cnf
echo "select 1 as one" | mysql --defaults-extra-file=my.cnf -u oreore
rm -f my.cnf

skip-column-names

ngyuki さんありがとうございます。

unset ValueArray[0] # ID句を削除

列名の部分が不要なら --skip-column-names を付ければ値しか返ってこないので簡単です。

$ echo "select 1 as one" | mysql
one
1
$ echo "select 1 as one" | mysql --skip-column-names
1