Если вы хотите '$dbserver'
в запросе расширенного внутри цикла, вы, вероятно, написать:
while read dbserver username password dbname type
do
query="select '$dbserver' as server;"
mysql -h$dbserver -u$username -p$password $dbname -Be"$query"
done < $dblist > /home/develop/myreport.csv
Как первоначально написано, строка запроса оценивается до того, как любое значение будет присвоено $dbserver
, поэтому вы получили пустую строку на выходе.
Обратите внимание, что перенаправление вывода выполнялось только один раз - на линии done
, а не каждый раз в цикле (что означает, что вам больше не нужно добавлять).
Получение запроса, созданного за пределами цикла, как правило, то, что вы можете сделать, используя eval
. Однако, поскольку значение $dbserver
заключено внутри одинарных кавычек, это оказывается hard. Если СУБД вы используете позволяет использовать двойные кавычки вокруг строк (вопреки стандарту SQL), то работает с Eval:
query='select \"$dbserver\" as server;'
echo "$query"
while read dbserver username password dbname type
do
echo 1: "$query"
eval echo 2: "$query"
qval=$(eval echo "$query")
echo mysql -h$dbserver -u$username -p$password $dbname -Be"$qval"
done
Вы можете приспособить это использовать одиночные кавычки, заменив '"
«с» ''\''
последовательности:
query='select \'\''$dbserver\'\'' as server;'
echo "$query"
while read dbserver username password dbname type
do
echo 1: "$query"
eval echo 2: "$query"
qval=$(eval echo "$query")
echo mysql -h$dbserver -u$username -p$password $dbname -Be"$qval"
done
То есть, однако, своего рода цитатой последовательности, которая посылает здравомыслящих людей от крика комнаты - простите мне момент, когда я освободить помещение грохотом! [... позже ...] Это лучше!
Объяснение:
- Общая строка в одинарных кавычках.
- В такой строке нет escape-символов.
- Следовательно, первая обратная косая черта - это просто обратная косая черта.
- Следующие 4 символа - это последовательность
'\''
.
- Первый из этих кавычек завершает текущую строку с одной кавычкой.
- Обратная косая черта приостанавливает специальное значение следующего символа, так что строка содержит фактическую одинарную кавычку из второй одиночной кавычки в последовательности.
- Третья одиночная кавычка запускает новую строку с одним кавычком.
- Итак, после обработки первой последовательности обратных косых черт и кавычек строка содержит обратную косую черту и одну кавычку.
- $ dbserver - это обычный текст в данный момент.
- Затем мы повторяем предыдущую последовательность, в результате получим вторую пару обратной косой черты в строке.
- Все нормально для последней отдельной цитаты на линии.
Процесс eval
запускает дополнительную партию расширения на строку. Пары обратной косой черты заменяются просто цитатой; вставляется текущее значение $dbserver
. Затем это можно передать команде как обычный аргумент.
Сложность с eval
гарантирует, что вы не получите неожиданных побочных эффектов. Это вдвойне сложнее с MySQL, который использует обратные кавычки для включения ключевых слов, используемых в качестве токенов. Разумеется, эта нотация взаимодействует дьявольски с eval
. Тем не менее, одинарные кавычки вокруг всего запроса и обратной косой черты вместо обратной кавычки каждой обратной кавычки, вы можете это сделать:
query='select \'\''$dbserver\'\'' as server, \`ls\` as column;'
echo "$query"
while read dbserver username password dbname type
do
echo 1: "$query"
eval echo 2: "$query"
qval=$(eval echo "$query")
echo mysql -h$dbserver -u$username -p$password $dbname -Be"$qval"
done
Я не думаю, что это может быть рекомендовано, однако.
Спасибо. Я хотел, чтобы запрос был помещен в начало скрипта и вышел из цикла, потому что его было бы легче отредактировать позже. – shantanuo
@shantanuo: вы можете это сделать - см. Мой расширенный ответ. Я не уверен, что требуемая нотация дает вам пользу, которую вы ищете; сложнее получить запрос правильно. –