2008-11-18 14 views
9

Estoy ejecutando un script en un Solaris Box. específicamente SunOS 5.7. Yo no soy root Estoy tratando de ejecutar un script similar al siguiente:¿Cómo se usa newgrp en un script y luego permanecer en ese grupo cuando el script sale

newgrp delgrupo < < FOO
fuente .login_stuff
echo "hola mundo"
FOO

El Secuencia de comandos se ejecuta El problema es que regresa al proceso de llamada que me coloca en el antiguo grupo con la fuente .login_stuff no siendo de origen. Entiendo este comportamiento Lo que estoy buscando es una forma de permanecer en el submarino. Ahora sé que podría poner un xterm & (ver abajo) en el script y eso lo haría, pero tener un nuevo xterm no es deseable.

Pasando su pid actual como parámetro.

newgrp delgrupo < < FOO
fuente .login_stuff
xterm &
echo $ 1
kill -9 $ 1
FOO

no tengo sg disponibles. Además, newgrp es necesario.

Respuesta

15

Lo siguiente funciona muy bien; ponga el siguiente bit en la parte superior del guión (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 

Esto funciona bien en Linuxen. Una advertencia: los argumentos que contienen espacios se rompen. Le sugiero que use el env arg1 = 'valor 1' arg2 = 'valor 2' script.sh constructo para pasarlos (no pude hacer que funcione con $ @ por alguna razón)

+0

¿Pueden las cotizaciones ayudar? como en exec sg nas_bio3 "$ @" –

+1

No sé por qué se aceptó una respuesta para Linuxen cuando se etiquetó la pregunta Solaris. Estoy en la misma situación y "sg" no existe en mi cuadro de Solaris. – Jolta

0

Tal

exec $SHELL 

haría el truco?

+0

Eso no funciona – Paul

+0

No ... eso no funciona. –

0

Se puede usar sh & (o lo que sea shell que desee utilizar) en lugar de xterm &

O también se puede ver en el uso de un alias (si su cáscara apoya esto) para que se quedara en el contexto del caparazón actual.

+0

No ... eso no funciona. –

7

El comando newgrp solo se puede utilizar de manera significativa desde un shell interactivo, AFAICT. De hecho, me di por vencido sobre ... bueno, digamos hace mucho tiempo que el reemplazo que escribí ahora es elegible para votar tanto en el Reino Unido como en los Estados Unidos.

Tenga en cuenta que newgrp es un comando especial 'integrado' en el shell. Estrictamente, es un comando que es externo al shell, pero el shell tiene un conocimiento incorporado sobre cómo manejarlo. El shell realmente es el programa exec, por lo que obtienes un nuevo intérprete de comandos inmediatamente después. También es un programa raíz setuid. En Solaris, al menos, newgrp también parece ignorar la variable de entorno SHELL.

Tengo una variedad de programas que solucionan el problema que newgrp estaba destinado a tratar. Recuerde, el comando es anterior a la capacidad de los usuarios para pertenecer a múltiples grupos a la vez (consulte Version 7 Unix Manuals).Dado que newgrp no proporciona un mecanismo para ejecutar comandos después de su ejecución, a diferencia de su o sudo, escribí un programa newgid que, como newgrp, es un programa raíz setuid y le permite cambiar de un grupo a otro. Es bastante simple, solo main() más un conjunto de funciones de informe de error estandarizadas. Ponte en contacto conmigo (primer punto por último en punto com de gmail) para la fuente. También tengo un comando mucho más peligroso llamado 'asroot' que me permite (pero solo a mí, bajo la compilación predeterminada) ajustar las listas de usuarios y grupos mucho más 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 

(Este programa se desarrolló: se me rehacer desde cero, aceptaría ID de usuario o nombre de usuario sin requerir diferentes letras de opciones; lo mismo para el ID de grupo o nombre de grupo.)

Puede ser difícil para obtener permiso para instalar programas raíz setuid. Hay algunas soluciones disponibles ahora debido a las instalaciones de varios grupos. Una técnica que puede funcionar es establecer el bit setgid en los directorios donde quiere que se creen los archivos. Esto significa que independientemente de quién crea el archivo, el archivo pertenecerá al grupo que posee el directorio. Esto a menudo logra el efecto que necesita, aunque conozco a pocas personas que lo usan de manera consistente.

+0

Creo que eso funcionaría. Le enviaré un correo electrónico y le preguntaré por la fuente (o mi correo electrónico es [email protected]) ¿Puedo usar la fuente sin restricciones? Pregunto esto porque es para uso comercial (aunque en uso doméstico) Esta respuesta es la excepción. – Paul

+0

¡Respuesta abrasadora! Solaris 10's newgrp (1) (al menos) preserva el shell del usuario, y de hecho comprueba $ SHELL (revisé el código fuente de OpenSolaris). –

6

Este ejemplo fue ampliado de la respuesta de plinjzaad; maneja una línea de comando que contiene parámetros cotizados que contienen espacios.

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

Lo usé para demostrar que funciona.

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

salida ..will:

This is running as group adm 

Cuidado - Asegúrese de que a escapar de la '$' con una barra. Las interacciones son un poco extrañas, ya que expande incluso comillas simples antes de ejecutar el shell como el otro grupo. Por lo tanto, si su grupo primario es 'usuarios', y el grupo que está tratando de utilizar es 'adm', entonces:

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

salida ..will:

This is running as group users 

..because ' id -gn 'fue ejecutado por el shell actual, luego enviado al que se ejecuta como adm. De todos modos, sé que esta publicación es antigua, pero espero que esto sea útil para alguien.

0

En un archivo de script por ejemplo tst.ksh:

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

En la línea de comandos:

>> groups fred 
oldgroup 
>> tst.ksh 

>> groups fred 
thegroup 
Cuestiones relacionadas