2008-11-18 11 views
9

Sono in esecuzione di uno script su una scatola di Solaris. in particolare SunOS 5.7. Io non sono root. Sto cercando di eseguire uno script simile al seguente:come si usa newgrp in uno script poi rimanere in quel gruppo quando lo script esce

newgrp TheGroup < < FOO
fonte .login_stuff
echo "ciao mondo"
FOO

Il Script funziona. Il problema è che ritorna al processo chiamante che mi mette nel vecchio gruppo con il sorgente .login_stuff che non è stato originato. Capisco questo comportamento. Quello che sto cercando è un modo per rimanere nella sottocoppa. Ora so che ho potuto mettere un xterm & (vedi sotto) nello script e che farei, ma avere un nuovo xterm è indesiderabile.

Passare il pid corrente come parametro.

newgrp TheGroup < < FOO
fonte .login_stuff
xterm &
echo $ 1
kill -9 $ 1
FOO

Non ho sg disponibili. Inoltre, newgrp è necessario.

risposta

15

Il seguente funziona bene; inserire il seguente bit all'inizio dello script (Bourne o Bash):

### first become another group 
group=admin 

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

### now continue with rest of the script 

Questo funziona perfettamente su Linuxen. Un avvertimento: gli argomenti contenenti spazi sono separati. Vi suggerisco di utilizzare il env arg1 = 'valore 1' arg2 = 'valore 2' script.sh costruire a passare dal vivo a (non ho potuto farlo funzionare con $ @ per qualche motivo)

+0

Le citazioni possono aiutare? come in exec sg nas_bio3 "$ @" –

+1

Non so perché una risposta per Linuxen è stata accettata quando la domanda è stata contrassegnata come Solaris. Sono nella stessa situazione, e "sg" non esiste sulla mia scatola Solaris. – Jolta

0

Forse

exec $SHELL 

sarebbe fare il trucco?

+0

Che non funziona – Paul

+0

No ... che non funziona. –

0

Si potrebbe utilizzare sh & (o qualsiasi altra cosa che si desidera utilizzare shell) al posto di xterm &

Oppure si potrebbe anche considerare di usare un alias (se la tua shell supporta questa), in modo che si dovrebbe rimanere nel contesto della shell corrente.

+0

No ... non funziona. –

7

Il comando newgrp può solo significato essere utilizzato da una shell interattiva, AFAICT. In effetti, ho rinunciato a questo ... beh, diciamo abbastanza tempo fa che la sostituzione che ho scritto è ora eleggibile per votare sia nel Regno Unito che negli Stati Uniti.

noti che newgrp è un comando speciale 'incorporato nella' guscio. Strettamente, si tratta di un comando esterno alla shell, ma la shell ha una conoscenza integrata su come gestirla. La shell in realtà è il programma exec, quindi ottieni subito una nuova shell. È anche un programma di root setuid. Su Solaris, almeno, newgrp sembra anche ignorare la variabile di ambiente SHELL.

Ho una varietà di programmi che risolvono il problema che newgrp era destinato a risolvere. Ricordate, il comando pre-date la capacità degli utenti di appartenere a più gruppi in una sola volta (vedi la Version 7 Unix Manuals).Poiché newgrp non fornisce un meccanismo per eseguire comandi dopo aver eseguito, a differenza su o sudo, ho scritto un programma newgid che, come newgrp, è un programma setuid root e permette di passare da un gruppo all'altro. È abbastanza semplice: solo main() più una serie di funzioni di reporting degli errori standardizzate utilizzate. Contattami (il primo punto è valido a gmail dot com) per la fonte. Ho anche un comando molto più pericoloso chiamato 'asroot' che mi consente (ma solo a me - sotto la compilazione di default) di modificare gli elenchi di utenti e gruppi molto più a fondo.

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 

(Questo programma cresciuto: sono stati ho rifatto da zero, io accetto ID utente o nome utente senza richiedere diverse lettere di opzione; idem per ID gruppo o il nome del gruppo.)

Può essere difficile per ottenere il permesso di installare i programmi di root setuid. Ci sono alcune soluzioni alternative ora a causa delle strutture multi-gruppo. Una tecnica che può funzionare è impostare il bit setgid nelle directory in cui si desidera creare i file. Ciò significa che, indipendentemente da chi crea il file, il file apparterrà al gruppo che possiede la directory. Questo spesso raggiunge l'effetto che ti serve, anche se conosco poche persone che lo usano costantemente.

+0

Penso che funzionerebbe. Ti invierò un'e-mail e ti chiederò la fonte (o la mia e-mail è [email protected]) Posso usare la fonte senza restrizioni. Lo chiedo perché è per uso commerciale (anche se in uso domestico) Questa risposta è la risposta esente. – Paul

+0

Risposta bruciante! Newgrp di Solaris 10 (1) (almeno) conserva la shell dell'utente e controlla effettivamente $ SHELL (ho controllato l'origine di OpenSolaris). –

6

Questo esempio è stato ampliato dalla risposta di plinjzaad; gestisce una riga di comando che contiene parametri quotati che contengono spazi.

#!/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 

Ho usato questo per dimostrare che funziona.

% ./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 

uscita ..will:

This is running as group adm 

Attenzione - Assicurarsi di sfuggire alla '$' con una barra. Le interazioni sono un po 'strane, perché espande anche le virgolette singole prima di eseguire la shell come l'altro gruppo. quindi, se il gruppo primario è 'utenti', e il gruppo che si sta tentando di utilizzare è 'adm', quindi:

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

uscita ..will:

This is running as group users 

..perché ' id -gn 'è stato eseguito dalla shell corrente, quindi inviato a quello in esecuzione come adm. Ad ogni modo, so che questo post è antico, ma spero che questo sia utile a qualcuno.

0

In un file di script ad esempio tst.ksh:

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

Nella riga di comando:

>> groups fred 
oldgroup 
>> tst.ksh 

>> groups fred 
thegroup 
Problemi correlati