Как использовать newgrp в скрипте, а затем оставаться в этой группе при выходе из скрипта?
Вопрос
Я запускаю скрипт на коробке Solaris. в частности SunOS 5.7. Я не root. Я пытаюсь выполнить скрипт, подобный следующему:
newgrp thegroup < < FOO
источник .login_stuff
эхо " привет мир "
FOO
Сценарий запускается. Проблема в том, что он возвращается к вызывающему процессу, который помещает меня в старую группу с исходным кодом .login_stuff, который не был получен. Я понимаю это поведение. То, что я ищу, - это способ остаться в субоболочке. Теперь я знаю, что могу поставить xterm & Amp; (см. ниже) в сценарии, и это бы сделало это, но наличие нового xterm нежелательно. Р>
Передача вашего текущего pid в качестве параметра.
newgrp thegroup < < FOO
источник .login_stuff
& Xterm усилитель;
эхо $ 1
убить -9 $ 1
FOO
У меня нет sg в наличии. Также необходим newgrp.
Решение
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
Будьте осторожны - убедитесь, что вы избежали '$' косой чертой. Взаимодействия немного странные, потому что они расширяют даже одинарные кавычки перед тем, как выполнить оболочку как другая группа. Итак, если ваша основная группа - «пользователи», а группа, которую вы пытаетесь использовать, - «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' был запущен текущей оболочкой, а затем отправлен той, которая работает как adm. В любом случае, я знаю, что этот пост древний, но надеюсь, что он кому-нибудь пригодится.
Другие советы
Следующее работает хорошо; поместите следующий бит вверху скрипта (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 конструкция для их передачи (по какой-то причине я не смог заставить ее работать с $ @)
Команда newgrp
может быть осмысленно использована только из интерактивной оболочки AFAICT. На самом деле, я отказался от этого из-за ... ну, скажем, достаточно давно, что написанная мною замена теперь имеет право голосовать как в Великобритании, так и в США.
Обратите внимание, что exec
- это специальная команда, встроенная в оболочку. Строго говоря, это команда, которая является внешней по отношению к оболочке, но оболочка обладает встроенными знаниями о том, как ее обрабатывать. Оболочка фактически является программой, поэтому сразу после этого вы получаете новую оболочку. Это также корневая программа setuid. По крайней мере, в Solaris su
также игнорирует переменную среды SHELL.
У меня есть множество программ, которые решают проблему, которую sudo
должен был решить. Помните, что команда предшествует возможности пользователей принадлежать к нескольким группам одновременно (см. Unix версии 7 Руководства ). Поскольку newgid
не предоставляет механизма для выполнения команд после его выполнения, в отличие от asroot
или <=>, я написал программу <=>, которая, как и <=>, является корневой программой setuid и позволяет вам переключаться с одна группа в другую. Это довольно просто - просто main () плюс набор стандартных функций отчетов об ошибках. Свяжитесь со мной (первая точка последняя в gmail точка com) для источника. У меня также есть намного более опасная команда под названием <=>, которая позволяет мне (но только мне - при компиляции по умолчанию) настраивать списки пользователей и групп гораздо более тщательно.
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
(Эта программа выросла: если бы я ее переделывал с нуля, я бы принял идентификатор пользователя или имя пользователя, не требуя других букв опций; то же самое для идентификатора группы или имени группы.)
Получить разрешение на установку корневых программ setuid может быть сложно. В настоящее время доступны некоторые обходные пути из-за возможности использования нескольких групп. Один из методов, который может работать, - установить бит setgid в каталогах, в которых вы хотите создать файлы. Это означает, что независимо от того, кто создает файл, файл будет принадлежать группе, которой принадлежит каталог. Это часто дает нужный вам эффект - хотя я знаю мало людей, которые постоянно используют это. Р>
Этот пример был расширен из ответа Плинджаада; он обрабатывает командную строку, которая содержит параметры в кавычках, содержащие пробелы.
#!/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
Возможно
exec $SHELL
сделал бы трюк?
Вы можете использовать sh & amp; (или любую другую оболочку, которую вы хотите использовать) вместо xterm & amp;
Или вы можете также использовать псевдоним (если ваша оболочка поддерживает это), чтобы вы оставались в контексте текущей оболочки.
В файле сценария, например, tst.ksh:
#! /bin/ksh
/bin/ksh -c "newgrp thegroup"
В командной строке:
>> groups fred
oldgroup
>> tst.ksh
>> groups fred
thegroup
sudo su - [user-name] -c exit;
Должен сделать свое дело:)