如何以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 
+0

我做了一些测试,我不确定那是否有效,尽管它看起来应该是这样! – 2010-10-06 18:54:53

+0

只需清理一些东西。同样,这不起作用的原因是上面的ENV变量没有被设置。试试'perl -E'说$ 2010-11-14 16:01:47

您可以通过改变与POSIX::setuid()的UID更改脚本中间的UID(见perldoc POSIX):

use POSIX 'setuid'; 

# call cpan to install modules... 

POSIX::setuid($newuid); 

# ... continue with script 
+0

这看起来很有希望。结合getlogin()获取登录名,getpwnam(name)以便在开始时获得我的uid,我希望它可以工作。 – 2010-10-06 18:54:10

+0

不幸的是,这还不够。在阅读更多内容之后,gconftool-2用dbus检查它的魔法。这远高于我的头脑。我将编辑我的问题,但如果这样做进展不顺利,我将不得不满足两个脚本,一个在sudo下运行,另一个以用户身份运行。 – 2010-10-08 16:46:38

+0

我确实需要POSIX :: setuid命令,但我更需要环境变量,所以我投票给你,但不正确。别往心里放! – 2010-10-13 00:10:07