Как я могу запустить Perl-скрипт от имени пользователя root, но все же повлиять на настройки gconf

НОВЫЙ ЗАПРОС: Я пытаюсь создать единый сценарий, который инициализирует новую установку Ubuntu по своему вкусу, для установки пакетов он должен запускаться под sudo, но использование gconftool-2 для влияния на настройку gconf опирается на сеанс dbus, который не обрабатывается правильно методом простого изменения UID только в скрипте. Кто-нибудь знает, как это сделать?

СТАРЫЙ ЗАПРОС: Я пишу сценарий Perl, который будет выполняться при первой загрузке новой установки Ubuntu. Это облегчает добавление репозиториев, установку пакетов и настройку параметров gconf. Моя проблема - разрешения. Для установки пакетов мне нужно, чтобы скрипт выполнялся как sudo, но затем вызов gconftool-2 действует от имени пользователя root, а не от моего личного пользователя.

Ответы на вопрос(3)

Решение Вопроса

После долгих чтений, проб и ошибок кажется, что при запуске скрипта от имени root отсутствует то, что переменная среды DBUS_SESSION_BUS_ADDRESS не установлена. Это должно быть установлено И UID изменен на пользовательский, прежде чем настройки 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
 Joel Berger13 окт. 2010 г., 02:10
Мне нужна была команда POSIX :: setuid, но мне нужна была переменная среды, поэтому я проголосовал за вас, но не правильно. Никаких обид!
 Joel Berger06 окт. 2010 г., 20:54
Это выглядит многообещающе. В сочетании с getlogin () для получения имени для входа и getpwnam (name) для получения моего идентификатора в начале, он должен работать, я надеюсь.
 Joel Berger08 окт. 2010 г., 18:46
К сожалению, этого недостаточно. Прочитав еще немного, gconftool-2 проверяет с помощью dbus что-то магическое. Это намного выше моей головы. Я отредактирую свой вопрос, но если это не будет продвигаться хорошо, мне придется довольствоваться двумя сценариями, один для запуска под sudo и один для запуска в качестве пользователя.

Вы можете снова использовать sudo для удаления своих привилегий root, таких как:

sudo -u 'your_username' gfconftool-2
 Joel Berger14 нояб. 2010 г., 17:01
Просто убираю вещи. Опять же, причина того, что это не работает, состоит в том, что указанная выше переменная ENV не устанавливается. Пытатьсяperl -E 'say $< . "\n" . $ENV{'DBUS_SESSION_BUS_ADDRESS'}' как пользователь, подsudo и подsudo -u username увидеть разницу
 Joel Berger06 окт. 2010 г., 20:54
Я провел некоторое тестирование, и я не уверен, что это работает, хотя, конечно, кажется, что это должно!

Ваш ответ на вопрос