2008-11-18 186 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