
Estou consultando um banco de dados mysql para obter o nome de um banco de dados por padrão. Atualmente minha implementação está assim:
include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
| paste -sd ",")
O que retornará uma lista separada por vírgulas de nomes de bancos de dados que correspondem ao padrão.
No entanto, na verdade, espero que apenas um nome de banco de dados seja retornado e acho que seria melhor cometer um erro quando o mysql retornar um resultado com 2 linhas.
Existe algo como:
include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES LIKE 'foo%'" \
| __error_if_two_lines__ )
Responder1
Você pode usar head
para extrair a primeira linha:
include_databases=$(… | head -n 1)
No entanto, isso ignorará silenciosamente quaisquer outras linhas. Você pode usar o awk para retornar um código de saída diferente se houver mais linhas:
include_databases=$(… | awk 'NR>1 {exit(2)} 1')
if [ $? -ne 0 ]; then
echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
fi
Ou, sob set -e
:
include_databases=$(… | awk 'NR>1 {print "mysql returned multiple lines! Aborting." >"/dev/stderr"; exit(2)} 1')
Alternativamente, você pode armazenar a saída em uma variável e testar se ela contém uma quebra de linha. (Observe que a nova linha final do comando não está incluída na substituição do comando.)
include_databases=$(…)
nl='
'
case $include_databases in
*"$nl"*) echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac
Em ksh/bash/zsh, mas não em sh simples, você pode escrever isso de uma forma mais compacta.
include_databases=$(…)
if [[ "$include_databases" = *$'\n'* ]]; then
echo >&2 'mysql returned multiple lines! Aborting.'; exit 2;;
esac
Responder2
Acho que wc
é seu amigo. Use a opção -l
para contar linhas, -w
para contar palavras. (veja a página de manual)
mysql --batch --skip-column-names --execute "SHOW DATABASES" | wc -w
mostra o número de bancos de dados.
por exemplo, algo assim
include_databases=$(mysql --batch --skip-column-names --execute "SHOW DATABASES")
numDB=$(echo $include_databases | wc -w)
[ $numDB -gt 1 ] && echo -n "$numDB dbs is more than "
echo "one db"
Dica: você deve melhorar este script, pois ele usa muitos subsheels