4

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

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

4

3 回答 3

4

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

use POSIX 'setuid';

# call cpan to install modules...

POSIX::setuid($newuid);

# ... continue with script
于 2010-10-06T18:37:48.953 回答
2

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

sudo -u 'your_username' gfconftool-2
于 2010-10-06T18:37:26.163 回答
0

经过大量阅读和反复试验,当您以 root 身份运行脚本时,似乎缺少的是未设置 DBUS_SESSION_BUS_ADDRESS 环境变量。在设置 gconf 设置之前,必须设置此项并将 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);

注意:这里有一些很好的信息。

于 2010-10-13T00:09:08.010 回答