我在solaris Box上运行脚本.特别是SunOS 5.7.我不是根.我正在尝试执行类似于以下内容的脚本:
newgrp
thegroup << FOO source .login_stuff
echo"hello world"
FOO
脚本运行.问题是它返回到调用进程,该进程将我放入源组.login_stuff未被获取的旧组中.我理解这种行为.我正在寻找的是一种留在子壳中的方法.现在我知道我可以在脚本中放一个xterm&(见下文)并且会这样做,但是有一个新的xterm是不可取的.
将当前pid作为参数传递.
newgrp
thegroup << FOO source .login_stuff
xterm&
echo $ 1
kill -9 $ 1
FOO
我没有可用的sg.此外,newgrp是必要的.
以下工作很好; 将以下位置放在(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'tcript.sh构造来传递它们(由于某些原因,我无法使用$ @)
该newgrp
命令只能在交互式shell AFAICT中有意义地使用.事实上,我放弃了......好吧,让我们说很久以前我写的替代品现在有资格在英国和美国投票.
请注意,这newgrp
是一个特殊的命令'内置'到shell中.严格来说,它是shell外部的命令,但shell具有关于如何处理它的内置知识.shell实际上exec
是程序,所以你之后会立即得到一个新的shell.它也是一个setuid root程序.至少在Solaris上,newgrp
似乎也忽略了SHELL环境变量.
我有各种各样的程序可以解决这个问题newgrp
.请记住,该命令会提前确定用户是否同时属于多个组(请参阅第7版Unix手册).由于newgrp
不提供执行命令后执行命令的机制,不像su
或者sudo
,我写了一个程序newgid
,比如newgrp
,是一个setuid根程序,允许你从一个组切换到另一个组.它非常简单 - 只需要main()以及一组标准化的错误报告功能.联系我(gmail dot com的第一个点)来源.我还有一个更危险的命令'asroot
'这允许我(但只有我 - 在默认编译下)更彻底地调整用户和组列表.
asroot: Configured for use by jleffler only Usage: asroot [-hnpxzV] [] [ ] [-m umask] [--] command [arguments] = [-u usr|-U uid] [-s euser|-S euid][-i user] = [-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位.这意味着无论谁创建文件,该文件都属于拥有该目录的组.这通常会达到您所需要的效果 - 尽管我知道很少有人一直使用它.
这个例子从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
newgrp adm << ANYNAME # You can do more lines than just this. echo This is running as group \$(id -gn) ANYNAME
..将输出:
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
..将输出:
This is running as group users
..因为'id -gn'是由当前shell运行的,然后发送给以adm运行的shell。无论如何,我知道这篇文章很古老,但是希望这对某人有用。