سؤال

تحيات.

لقد كتبت نصًا صغيرًا بيثون يستدعي MySQL في عملية فرعية.[نعم، أعلم أن النهج الصحيح هو استخدام MySQLdb، ولكن تجميعه ضمن OS X Leopard يعد أمرًا مؤلمًا، وربما أكثر إيلامًا إذا أردت استخدام البرنامج النصي على أجهزة كمبيوتر ذات بنيات مختلفة.] تعمل تقنية العملية الفرعية، بشرط أن أقوم بتوفير كلمة المرور في الأمر الذي يبدأ العملية؛ومع ذلك، فهذا يعني أن المستخدمين الآخرين على الجهاز يمكنهم رؤية كلمة المرور.

يمكن رؤية الكود الأصلي الذي كتبته هنا.

هذا المتغير أدناه مشابه جدًا، على الرغم من أنني سأحذف روتين الاختبار لإبقائه أقصر:

#!/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

أشك في أن مطالبة كلمة مرور MySQL ليست في الواقع على stdout (أو stderr)، على الرغم من أنني لا أعرف كيف يمكن أن يكون ذلك أو إذا كان ذلك يعني أنني أستطيع محاصرة ذلك.

لقد حاولت قراءة المخرجات أولاً، قبل توفير كلمة المرور، لكنها لم تنجح.لقد حاولت أيضًا تمرير كلمة المرور

مرة أخرى، إذا قمت بتوفير كلمة المرور في سطر الأوامر (وبالتالي لا يوجد رمز بين وظيفتي "الفتح" و"الاتصال") فإن وظيفتي الملتفة تعمل.


فكرتان جديدتان، بعد أشهر:

  1. استخدام توقع اسمحوا لي أن توفير كلمة المرور.إنه يحاكي tty ويحصل على كل المخرجات، حتى تلك التي تتجاوز stdout وstderr.

  2. هناك مشروع اسمه رابط MySQL/بايثون, ، في أوائل ألفا، سيسمح ذلك بتوفير مكتبة بايثون خالصة للوصول إلى MySQL، دون الحاجة إلى ترجمة أي كود C.

هل كانت مفيدة؟

المحلول

يمكنك ببساطة إنشاء ملف my.cnf والإشارة إليه في أمر mysql.من الواضح أنك ستحتاج إلى حماية هذا الملف بالأذونات/وصول الوصول.ولكن لا ينبغي أن يكون الأمر أكثر/أقل أمانًا حقًا من وجود كلمة المرور في برنامج python النصي الخاص بك، أو التكوين الخاص ببرنامج python النصي الخاص بك.

لذلك سوف تفعل شيئا من هذا القبيل

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

وسيبدو التكوين الخاص بك على هذا النحو

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

نصائح أخرى

الطريقة الآمنة الوحيدة هي استخدام ملف MySQL cnf كما ذكر أحد الملصقات الأخرى.يمكنك أيضًا تمرير متغير env MYSQL_PWD، لكن هذا غير آمن أيضًا: http://dev.mysql.com/doc/refman/5.0/en/password-security.html

وبدلاً من ذلك، يمكنك التواصل مع قاعدة البيانات باستخدام ملف مقبس Unix ومع القليل من التغيير والتبديل يمكنك التحكم في الأذونات على مستوى معرف المستخدم.

والأفضل من ذلك، يمكنك استخدام حزمة BitNami المجانية DjangoStack التي تحتوي على Python وMySQLDB المترجمة مسبقًا لنظام التشغيل OS X (وWindows وLinux) http://bitnami.org/stacks

قد تكون هذه إحدى ميزات Windows / SQL Server، ولكن هل يمكنك استخدام اتصال موثوق به (على سبيل المثال؟استخدام تسجيل الدخول/كلمة المرور لنظام التشغيل الخاص بك للوصول إلى قاعدة البيانات)؟قد يكون هناك نظام OS X مكافئ لـ MySQL.

أو قد تحتاج فقط إلى إعداد قاعدة البيانات الخاصة بك لاستخدام معلومات تسجيل الدخول وكلمة المرور لنظام التشغيل بحيث لا تحتاج إلى الاحتفاظ بهما في التعليمات البرمجية الخاصة بك.

على أية حال، مجرد فكرة.

جرب هذا:

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

return stdout

اتصل بـ communication() لفرض إرسال ما كتبته للتو إلى المخزن المؤقت.ومن الجيد أيضًا إغلاق stdin عند الانتهاء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top