Как я могу запускать программу в качестве другого пользователя во всех отношениях?

Задний план

Я пытаюсь регулярно перезапускать некоторые программы ( mail-notification и stalonetray ), поскольку они, кажется, часто умирают. Я хочу перезапустить их, когда NetworkManager снова подключится. Следовательно, я их вызвал сценарий в /etc/NetworkManager/dispatcher.d/ .

Scripting

Я могу создать скрипт следующим образом.

 #!/bin/bash sudo -u foo_user pkill mail-notificati -x sudo -u foo_user DISPLAY=:0 mail-notification & 

Это отлично работает, если я запускаю его непосредственно как пользователь. Однако, если я вызываю это из корневого скрипта, он терпит неудачу. Мне предлагается ввести пароли для mail-notification ; он не может читать Gnome Keyring.

Как я могу запускать эту программу как foo_user во всех отношениях?

Если вы хотите взаимодействовать с графическим интерфейсом из процесса, который не запускается из этого графического интерфейса, вам необходимо установить несколько переменных среды: по крайней мере, DISPLAY , возможно, также XAUTHORITY если он не находится по умолчанию, и для многих современных вам необходимо установить DBUS_SESSION_BUS_ADDRESS .

Но более надежным подходом к вашей проблеме было бы не перезапускать эти программы из NetworkManager. В дополнение к сложности их успешного запуска вам также нужно беспокоиться о том, что вы вообще вошли в систему, и если могут быть другие пользователи и другие дисплеи, которые необходимо учитывать, и так далее. Вместо этого убейте эти программы, но не перезагружайте их. В своем обычном сеансе вместо их непосредственного запуска запустите их из супервизора, который перезапустит их, если они умрут. Я думаю, systemd включает эту функциональность (но я не знаю, как ее использовать); или вы можете использовать специальные программы супервизора, такие как monit , supervise , …

Вы всегда можете использовать добрый старый su :

man 1 su

Эта команда открывает подчиненную оболочку как пользователь, которого вы хотите выдать. В качестве пользователя root вы можете использовать его, не запрашивая пароль.

su foo_user -c whatevercommandyouwant

Работает и из скриптов.