Question

Salutations.

J'ai écrit un petit script python qui appelle MySQL dans un sous-processus. [Oui, je sais que la bonne approche consiste à utiliser MySQLdb, mais sa compilation sous OS X Leopard est pénible et probablement plus pénible si je souhaite utiliser le script sur des ordinateurs d'architectures différentes.] La technique de sous-processus fonctionne, à condition que Je fournis le mot de passe dans la commande qui lance le processus; cependant, cela signifie que les autres utilisateurs de la machine pourraient voir le mot de passe.

Le code original que j'ai écrit est visible ici .

Cette variante ci-dessous est très similaire, même si je vais omettre la routine de test pour la raccourcir:

#!/usr/bin/env python

from subprocess import Popen, PIPE

# Set the command you need to connect to your database
mysql_cmd_line = "/Applications/MAMP/Library/bin/mysql -u root -p"
mysql_password = "root"

def RunSqlCommand(sql_statement, database=None):

    """Pass in the SQL statement that you would like executed.
    Optionally, specify a database to operate on.  Returns the result."""

    command_list = mysql_cmd_line.split()
    if database:
        command_list.append(database)

    # Run mysql in a subprocess
    process = Popen(command_list, stdin=PIPE, stdout=PIPE,
                    stderr=PIPE, close_fds=True)

    #print "Asking for output"
    #needs_pw = process.stdout.readline()
    #print "Got: " + needs_pw

    # pass it in the password
    process.stdin.write(mysql_password + "\n")

    # pass it our commands, and get the results
    #(stdout, stderr) = process.communicate( mysql_password + "\n" + sql_statement)
    (stdout, stderr) = process.communicate( sql_statement )

    return stdout

Je soupçonne que l'invite de mot de passe MySQL n'est pas réellement sur stdout (ou stderr), bien que je ne sache pas comment cela pourrait être ou si cela signifie que je pourrais le piéger.

J'ai d'abord essayé de lire la sortie avant de fournir un mot de passe, mais cela n'a pas fonctionné. J'ai aussi essayé de passer le mot de passe

Encore une fois, si je fournis le mot de passe sur la ligne de commande (et ne dispose donc d'aucun code entre les fonctions "Popen" et "communiquer"), ma fonction encapsulée fonctionne.

Deux nouvelles pensées, des mois plus lents:

  1. L'utilisation de pexpect me permettrait de fournir un mot de passe. Il simule un tty et obtient toutes les sorties, même celles qui contournent stdout et stderr.

  2. Il existe un projet appelé Connecteur MySQL / Python , qui permet de fournir une bibliothèque python pure pour accéder à MySQL, sans avoir à compiler de code C.

Était-ce utile?

La solution

Vous pouvez simplement créer un fichier my.cnf et y indiquer la commande mysql. Évidemment, vous voudrez protéger ce fichier avec permissions / acls. Mais il ne devrait pas être vraiment plus / moins sûr d’avoir le mot de passe dans votre script python, ou la configuration de votre script python.

Vous feriez donc quelque chose comme

mysql_cmd_line = "/Applications/MAMP/Library/bin/mysql --defaults-file=credentials.cnf"

et votre configuration ressemblerait à ceci

[client]
host     = localhost
user     = root
password = password
socket   = /var/run/mysqld/mysqld.sock

Autres conseils

La seule méthode sécurisée consiste à utiliser un fichier cnf MySQL comme l’indique l’une des autres affiches. Vous pouvez également passer une variable env MYSQL_PWD, mais cela n’est pas sûr non plus: http://dev.mysql.com/doc/refman/5.0/fr/password-security.html

Alternativement, vous pouvez communiquer avec la base de données à l'aide d'un fichier de socket Unix et, avec quelques ajustements, vous pouvez contrôler les autorisations au niveau de l'ID utilisateur.

Encore mieux, vous pouvez utiliser la pile gratuite BitNami DjangoStack qui a pré-compilé Python et MySQLDB pour OS X (et Windows et Linux) http://bitnami.org/stacks

Il s’agit peut-être d’une fonctionnalité Windows / SQL Server, mais pouvez-vous utiliser une connexion sécurisée (c’est-à-dire utiliser votre identifiant / mot de passe du système d’exploitation pour accéder à la base de données)? Il peut y avoir un équivalent de Mac OS X pour MySQL.

Ou vous devrez peut-être simplement configurer votre base de données pour utiliser le nom d'utilisateur et le mot de passe du système d'exploitation, de sorte que vous n'ayez pas besoin de les conserver dans votre code.

En tout cas, juste une idée.

Essayez ceci:

process.stdin.write(mysql_password + "\n")
process.communicate()
(stdout, stderr) = process.communicate( sql_statement )
process.stdin.close()

return stdout

Appelez communic () pour forcer l’envoi de ce que vous venez d’écrire dans le tampon. En outre, il est bon de fermer stdin lorsque vous avez terminé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top