2011-04-21 8 views
5

मैं अपने पायथन ऐप में पॉप अप करने के लिए विशेषाधिकार उन्नयन संवाद कैसे प्राप्त करूंगा? मैं विंडोज पर यूएसी संवाद और मैक पर पासवर्ड प्रमाणीकरण संवाद चाहता हूँ।मैक ओएस एक्स, विंडोज़ पर पाइथन में रूट संवाद प्राप्त करें?

असल में, मुझे अपने आवेदन के हिस्से के लिए रूट विशेषाधिकारों की आवश्यकता है और मुझे उन विशेषाधिकारों को जीयूआई के माध्यम से प्राप्त करने की आवश्यकता है। मैं wxPython का उपयोग कर रहा हूँ। कोई विचार?

+0

यह सुनिश्चित नहीं है कि आप इसे ओएसएक्स में पायथन लिपि के माध्यम से कर सकते हैं या नहीं। कुछ यूनिक्स-जैसे ओएस (ओएस एक्स शामिल) के तहत, स्क्रिप्ट्स (जैसे खोल, पर्ल, पायथन, ...) को चॉउन/चग्र को कॉल करने के लिए नहीं दिया जा सकता है जो आपको अन्य विशेषाधिकार देता है। – Drake

उत्तर

4

विंडोज़ पर आपको नई प्रक्रिया शुरू किए बिना यूएसी संवाद नहीं मिल सकता है, और आप CreateProcess के साथ उस प्रक्रिया को भी शुरू नहीं कर सकते हैं।

यूएसी संवाद को एक अन्य एप्लिकेशन चलाकर लाया जा सकता है जिसमें उपयुक्त मैनिफेस्ट फ़ाइल है - Running compiled python (py2exe) as administrator in Vista देखें कि इसे py2exe के साथ कैसे किया जाए।

तुम भी प्रोग्राम के Win32 एपीआई ShellExecute http://msdn.microsoft.com/en-us/library/bb762153(v=vs.85).aspx साथ runas क्रिया का उपयोग कर सकते हैं - आप ctypes http://python.net/crew/theller/ctypes/ जो 2.5+ अजगर पर iirc मानक पुस्तकालय का हिस्सा है का उपयोग करके यह कह सकते हैं।

क्षमा करें मैक के बारे में पता नहीं है। यदि आप विंडोज़ पर जो हासिल करना चाहते हैं उस पर अधिक जानकारी देते हैं तो मैं अधिक विशिष्ट सहायता प्रदान कर सकता हूं।

1

मुझे मैक ओएस एक्स पर एक ही समस्या है। मेरे पास एक कामकाजी समाधान है, लेकिन यह इष्टतम नहीं है। मैं यहां अपने समाधान की व्याख्या करूंगा और एक बेहतर खोजना जारी रखूंगा।

कार्यक्रम की शुरुआत में मैं जाँच अगर मैं क्रियान्वित

def _elevate(): 
    """Elevate user permissions if needed""" 
    if platform.system() == 'Darwin': 
     try: 
      os.setuid(0) 
     except OSError: 
      _mac_elevate() 

os.setuid द्वारा जड़ कर रहा हूँ या नहीं (0) असफल हो जायेगी अगर मैं पहले से ही जड़ नहीं कर रहा हूँ और उस _mac_elevate ट्रिगर किया जाएगा() जो osascript की मदद से व्यवस्थापक के रूप में शुरुआत से अपने कार्यक्रम को फिर से लॉन्च करता है। ऑस्स्क्रिप्ट का उपयोग सेबस्क्रिप्ट और अन्य सामान निष्पादित करने के लिए किया जा सकता है। मैं इसे इस तरह का उपयोग करें:

def _mac_elevate(): 
    """Relaunch asking for root privileges.""" 
    print "Relaunching with root permissions" 
    applescript = ('do shell script "./my_program" ' 
        'with administrator privileges') 
    exit_code = subprocess.call(['osascript', '-e', applescript]) 
    sys.exit(exit_code) 

