Passar uma função para outro usuário no Bash?


11

Existe alguma maneira de eu passar uma função de um usuário para outro usuário?

Por exemplo, eu tenho um pequeno script Bash que executo como Raiz:

#!/bin/bash
user_func(){
  whoami
  exit
}
su vagrant -c 'user_func'

No entanto, a função user_func não está definida para o usuário do Vagrant, apenas para o Root e não pode ser executada.

Minha outra opção seria ter várias linhas de

su vagrant -c 'cmd1' 
su vagrant -c 'cmd2'
, etc 

Ou execute vários comandos ex:, su vagrant -c 'cmd1; cmd2; cmd3;'mas eu preferiria não ter excesso, principalmente ao tentar executar mais de 5 comandos como o usuário do Vagrant.

É possível passar uma Função para outro usuário a partir do mesmo script (por exemplo, não criando um script no disco como um usuário diferente e executando esse script gerado)? Ou existe outra opção que estou ignorando?

Respostas:


10

Parece que você precisa exportprimeiro dessa definição de função:

#!/bin/bash
user_func (){
  whoami
  exit
}
export -f user_func
su vagrant -c 'user_func'

deve fazer o truque.

O -fdiz exportque este é um nome de função e não um nome de variável. Citação de help export:

Marca cada NAME para exportação automática para o ambiente de comandos executados posteriormente. ....

Opções:

 -f   refer to shell functions

Como apontado por Peter e Stephane nos comentários, isso pressupõe duas coisas:

  1. Que seu sucomando não substituirá o ambiente do usuário
  2. Esse vagranté o shell de login bash. Caso contrário, você pode usar a sulinha de comando alternativa fornecida por Stephane:

    su vagrant -c 'bash -c user_func'

Na verdade, era exatamente isso que eu esperava. Eu não sabia que você seria capaz de exportar a função. Isso funcionou exatamente como eu esperava, depois de editar o script de exemplo. Obrigado!
gdieckmann

1
Bom, mas não funcionará nos casos em que susubstitua o ambiente.
Peterph

1
Observe que ele só funciona se o shell de logon vagrantfor bash. Se não,su vagrant -c 'bash -c user_func'
Stéphane Chazelas

6

É um pouco tolo, mas você pode imprimir a definição da função dentro do sommand passado sue, é claro, usá-lo.

$ function foo { do_some_stuff_here; }
$ su test -c "$(typeset -f foo); foo"

Isso funcionará mesmo se, por algum motivo, o ambiente do shell gerado sufor substituído, pois coloca a definição após a inicialização do shell. Se você escrever a função de forma compatível o suficiente, ela funcionará mesmo quando os dois usuários em questão estiverem usando shells diferentes.


+1 truque muito legal! Apenas uma pergunta, porém, o suambiente do shell pode ser substituído por fatores externos? Quero dizer, neste caso, você tem controle total sobre a sulinha de comando, pois está em um script. Como o ambiente do seu novo shell pode ser substituído?
Joseph R.

Por exemplo, o shell gerado supode fazer alguma inicialização do ambiente. Também suele próprio pode retirar parte do ambiente do chamador para reforçar um pouco a segurança (embora isso geralmente seja feito por alternativas mais poderosas, como sudo).
Peterph

0

Esse não é um script que você possui, é uma função. Parece que você quer um script, no entanto. Faça um script adequado e coloque-o, conforme suas necessidades, dentro /usr/local/binou dentro /home/vagrant/bin, e do que você deve, por exemplo,su vagrant -c '/home/vagrant/bin/myscript.sh'


É uma função dentro de um script de amostra. Minha esperança era incluir tudo o que eu quero fazer nesse script único (os comandos são executados como raiz e como usuário do Vagrant), e não é necessário ter um script separado para o usuário raiz e um script separado para o usuário Vagrant.
Gdeckmann # 23/13

0

Outra maneira um pouco mais portátil de fazer isso (sem dependência do bash) é fazer com que seu script se auto-identifique e mude seu comportamento com base no contexto (uid) ou nos parâmetros. exemplos disso são fornecidos na documentação para superonde eles mostram um script que precisa de permissões de root, chamando a si próprio de super quando não root.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.