Execute um script de shell como um usuário diferente

42

Qual é uma boa maneira de executar um script de shell como um usuário diferente. Estou usando o Debian etch e sei qual usuário quero personificar.

Se eu estivesse fazendo isso manualmente, faria:

su postgres
./backup_db.sh /tmp/test
exit

Como eu quero automatizar o processo, preciso de uma maneira de executar o backup_db.sh como postgres (herdando o ambiente, etc.)

Obrigado!

Wadih M.
fonte

Respostas:

67

Para executar seu script como outro usuário como um comando, execute:

/bin/su -c "/path/to/backup_db.sh /tmp/test" - postgres

Breaking it down:
 /bin/su : switch user
 -c "/path/to..." : command to run
 - : option to su, make it a login session (source profile for the user)
 postgres : user to become

Eu recomendo sempre o uso de caminhos completos em scripts como este - você nem sempre pode garantir que estará no diretório certo quando fizer o processo (talvez alguém tenha alterado o nome de usuário, quem sabe). Eu também sempre uso o caminho completo para su (/ bin / su) porque sou paranóico. É possível que alguém possa editar seu caminho e fazer com que você use uma versão comprometida do su.

Baumgart
fonte
Sempre será necessário digitar a senha? Como contornar isso?
Zjffdu 29/03/12
2
Sempre será necessário digitar uma senha se você estiver executando o comando como um usuário não root. Se você deseja evitar a senha, pode configurar o sudo para permitir isso. NO ENTANTO - configurar o sudo para permitir que um usuário execute o su permite que ele se torne qualquer usuário. Eu sugeriria a criação de um script para o seu comando, definindo as permissões de script para 700 e de propriedade do root e, em seguida, configurando o sudo para permitir que um usuário execute esse script único.
baumgart
Acredito - embora essa resposta possa funcionar para o OP - não está totalmente correta. Que eu saiba, o uso de ambos -(ou --login) junto com --command, -cna verdade não inicia uma sessão de logon, porque -csempre força um shell que não é de logon.
JeanMertz
1
Nota: para portabilidade, - postgressdeve aparecer no final do comando. Na página de manual:When - is used, it must be specified before any username. For portability it is recommended to use it as last option, before any username. The other forms (-l and --login) do not have this restriction.
jonny
23

Se o usuário de destino a executar tiver nologin shelll definido, você poderá usar a opção -s para especificar o shell:

/bin/su -s /bin/bash -c '/path/to/your/script' testuser

Veja a seguinte pergunta: execute o script como usuário que possui o shell nologin

Basil A
fonte
9

Para automatizar isso em uma programação, você pode colocá-lo no crontab do usuário. Porém, os trabalhos em Cron não terão o ambiente completo, mas pode ser melhor colocar todas as variáveis ​​env que você precisa no próprio script de qualquer maneira.

Para editar o crontab do usuário:

sudo crontab -u postgres -e
Kyle Brandt
fonte
Poderia explicar mais?
26416 saravanakumar
3

Esta deve ser uma leitura informativa - setuid em scripts de shell

Se você executar su com uma - usernamesequência de argumentos " ", ele criará um shell de login para o usuário fornecer o mesmo ambiente que o usuário. Geralmente, é usado para executar rapidamente seu script com o ambiente doméstico a partir de um login diferente.

nik
fonte
Isso pode ser útil se você precisar executar uma série de ações. Mas lembre-se de que a maioria das contas de serviço do sistema não deve ter caminhos e shell domésticos válidos.
22611 Dan Carley
2

Experimente a página de manual su:

su -c script_run_as_postgres.sh - postgres

Por outro lado, você pode usar o sudo para permitir que você execute exatamente esse comando como postgres sem uma senha. Porém, é preciso alguma configuração no seu / etc / sudoers.

pjz
fonte
2

O método "su -c ..." publicado por outras pessoas é bom. Para automação, você pode adicionar o script ao crontab do usuário para o qual precisa executar.

Geoff Fritz
fonte
1

Se o usuário já tiver uma entrada no sudo e você não souber a senha do superusuário, tente o seguinte: Este reinicia os postgres inicializados em /data/my-db/pgsql/9.6/data

sudo su - postgres -c "/usr/pgsql-9.6/bin/pg_ctl -D /data/my-db/pgsql/9.6/data -l /var/log/pgsql.log restart"
smishra
fonte
-1

Você também pode usar:

sudo -u postgres script_run_as_postgres.sh

Xandersoft
fonte