इस के साथ समस्या यह है कि अगर मैं subprocess.call का उपयोग ऊपर के रूप में मैं वर्तमान प्रक्रिया चालू रखने और दो गोदी प्रतीक दे रही है चल मेरे ऐप के दो उदाहरणों हो जाएगा। यदि मैं इसके बजाय subprocess.Popen का उपयोग करता हूं और गैर-निजीकृत प्रक्रिया को तत्काल मरने देता हूं तो मैं बाहर निकलने वाले कोड का उपयोग नहीं कर सकता, न ही मैं stdout/stderr धाराएं ला सकता हूं और मूल प्रक्रिया शुरू करने के लिए टर्मिनल में प्रचार कर सकता हूं।

2

मुझे पता है कि पोस्ट थोड़ा पुराना है, लेकिन मैंने अपनी समस्या के समाधान के रूप में निम्नलिखित लिखा है (लिनक्स और ओएस एक्स दोनों पर रूट के रूप में एक पायथन लिपि चला रहा है)।

#!/bin/bash 

if [ -z "$1" ]; then 
    echo "Specify executable" 
    exit 1 
fi 

EXE=$1 

available(){ 
    which $1 >/dev/null 2>&1 
} 

platform=`uname` 

if [ "$platform" == "Darwin" ]; then 
    MESSAGE="Please run $1 as root with sudo or install osascript (should be installed by default)" 
else 
    MESSAGE="Please run $1 as root with sudo or install gksu/kdesudo!" 
fi 

if [ `whoami` != "root" ]; then 

    if [ "$platform" == "Darwin" ]; then 
     # Apple 
     if available osascript 
     then 
      SUDO=`which osascript` 
     fi 

    else # assume Linux 
     # choose either gksudo or kdesudo 
     # if both are avilable check whoch desktop is running 
     if available gksudo 
     then 
      SUDO=`which gksudo` 
     fi 
     if available kdesudo 
     then 
      SUDO=`which kdesudo` 
     fi 
     if (available gksudo && available kdesudo) 
     then 
      if [ $XDG_CURRENT_DESKTOP = "KDE" ]; then 
       SUDO=`which kdesudo`; 
      else 
       SUDO=`which gksudo` 
      fi 
     fi 

     # prefer polkit if available 
     if available pkexec 
     then 
      SUDO=`which pkexec` 
     fi 

    fi 

    if [ -z $SUDO ]; then 
     if available zenity; then 
      zenity --info --text "$MESSAGE" 
      exit 0 
     elif available notify-send; then 
      notify-send "$MESSAGE" 
      exit 0 
     elif available xmessage notify-send; then 
      xmessage -buttons Ok:0 "$MESSAGE" 
      exit 0 
     else 
      echo "$MESSAGE" 
     fi 
    fi 

fi 

if [ "$platform" == "Darwin" ] 
then 
    $SUDO -e "do shell script \"$*\" with administrator privileges" 
else 
    $SUDO [email protected] 
fi 

असल में, जिस तरह से मैं अपने सिस्टम की स्थापना की है कि मैं रखें:

मैं (लिनक्स और ओएस एक्स सिस्टम पर काम करता है) व्यवस्थापक विशेषाधिकारों के साथ बैश/अजगर आलेख निष्पादित करने के निम्नलिखित बैश-पटकथा लिखी बिन निर्देशिकाओं के अंदर subfolders (उदाहरण के लिए/usr/स्थानीय/बिन/pyscripts/usr/स्थानीय/बिन में), और निष्पादन योग्य के लिए प्रतीकात्मक लिंक बनाएँ। इसके लिए मेरे लिए तीन फायदे हैं:

(1) यदि मेरे पास अलग-अलग संस्करण हैं, तो मैं आसानी से स्विच कर सकता हूं जिसे प्रतीकात्मक लिंक बदलकर निष्पादित किया जाता है और यह बिन निर्देशिका क्लीनर (उदाहरण/usr/local/bin/gcc -वर्सन/4.9 /, /usr/local/bin/gcc-versions/4.8/,/usr/local/bin/gcc -> gcc-version/4.8/gcc)

(2) मैं स्टोर कर सकता हूं उनके एक्सटेंशन के साथ स्क्रिप्ट (आईडीई में हाइलाइटिंग सिंटैक्स के लिए सहायक), लेकिन निष्पादन योग्य में उन्हें शामिल नहीं किया गया क्योंकि मुझे यह पसंद है (जैसे svn-tools -> pyscripts/svn-tools।py)

