如何以root身份运行Perl脚本,但仍影响用户gconf设置

时间:2010-10-06 18:29:03

标签: perl gnome sudo dbus gconf

新的问题:我正在尝试创建一个统一的脚本来初始化我喜欢的新Ubuntu安装,它必须在sudo下运行才能安装软件包,但使用gconftool-2来影响gconf设置依赖于dbus会话通过仅在脚本中简单地更改UID的方法无法正确处理。有人知道如何设法做到这一点吗?

OLD QUERY:我正在编写一个Perl脚本,要在新的Ubuntu安装的第一次启动时执行。这是为了方便添加存储库,安装包和设置gconf设置。我的问题是权限。要安装软件包,我需要将脚本作为sudo执行,但是gconftool-2调用对root用户起作用,而不是在我的个人用户上。

3 个答案:

答案 0 :(得分:4)

您可以通过POSIX::setuid()更改uid来更改脚本中间的uid(请参阅perldoc POSIX):

use POSIX 'setuid';

# call cpan to install modules...

POSIX::setuid($newuid);

# ... continue with script

答案 1 :(得分:2)

您可以再次使用sudo删除root权限,如:

sudo -u 'your_username' gfconftool-2

答案 2 :(得分:0)

经过多次阅读和反复试验后,以root身份运行脚本时缺少的是DBUS_SESSION_BUS_ADDRESS环境变量未设置。必须设置此项并且在设置gconf设置之前,uid已更改为用户的uid。这是我以前尝试过的测试脚本。在末尾运行一个或另一个系统调用以切换窗口按钮顺序。以用户或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);

注意:获得了一些不错的信息here