Как я могу запустить Perl-скрипт от имени пользователя root, но все же повлиять на пользовательские настройки gconf
НОВЫЙ ЗАПРОС: Я пытаюсь создать единый сценарий, который инициализирует новую установку Ubuntu по своему вкусу, для установки пакетов его необходимо запустить под sudo, но использование gconftool-2 для влияния на настройку gconf зависит от сеанса dbus, который не обрабатывается правильно методом простого изменения UID только в скрипте. Кто-нибудь знает, как это сделать?
СТАРЫЙ ЗАПРОС: Я пишу Perl-скрипт, который будет выполняться при первой загрузке новой установки Ubuntu. Это облегчает добавление репозиториев, установку пакетов и настройку параметров gconf. Моя проблема - разрешения. Для установки пакетов мне нужно, чтобы скрипт выполнялся как sudo, но затем вызов gconftool-2 действует от имени пользователя root, а не от моего личного пользователя.
3 ответа
После долгих чтений, проб и ошибок кажется, что при запуске скрипта от имени root отсутствует то, что переменная среды DBUS_SESSION_BUS_ADDRESS не установлена. Это должно быть установлено И ИД пользователя должен быть изменен на пользовательский, прежде чем настройки gconf могут быть установлены. Это мой тестовый скрипт, который я использовал, чтобы опробовать его. Выполните один или другой из системных вызовов в конце, чтобы изменить порядок кнопок окна. Попробуйте скрипт как пользователь или как root (sudo), чтобы увидеть, что он работает.
#!/usr/bin/perl
use strict;
use warnings;
use POSIX;
# get the user's name (as opposed to root)
my $user_name = getlogin();
# get the uid of the user by name
my $user_uid = getpwnam($user_name);
print $user_name . ": " . $user_uid . "\n";
my %dbus;
# get the DBUS machine ID
$dbus{'machine_id'} = qx{cat /var/lib/dbus/machine-id};
chomp( $dbus{'machine_id'} );
# read the user's DBUS session file to get variable DBUS_SESSION_BUS_ADDRESS
$dbus{'file'} = "/home/" . $user_name . "/.dbus/session-bus/" . $dbus{'machine_id'} . "-0";
print "checking DBUS file: " . $dbus{'file'} . "\n";
if (-e $dbus{'file'}) {
open(my $fh, '<', $dbus{'file'}) or die "Cannot open $dbus{file}";
while(<$fh>) {
if ( /^DBUS_SESSION_BUS_ADDRESS=(.*)$/ ) {
$dbus{'address'} = $1;
print "Found DBUS address: " . $dbus{'address'} . "\n";
}
}
} else {
print "cannot find DBUS file";
}
# set the uid to the user's uid not root's
POSIX::setuid($user_uid);
# set the DBUS_SESSION_BUS_ADDRESS environment variable
$ENV{'DBUS_SESSION_BUS_ADDRESS'} = $dbus{'address'};
my $command1 = 'gconftool-2 --set "/apps/metacity/general/button_layout" --type string "menu:maximize,minimize,close"';
my $command2 = 'gconftool-2 --set "/apps/metacity/general/button_layout" --type string "menu:minimize,maximize,close"';
system($command1);
## or
#system($command2);
Примечание: есть хорошая информация здесь.
Вы можете изменить UID в середине скрипта, изменив UID с помощью POSIX::setuid()
(см. perldoc POSIX):
use POSIX 'setuid';
# call cpan to install modules...
POSIX::setuid($newuid);
# ... continue with script
Вы можете снова использовать sudo для удаления своих привилегий root, таких как:
sudo -u 'your_username' gfconftool-2