(3) कारण मैं नीचे प्रदर्शित करेगी:

मैं स्क्रिप्ट को नाम "चलाने के रूप में रूट आवरण" और एक बहुत ही आम रास्ते में यह जगह (जैसे/usr/स्थानीय/bin) इसलिए पाइथन को इसे ढूंढने के लिए विशेष चीज़ की आवश्यकता नहीं है। तब मैं निम्नलिखित run_command.py मॉड्यूल है:

import os 
import sys 
from distutils.spawn import find_executable 

#===========================================================================# 

def wrap_to_run_as_root(exe_install_path, true_command, expand_path = True): 
    run_as_root_path = find_executable("run-as-root-wrapper") 

    if(not run_as_root_path): 
     return False 
    else: 
     if(os.path.exists(exe_install_path)): 
      os.unlink(exe_install_path) 

     if(expand_path): 
      true_command = os.path.realpath(true_command) 
      true_command = os.path.abspath(true_command) 
      true_command = os.path.normpath(true_command) 

     f = open(exe_install_path, 'w') 
     f.write("#!/bin/bash\n\n") 
     f.write(run_as_root_path + " " + true_command + " [email protected]\n\n") 
     f.close() 
     os.chmod(exe_install_path, 0755) 

     return True 

मेरे वास्तविक अजगर स्क्रिप्ट में, मैं निम्नलिखित कार्य हो:

def install_cmd(args): 
    exe_install_path = os.path.join(args.prefix, 
            os.path.join("bin", args.name)) 

    if(not run_command.wrap_to_run_as_root(exe_install_path, sys.argv[0])): 
     os.symlink(os.path.realpath(sys.argv[0]), exe_install_path) 

तो अगर मैं एक स्क्रिप्ट TrackingBlocker.py (वास्तविक स्क्रिप्ट कहा जाता रहा ज्ञात ट्रैकिंग डोमेन को 127.0.0.1 को फिर से रूट करने के लिए/etc/hosts फ़ाइल को संशोधित करने के लिए उपयोग करें), जब मैं "sudo /usr/local/bin/pyscripts/TrackingBlocker.py --prefix/usr/local --name ModifyTrackingBlocker को कॉल करता हूं इंस्टॉल करें "(Argparse मॉड्यूल के माध्यम से प्रबंधित तर्क), यह"/usr/local/bin/ModifyTrackingBlocker "स्थापित करता है, जो

निष्पादित एक बैश स्क्रिप्ट है
/usr/local/bin/run-as-root-wrapper /usr/local/bin/pyscripts/TrackingBlocker.py [args] 

उदा।

ModifyTrackingBlocker add tracker.ads.com 

कार्यान्वित:

/usr/local/bin/run-as-root-wrapper /usr/local/bin/pyscripts/TrackingBlocker.py add tracker.ads.com 

जो तब authentification संवाद विशेषाधिकार जोड़ने के लिए प्राप्त करने के लिए आवश्यक प्रदर्शित करता है:

127.0.0.1 tracker.ads.com 

मेरी होस्ट फ़ाइल से (जो एक सुपर उपयोगकर्ता द्वारा केवल लिखने योग्य है) ।

आप को आसान बनाने/रूट के रूप में केवल कुछ आदेश को चलाने के लिए इसे संशोधित करना चाहते हैं, तो आप बस इस अपनी स्क्रिप्ट के लिए (आवश्यक आयात के साथ ऊपर स्थित + आयात उपप्रक्रिया विख्यात) जोड़ सकते हैं: ऊपर का उपयोग

def run_as_root(command, args, expand_path = True): 
    run_as_root_path = find_executable("run-as-root-wrapper") 

    if(not run_as_root_path): 
     return 1 
    else: 
     if(expand_path): 
      command = os.path.realpath(command) 
      command = os.path.abspath(command) 
      command = os.path.normpath(command) 

     cmd = [] 
     cmd.append(run_as_root_path) 
     cmd.append(command) 
     cmd.extend(args) 

     return subprocess.call(' '.join(cmd), shell=True) 

(run_command मॉड्यूल में):

>>> ret = run_command.run_as_root("/usr/local/bin/pyscripts/TrackingBlocker.py", ["status", "display"]) 
>>> /etc/hosts is blocking approximately 16147 domains