Сменить пользователя (su) через скрипт Python (pexpect, popen)

Я запускаю скрипт Python с user1, и в этом скрипте мне нужно переместить файл в папку, к которой у меня нет доступа. Папка принадлежит user2.

Что я хочу сделать, так это:
- перейти с user1 на user2 с помощью su - user2
- ввести пароль
- переместить файл

До сих пор я пробовал с Popen :

p = subprocess.Popen(["su", "-", "user2"])
p.communicate("user2_password")
p.communicate("mv path/to/file other/path/to/file")

Не работает, мне нужно вручную ввести пароль в оболочке.


И я также пробовал с pexpect :

child = pexpect.spawn('su - user2')
child.expect ('Password:')
child.sendline('user2_password')
child.sendline('mv path/to/file other/path/to/file')

Скрипт запускается, но ничего не происходит, и после запуска скрипта я все еще user1.

Любая идея, почему? Что бы это ни стоило, похоже, что это относится к su, потому что, если я пишу скрипт с sudo, он работает (я могу ввести пароль).

Спасибо за помощь !


person Edouard Cuny    schedule 16.06.2017    source источник
comment
su и sudo разные. Возможно, ваш пароль root отличается от пароля sudo пользователя User2.   -  person Ludisposed    schedule 16.06.2017
comment
я проверял, они одинаковые!   -  person Edouard Cuny    schedule 16.06.2017


Ответы (1)


Ваша команда не работает, так как вы ничего не ожидаете после отправки пароля. В зависимости от вашей оболочки и т. д., вы получите своего рода командную строку после успешного выполнения su. Моя подсказка такова:

klunssi@xyzzy:~$

На самом деле печать этого приглашения включает в себя множество специальных символов для управления выводом tty, поэтому я просто хочу получить завершающий $:

child = pexpect.spawn('su - klunssi')
child.expect ('Password:')
child.sendline('klunssi')
child.expect('\$')
child.sendline('mv /home/klunssi/foo /home/klunssi/bar')

Это работает и делает ход.

Это не оставляет меня с учетной записью «klunssi», поскольку pexpect.spawn() создает подпроцесс, и там происходит su.

Если у вас есть root-доступ к системе, я предлагаю изменить /etc/sudoers и добавить sudo без пароля, чтобы ваш user1 мог выполнять команды как user2. Это намного надежнее, так как вам вообще не нужен pexpect, и вы можете просто

Popen(["sudo", "-u", "user2", "yourcommand"])

Если это не вариант, то указанный выше pexpect должен помочь.

Ханну

person Hannu    schedule 16.06.2017