如何以root用户身份运行Perl脚本,但仍然影响用户gconf设置
新查询:我正在尝试制作一个统一的脚本,以便根据我的喜好初始化新的Ubuntu安装,它必须在sudo下运行才能安装软件包,但使用gconftool-2来影响gconf设置依赖于dbus会话,而这仅仅通过单独更改脚本中的UID的方法就无法正确处理。有人知道如何设法做到这一点吗?如何以root用户身份运行Perl脚本,但仍然影响用户gconf设置
OLD QUERY:我正在编写一个Perl脚本,以便在新Ubuntu安装的第一次启动时执行。这是为了便于添加存储库,安装软件包和设置gconf设置。我的问题是权限。要安装软件包,我需要将脚本作为sudo执行,但是gconftool-2调用将作用于root用户而不是我个人用户。
经过大量阅读和试验和错误之后,当您以root身份运行脚本时,似乎缺少的是DBUS_SESSION_BUS_ADDRESS环境变量未设置。这必须被设置,并且在gconf设置可以被设置之前,uid被改变为用户的uid。这是我用来测试的测试脚本。在最后运行一个或另一个系统调用来切换窗口按钮顺序。尝试脚本作为用户或作为根(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。
您可以再次使用sudo下降喜欢你的root权限:
sudo -u 'your_username' gfconftool-2
您可以通过改变与POSIX::setuid()
的UID更改脚本中间的UID(见perldoc POSIX):
use POSIX 'setuid';
# call cpan to install modules...
POSIX::setuid($newuid);
# ... continue with script
这看起来很有希望。结合getlogin()获取登录名,getpwnam(name)以便在开始时获得我的uid,我希望它可以工作。 – 2010-10-06 18:54:10
不幸的是,这还不够。在阅读更多内容之后,gconftool-2用dbus检查它的魔法。这远高于我的头脑。我将编辑我的问题,但如果这样做进展不顺利,我将不得不满足两个脚本,一个在sudo下运行,另一个以用户身份运行。 – 2010-10-08 16:46:38
我确实需要POSIX :: setuid命令,但我更需要环境变量,所以我投票给你,但不正确。别往心里放! – 2010-10-13 00:10:07
我做了一些测试,我不确定那是否有效,尽管它看起来应该是这样! – 2010-10-06 18:54:53
只需清理一些东西。同样,这不起作用的原因是上面的ENV变量没有被设置。试试'perl -E'说$ 2010-11-14 16:01:47