|
|
|
| У меня есть скриптина, которая выполняет stored procedure в mysql и выдаёт результат в консоль
#!/bin/bash
database=
usage="Usage: ./opt.sh -d database_name"
while getopts "d:" opt; do
case $opt in
d) database=`echo "$OPTARG" | sed -r "s/[\"']//g"`;;
esac
done
if [ x = "x$database" ] ; then
echo "$usage" >&2
exit 1
fi
cmd="mysql -u root -pxxx -D dbname -e 'CALL optimize_tables(\""$database"\")' 2>/dev/null | grep '\\.' | awk '{split(\$0,a,\"\\t\");split(a[1],b,\".\");printf \"%-30s %s\\n\", b[2], a[4]}'"
result=`eval $cmd`
if [ x = "x$result" ] ; then
echo "Database \"$database\" not exists or have no tables"
exit 1
fi
echo "$result"
|
В таблице dbname есть процедура optimize_tables, которая выполняет OPTIMIZE TABLE на все таблицы указанной базы данных. Дело в том, что эта процедура сразу выдаёт результат обработки таблицы по мере её обработки. Но в данном скрипте эти результаты буфферизуются (захватываются) в переменную result и уже потом выводятся результаты. Но я не нашел способа выполнения команды без eval и захвата вывода. То есть нужно выводить в консоль результат работы команды cmd по мере его поступления. Другими словами, подстановка $database в команду не происходит если вся команда не заключена в двойные кавычки. | |
|
|
|
|
|
|
|
для: Саня
(12.01.2011 в 16:04)
| | Хм... а если просто поместить команду "mysql ..." в обратные кавычки, без присвоения её result? | |
|
|
|
|
|
|
|
для: cheops
(12.01.2011 в 16:08)
| | Тогда не совершится подстановка $database и mysql вернёт ошибку, что база данных $database не существует. | |
|
|
|
|
|
|
|
для: Саня
(12.01.2011 в 16:14)
| | Я имею в виду, почему бы не выполнить запрос так
Строка разве не будет сформирована в виде полноценной команды? | |
|
|
|
|
|
|
|
для: cheops
(12.01.2011 в 16:16)
| | Я понял что вы имели ввиду, но почему-то выполнение команды обрывается, если выполнять её без eval. А ещё мне не нужен захват вывода команды. | |
|
|
|
|
|
|
|
для: cheops
(12.01.2011 в 16:16)
| | Если убрать всё лишнее
#!/bin/bash
database="db_need_to_be_optimized"
mysql -u root -pxxx -D database -e 'CALL optimize_tables("$database")'
|
Этот код выдаёт ошибку из-за того, что $database не подставляется. Даже если включить всю команду в обратные кавычки. | |
|
|
|
|
|
|
|
для: cheops
(12.01.2011 в 16:16)
| | Если переписать так
#!/bin/bash
database="db_need_to_be_optimized"
mysql -u root -pxxx -D database -e "CALL optimize_tables('$database')"
|
То переменная подставляется, но всё равно выводится всё одним куском, а не по мере выполнения оптимизации таблиц. | |
|
|
|
|
|
|
|
для: Саня
(12.01.2011 в 16:04)
| | Сам скрипт исполняется так как нужно и работает в комплексе с другими скриптами, проводящими техническое обслуживание сервера, запускающимися по крону. Однако изредка возникает потребность запускать скрипты отдельно. И мой вопрос касается только лишь удобства для администратора. А то таблиц много и раз можно выдавать отчёт по мере выполнения команды, почему бы не воспользоваться этим? Можно, конечно, сначала получить список таблиц и в цикле их обработать. Но хочу разобраться в изначальном вопросе.
Собственно, вот реализация с циклом:
tables=`mysql -u optimizer -p$pwd -D $database -e "SHOW TABLES" 2>/dev/null | grep -v "^Tables_in_$database$"`
for i in $tables ; do
mysql -u optimizer -p$pwd -D $database -e "OPTIMIZE TABLE $i" 2>/dev/null | grep '\.' | awk '{split($0,a,"\t");split(a[1],b,".");printf "%-30s %s\n", b[2], a[4]}'
done
| Недостаток в том, что пользователю optimizer нужны права INSERT и SELECT. А с хранимой процедурой только EXECUTE. Так как пароль зашит в скрипте, не хочется оставлять ещё один канал утечки и порчи информации. | |
|
|
|