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

11

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

Por exemplo, 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 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 prefiro não ter o excesso, especialmente ao tentar executar mais de 5 comandos como o usuário Vagrant.

É possível passar uma função para outro usuário a partir do mesmo script (por exemplo, não criar um script no disco como um usuário diferente e, em seguida, executar esse script gerado)? Ou há outra opção que estou negligenciando?

    
por gdieckmann 23.12.2013 / 22:12

4 respostas

10

Parece que você precisa export da definição dessa função primeiro:

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

deve fazer o truque.

O -f informa export que este é um nome de função em vez de um nome de variável. Citando de help export :

Marks each NAME for automatic export to the environment of subsequently executed commands. ....

Options:

 -f   refer to shell functions

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

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

    su vagrant -c 'bash -c user_func'
    
por 23.12.2013 / 22:37
6

É um pouco hackish, mas você pode imprimir a definição da função dentro do sommand passado para su e então você pode, é claro, usá-la.

$ 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 por su for sobrescrito, já que ele coloca a definição após a inicialização do shell. Se você escrever a função de forma bastante compatível, ela funcionará mesmo quando os dois usuários em questão estiverem usando shells diferentes.

    
por 23.12.2013 / 22:44
0

Isso não é um script que você tem, é uma função. Parece que você quer um script, no entanto. Faça um roteiro apropriado e coloque-o, conforme suas necessidades, em /usr/local/bin ou em /home/vagrant/bin , e então você poderá e. g. su vagrant -c '/home/vagrant/bin/myscript.sh'

    
por 23.12.2013 / 22:27
0

Outra maneira um pouco mais portátil de fazer isso (sem dependência do bash) É fazer com que seu script chame a si mesmo e tenha seu comportamento alterado com base no contexto (uid) ou nos parâmetros. exemplos disso são dados na documentação de super , onde eles mostram um script que precisa de permissões de root, chamando a si mesmo por super quando não é root.

    
por 24.12.2013 / 17:57

Tags