【问题标题】:How do you use newgrp in a script then stay in that group when the script exits如何在脚本中使用 newgrp 然后在脚本退出时留在该组中
【发布时间】:2023-09-08 06:12:01
【问题描述】:

我在 solaris Box 上运行脚本。特别是 SunOS 5.7。我不是根。我正在尝试执行类似于以下的脚本:

newgrp thegroup 来源 .login_stuff
回声“你好世界”

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

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

newgrp thegroup 来源 .login_stuff
xterm&
回声 $1
杀死 -9 $1

我没有可用的 sg。 另外,newgrp 是必须的。

【问题讨论】:

    标签: unix shell solaris csh


    【解决方案1】:

    也许

    exec $SHELL
    

    会成功吗?

    【讨论】:

      【解决方案2】:

      您可以使用 sh&(或任何您想使用的 shell)代替 xterm&

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

      【讨论】:

        【解决方案3】:

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

        请注意,newgrp 是一个“内置”在 shell 中的特殊命令。严格来说,它是 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 位。这意味着无论谁创建文件,该文件都将属于拥有该目录的组。这通常可以达到您需要的效果 - 尽管我知道很少有人一直使用它。

        【讨论】:

        • 我认为这可行。我会通过电子邮件向您询问来源(或者我的电子邮件是 paulydavis@gmail.com) 我可以不受限制地使用该来源吗?我问这个是因为它是用于商业用途(尽管在内部使用)这个答案是例外的答案。
        • 炙手可热的答案! Solaris 10 的 newgrp(1)(至少)保留了用户的 shell,并且确实检查了 $SHELL(我检查了 OpenSolaris 源代码)。
        【解决方案4】:

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

        【讨论】:

        • 引用可以帮助吗?如 exec sg nas_bio3 "$@"
        • 我不知道为什么当问题被标记为 Solaris 时,Linuxen 的答案被接受了。我也有同样的情况,我的 Solaris 机器上不存在“sg”。
        【解决方案5】:

        这个例子是从 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
        

        【讨论】:

          【解决方案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 身份运行的那个。 无论如何,我知道这篇文章很古老,但希望这对某人有用。

          【讨论】:

          • 这对我没有任何帮助。但是我在ubuntu上,你能解释一下&lt;&lt;应该做什么,ANYNAME应该代表什么,END也是如此。
          • 这似乎没有回答问题,因为当脚本退出时你仍然不会在adm 组中。
          • @Shardj 我在 Ubuntu 20.04 上,这对我有用。 ANYNAMEENDheredocs - 我相信它们基本上可以轻松创建多行字符串。
          【解决方案7】:

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

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

          在命令行:

          >> groups fred
          oldgroup
          >> tst.ksh
          
          >> groups fred
          thegroup
          

          【讨论】:

            【解决方案8】:
            sudo su - [user-name] -c exit;
            

            应该做的伎俩:)

            【讨论】: