2008-11-18 184 views
9

我在solaris Box上运行脚本。特别是SunOS 5.7。我不是根。我想执行类似下面的脚本:如何在脚本中使用newgrp,然后在脚本退出时停留在该组中

使用newgrp thegroup < < FOO
源.login_stuff
回声的 “Hello World”
FOO

的脚本运行。问题是它返回到调用进程,它使我不在源中的源.login_stuff进入旧组。我理解这种行为。我正在寻找的是一种留在子外壳中的方法。现在我知道我可以在脚本中放置一个xterm &(见下文),并且这样做,但是有一个新的xterm是不可取的。

将您当前的pid作为参数传递。

使用newgrp thegroup < < FOO
源.login_stuff
的xterm &
回声$ 1
杀-9 $ 1
FOO

我没有SG可用。 此外,newgrp是必要的。

回答

15

以下工作很好;在(Bourne或Bash)脚本的顶部放置以下位:

### first become another group 
group=admin 

if [ $(id -gn) != $group ]; then 
    exec sg $group "$0 $*" 
fi 

### now continue with rest of the script 

这对Linuxen可以正常工作。一个警告:包含空格的参数被分开。我建议你使用 env arg1 ='value 1'arg2 ='value 2'script.sh构造来传递它们(由于某种原因我无法使用$ @来工作)

0

也许

exec $SHELL 

会做的伎俩?

+0

这并不工作 – Paul 2008-11-18 19:12:27

+0

都能跟得上...这是行不通的。 – 2008-11-18 19:30:22

0

你可以使用SH &(或任何外壳要使用),而不是xterm的&

或者你也可以考虑使用别名(如果你的外壳支持这一点),这样你会留在上下文的当前shell。

+0

不...没有用。 – 2008-11-18 19:31:58

7

newgrp命令只能在交互式shell,AFAICT中有效地使用。事实上,我放弃了......好吧,让我们先说很久,我写的替代品现在有资格在英国和美国投票。

请注意,newgrp是'内置到'外壳的特殊命令。严格来说,它是一个shell外部的命令,但shell具有关于如何处理它的内置知识。 shell实际上是exec的程序,所以你之后立即得到一个新的shell。它也是一个setuid根节目。在Solaris上,至少newgrp也似乎忽略了SHELL环境变量。

我有很多方案可以解决newgrp打算解决的问题。请记住,该命令会预先记录用户同时属于多个组的能力(请参阅Version 7 Unix Manuals)。由于newgrp没有提供执行命令后的执行机制,与susudo不同,我编写了一个程序newgid,与newgrp一样,它是一个setuid根程序,允许您从一个组切换到另一个组。它非常简单 - 只需main()外加一组使用的标准化错误报告功能。与我联系(源于gmail dot com的第一个点最后)。我还有一个非常危险的命令叫'asroot',它允许我(但只有我 - 在默认编译下)更加彻底地调整用户和组列表。

asroot: Configured for use by jleffler only 
Usage: asroot [-hnpxzV] [<uid controls>] [<gid controls>] [-m umask] [--] command [arguments] 
    <uid controls> = [-u usr|-U uid] [-s euser|-S euid][-i user] 
    <gid controls> = [-C] [-g grp|-G gid] [-a grp][-A gid] [-r egrp|-R egid] 
Use -h for more help 

Option summary: 
-a group Add auxilliary group (by name) 
-A gid Add auxilliary group (by number) 
-C  Cancel all auxilliary groups 
-g group Run with specified real GID (by name) 
-G gid Run with specified real GID (by number) 
-h  Print this message and exit 
-i  Initialize UID and GIDs as if for user (by name or number) 
-m umask Set umask to given value 
-n  Do not run program 

-p  Print privileges to be set 
-r euser Run with specified effective UID (by name) 
-R euid Run with specified effective UID (by number) 
-s egroup Run with specified effective GID (by name) 
-S egid Run with specified effective GID (by number) 
-u user Run with specified real UID (by name) 
-U uid Run with specified real UID (by number) 
-V  Print version and exit 
-x  Trace commands that are executed 
-z  Do not verify the UID/GID numbers 
Mnemonic for effective UID/GID: 
    s is second letter of user; 
    r is second letter of group 

(此程序长大:被我从头重做,我会接受用户ID或用户名,而无需不同的选项字母;对于组ID或组名同上。)

它可以是棘手获得安装setuid root程序的权限。由于多组设施,现在有一些解决方法可用。一种可行的技术是在你想要创建文件的目录上设置setgid位。这意味着无论谁创建文件,该文件都将属于拥有该目录的组。这通常可以达到你需要的效果 - 尽管我知道很少有人持续使用它。

+0

我认为那会奏效。我会通过电子邮件通知您并要求您提供源代码(或者我的电子邮件是[email protected])我可以不受限制地使用源代码。我问这是因为它是商业用途(尽管在家用)这个答案是例外的答案。 – Paul 2008-11-18 20:04:41

6

这个例子是从plinjzaad的答案扩大;它处理一个包含带空格的引用参数的命令行。

#!/bin/bash 
group=wg-sierra-admin 
if [ $(id -gn) != $group ] 
then 
    # Construct an array which quotes all the command-line parameters. 
    arr=("${@/#/\"}") 
    arr=("${arr[*]/%/\"}") 
    exec sg $group "$0 ${arr[@]}" 
fi 

### now continue with rest of the script 
# This is a simple test to show that it works. 
echo "group: $(id -gn)" 
# Show all command line parameters. 
for i in $(seq 1 $#) 
do 
    eval echo "$i:\${$i}" 
done 

我用这个来证明它的工作原理。

% ./sg.test 'a b' 'c d e' f 'g h' 'i j k' 'l m' 'n o' p q r s t 'u v' 'w x y z' 
group: wg-sierra-admin 
1:a b 
2:c d e 
3:f 
4:g h 
5:i j k 
6:l m 
7:n o 
8:p 
9:q 
10:r 
11:s 
12:t 
13:u v 
14:w x y z 
2
newgrp adm << ANYNAME 
# You can do more lines than just this. 
echo This is running as group \$(id -gn) 
ANYNAME 

..will输出:

This is running as group adm 

小心 - 确保你逃脱 '$' 与斜线。这些交互有点奇怪,因为它在作为另一个组执行shell之前甚至会扩展单引号。所以,如果你的主组是 '用户',而你试图使用组是 'ADM',则:

newgrp adm << END 
# You can do more lines than just this. 
echo 'This is running as group $(id -gn)' 
END 

..will输出:

This is running as group users 

..because“ id -gn'由当前shell运行,然后发送到以adm身份运行的那个。无论如何,我知道这篇文章是古代的,但希望这对某人有用。

0

在一个脚本文件如tst.ksh:

#! /bin/ksh 
/bin/ksh -c "newgrp thegroup" 

在命令行:

>> groups fred 
oldgroup 
>> tst.ksh 

>> groups fred 
thegroup