IOError: 13, «Отказано в доступе» при записи в /etc/hosts через Python

У меня есть приложение Python, над которым я работаю, которому необходимо получить доступ к файлу hosts, чтобы добавить несколько строк. С моим тестовым файлом все работало, но когда я сказал программе изменить файл hosts в /etc/hosts, я получил IOError 13. Насколько я понимаю, у моего приложения нет привилегий root.

У меня вопрос, как я могу обойти эту проблему? Есть ли способ запросить у пользователя пароль? Был бы процесс другим, если бы я запускал приложение на компьютере с Windows?

Вот код, о котором идет речь:

f = open("/etc/hosts", "a")
f.write("Hello Hosts File!")

Кроме того, я планирую использовать py2app и py2exe для конечного продукта. Решат ли они проблему с привилегиями root для меня?


person Parker    schedule 22.09.2011    source источник


Ответы (2)


Самый простой способ справиться с этим — записать изменения во временный файл, а затем запустить программу для перезаписи защищенного файла. Вот так:

with open('/etc/hosts', 'rt') as f:
    s = f.read() + '\n' + '127.0.0.1\t\t\thome_sweet_home\n'
    with open('/tmp/etc_hosts.tmp', 'wt') as outf:
        outf.write(s)

os.system('sudo mv /tmp/etc_hosts.tmp /etc/hosts')

Когда ваша программа Python запускает sudo, программа sudo запросит у пользователя пароль. Если вы хотите, чтобы это было основано на графическом интерфейсе, вы можете запустить sudo с графическим интерфейсом, например «gksu».

В Windows файл hosts спрятан в нескольких подкаталогах под \Windows. Вы можете использовать тот же общий прием, но в Windows нет команды sudo. Вот обсуждение эквивалентов:

https://superuser.com/questions/42537/is-there-any-sudo-command-for-windows

person steveha    schedule 22.09.2011
comment
Спасибо, это близко к тому, что мне нужно. Однако сценарий является графическим, поэтому есть ли способ передать строку системе для аутентификации? Я бы хотел, чтобы пользователь не вводил текст в терминал - person Parker; 23.09.2011
comment
Если вы запустите gksu, как я предложил, он предложит пользователю в диалоговом окне графического интерфейса. Если вы запустите простой sudo, это вызовет запрос в терминале. - person steveha; 23.09.2011
comment
Извините, почему-то не уловил. Но, у меня нет gksu, не знаете, что может быть похожего для QT? - person Parker; 23.09.2011
comment
Я этого не знаю, но я только что провел поиск в Google по запросу QT, эквивалентному sudo, и нашел эту страницу в Википедии: en.wikipedia.org/wiki/ Похоже, kdesu или kdesudo могут вам подойти. - person steveha; 23.09.2011

Если вы находитесь в списке sudoers, вы можете начать свою программу с sudo:

 sudo python append_to_host.py

sudo запускает ваш интерпретатор Python с привилегиями root. В первый раз, когда вы это сделаете, вас попросят ввести ваш пароль, последующие вызовы не будут спрашивать вас, был ли ваш последний sudo вызов не так давно.

Нахождение в списке sudoers (в большинстве случаев /etc/sudoers) говорит о том, что админ вам доверяет. Если вы позвоните sudo, вас спросят не root пароль, а ваш. Вы должны доказать, что за терминалом сидит правильный пользователь.

Подробнее о sudo на http://en.wikipedia.org/wiki/Sudo

Если вы хотите управлять этим удаленно, вы можете использовать переключатель командной строки -S или использовать http://www.noah.org/wiki/pexpect

person rocksportrocker    schedule 22.09.2011
comment
Спасибо, но в идеале я бы не хотел, чтобы пользователь запускал скрипт как sudo. Есть ли способ сделать это для них в фоновом режиме, если у меня есть их пароль? - person Parker; 23.09.2011
comment
Я провел дополнительное исследование «sudo -S», и похоже, что это то, что я могу использовать для передачи введенного пользователем пароля в систему. Спасибо! - person Parker; 23.09.2011