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

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

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


person Joel Berger    schedule 06.10.2010    source источник


Ответы (3)


Вы можете изменить uid в середине скрипта, изменив uid на POSIX::setuid() (см. perldoc POSIX):

use POSIX 'setuid';

# call cpan to install modules...

POSIX::setuid($newuid);

# ... continue with script
person Ether    schedule 06.10.2010
comment
Это выглядит многообещающе. В сочетании с getlogin() для получения имени для входа и getpwnam(name) для получения моего uid в начале, это должно сработать, я надеюсь. - person Joel Berger; 06.10.2010
comment
К сожалению, этого недостаточно. Прочитав еще немного, gconftool-2 каким-то образом проверяет dbus, чтобы сделать свое волшебство. Это намного выше моей головы. Я отредактирую свой вопрос, но если это не сработает, мне придется довольствоваться двумя сценариями, один для запуска под sudo, а другой для запуска от имени пользователя. - person Joel Berger; 08.10.2010
comment
Мне нужна была команда POSIX::setuid, но мне больше нужна была переменная окружения, поэтому я проголосовал за вас, но не правильно. Никаких острых ощущений! - person Joel Berger; 13.10.2010

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

sudo -u 'your_username' gfconftool-2
person Lekensteyn    schedule 06.10.2010
comment
Я провел несколько тестов и не уверен, что это работает, хотя кажется, что должно! - person Joel Berger; 06.10.2010
comment
Просто убираю некоторые вещи. Опять же, причина того, что это не работает, заключается в том, что указанная выше переменная ENV не установлена. Попробуйте perl -E 'say $< . "\n" . $ENV{'DBUS_SESSION_BUS_ADDRESS'}' как пользователь, под sudo и под sudo -u username, чтобы увидеть разницу - person Joel Berger; 14.11.2010

После долгих прочтений, проб и ошибок кажется, что при запуске сценария от имени пользователя 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);

Примечание: есть полезная информация здесь.

person Joel Berger    schedule 13.10.2010