Я знаю, что пост немного устарел, но я написал следующее в качестве решения моей проблемы (запуск сценария python от имени root как в Linux, так и в OS X).
Я написал следующий bash-сценарий для выполнения сценариев bash / python с правами администратора (работает в системах Linux и OS X):
#!/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 $@
fi
По сути, я настраиваю свою систему так, что я храню подпапки внутри каталогов bin (например, /usr / local / bin / pyscripts в / usr / local / bin) и создайте символические ссылки на исполняемые файлы.Для меня это имеет три преимущества:
(1) Если у меня есть разные версии, я легко могу выбрать, какая из них выполняется, изменив символическую ссылку, и она сохранит каталог bin более чистым (например, / usr / local / bin/gcc-versions/4.9/, /usr/local/bin/gcc-versions/4.8/, / usr / local / bin / gcc -> gcc-version / 4.8 / gcc)
(2)Я могу хранить сценарии с их расширением (полезно для подсветки синтаксиса в IDE), но исполняемые файлы не содержат их, потому что мне это нравится (например, svn-tools -> pyscripts / svn-tools.py)
(3) Причина, которую я покажу ниже:
Я называю скрипт «run-as-root-wrapper» и помещаю его в очень общий путь (например, / usr / local / bin), поэтому pythonне нужно ничего особенного, чтобы найти это.Затем у меня есть следующий модуль 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 + " $@\n\n")
f.close()
os.chmod(exe_install_path, 0755)
return True
В моем собственном скрипте Python у меня есть следующая функция:
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(фактический скрипт, который я использую для изменения файла / etc / hosts для перенаправления известных доменов отслеживания на 127.0.0.1), когда я вызываю "sudo /usr/local/bin/pyscripts/TrackingBlocker.py --prefix / usr / local--name ModifyTrackingBlocker install "(аргументы обрабатываются с помощью модуля argparse), он устанавливает" / usr / local / bin / ModifyTrackingBlocker ", который является bash-скриптом, выполняющим
/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
, который затем отображает диалоговое окно аутентификации, необходимое для получения привилегий для добавления:
127.0.0.1 tracker.ads.com
в мой файл hosts (который доступен для записи только суперпользователю).
Если вы хотите упростить / изменить его для запуска только определенных команд от имени пользователя root, вы можете просто добавить это в свой скрипт (с необходимыми импортами, отмеченными выше + подпроцесс импорта):
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)
Используя вышеупомянутое (в rмодуль un_command):
>>> ret = run_command.run_as_root("/usr/local/bin/pyscripts/TrackingBlocker.py", ["status", "display"])
>>> /etc/hosts is blocking approximately 16147 domains