2011-05-07 54 views
12

Necesito un script bash que pueda recuperar datos de MySQL desde una base de datos remota. En realidad lo he hecho, pero lo que necesito ahora es recorrer los registros de alguna manera y pasar una variable a otro archivo bash. Aquí es mi llamada MySQL:Bash Script Loop a través de MySQL

mysql -X -u $MyUSER -p$MyPASS -h$MyHOST -D$MyDB -e'SELECT `theme_name`, `guid` FROM `themes` WHERE `theme_purchased`="1" AND `theme_compiled`='0';' > themes.xml 
download_themes.sh 

Exporta los datos en un archivo XML denominado theme.xml en este momento, sólo estaba tratando de encontrar alguna forma de bucle a través de los datos. Estoy tratando de evitar PHP y Perl y solo intento usar bash. Gracias por adelantado.

+4

¿Hay algún motivo específico por el que desee evitar los lenguajes de scripting? No podrás analizar correctamente el xml en bash. Incluso podría tener problemas para eliminar la salida. ¿Por qué no ir por el camino fácil y usar php/perl/python/lua/java/tcl/javascript/... o algo en serio aparte de bash que simplemente no podrá hacer esto correctamente para muchos productos? – viraptor

+0

¿No sabe si hay una forma de generar resultados como una matriz y recorrer ese proceso? Busqué en Google esto, no pude encontrar nada. –

Respuesta

33

algo como:

mysql -e "SELECT `theme_name`, `guid` FROM `themes` WHERE `theme_purchased`='1' AND `theme_compiled`='0'" | while read theme_name guid; do 
    # use $theme_name and $guid variables 
    echo "theme: $theme_name, guid: $guid" 
done 

en resumen: las salidas de grabación mysql comandos separados por '\ n' y campos separados por '\ t' cuando la salida es una pipa. el comando read lee una línea, se divide en campos y pone cada uno en una variable.

si sus datos tienen espacios en los campos, se producen algunos problemas con la división predeterminada read. hay algunas formas de evitarlo; pero si solo está leyendo dos campos y uno de ellos no debería tener espacios (como el guid), entonces puede poner el campo 'peligroso' al final, y read pondrá todo 'extra' en la última variable .

así:

mysql -e "SELECT `guid` `theme_name`, FROM `themes` WHERE `theme_purchased`='1' AND `theme_compiled`='0'" | while read guid theme_name; do 
    # use $theme_name and $guid variables 
    echo "theme: $theme_name, guid: $guid" 
done 
+0

Parece haber funcionado la primera vez, pero ahora me da esto: /winterboard_theme_builder/get_themes.sh: línea 9: error de sintaxis cerca del token inesperado 'done ' /winterboard_theme_builder/get_themes.sh: línea 9: 'hecho ' –

+0

En realidad, el do estaba en la línea incorrecta, pero luego aparece un error diferente. Dice /winterboard_theme_builder/get_themes.sh: línea 7: leer: 'theme_name, ': no ​​es un identificador válido –

+0

oh, a la derecha. no hay comas entre los argumentos 'leídos', y un punto y coma antes de 'do'. fijo – Javier

2

lugar de salida XML, puede sugiero sólo tiene que utilizar la sintaxis SELECT INTO OUTFILE o mysql --batch --raw de valores separados por tabuladores de salida. A continuación, tiene un acceso mucho más fácil a través de bash al resto de la cadena de herramientas de Unix, como cut y awk para recuperar los campos que necesita y reutilizarlos con Bash. No es necesario ningún otro lenguaje de scripting y no necesita meterse con XML.

mysql --batch --raw -u $MyUSER -p$MyPASS -h$MyHOST -D$MyDB -e'SELECT `theme_name`, `guid` FROM `themes` WHERE `theme_purchased`="1" AND `theme_compiled`='0';' \ 
| awk '{print "theme: " $1 " guid: " $2}' 
3

La respuesta aceptada no funciona cuando hay espacios en la salida. Es una solución fácil (IFS = $ '\ t' - Tenga en cuenta el $ - es raro):


>mysql ... -BNr -e "SELECT 'funny man', 'wonderful' UNION SELECT 'no_space', 'I love spaces';" | while IFS=$'\t' read theme_name guid; do echo "theme: $theme_name guid: $guid"; done 
theme: funny man guid: wonderful 
theme: no_space guid: I love spaces 

Usted, por supuesto, quieren sustituir su propia consulta.

1

Pipe '|' while es peligroso, ya que los cambios dentro del ciclo ocurren en otro subproceso y no tendrán efecto en el script actual.

Por cierto, odio recurrir a la solución de archivos externos.

Sugiero usar "Process Substitute".

while read field1 field2 field3 
do 
done < <(mysql -NB -e "$sql") 
# ^
# space needed 
+0

cómo detectar si la consulta/conexión mysql falla, en este caso? – Siva

Cuestiones relacionadas