14

我在 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 是必要的。

4

8 回答 8

20

以下效果很好;将以下位放在(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 构造来传递它们(由于某种原因,我无法让它与 $@ 一起使用)

于 2010-09-08T11:33:09.283 回答
10

newgrp命令只能从交互式外壳 AFAICT 中有意义地使用。事实上,我放弃了关于......好吧,让我们说很久以前我写的替代品现在有资格在英国和美国投票。

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

我有各种各样的程序可以解决newgrp想要解决的问题。请记住,该命令早于用户同时属于多个组的能力(请参阅第7 版 Unix 手册)。由于newgrp不提供在执行命令后执行命令的机制,与suor不同sudo,我编写了一个程序newgid,该程序与 or 一样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 位。这意味着无论谁创建文件,该文件都将属于拥有该目录的组。这通常可以达到您需要的效果 - 尽管我知道很少有人一直使用它。

于 2008-11-18T19:47:58.567 回答
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
于 2011-12-02T22:37:22.197 回答
6
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 身份运行的那个。无论如何,我知道这篇文章很古老,但希望这对某人有用。

于 2012-04-09T21:27:57.873 回答
0

也许

exec $SHELL

会成功吗?

于 2008-11-18T19:01:35.307 回答
0

您可以使用 sh& (或您想使用的任何外壳)而不是 xterm&

或者你也可以考虑使用别名(如果你的 shell 支持这个),这样你就可以留在当前 shell 的上下文中。

于 2008-11-18T19:26:17.550 回答
0

在脚本文件中,例如 tst.ksh:

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

在命令行:

>> groups fred
oldgroup
>> tst.ksh

>> groups fred
thegroup
于 2014-02-28T13:19:20.860 回答
0
sudo su - [user-name] -c exit;

应该做的伎俩:)

于 2018-03-28T08:35:16.817 回答