Passer une fonction à un autre utilisateur dans Bash?


11

Existe-t-il un moyen de transmettre une fonction d'un utilisateur à un autre utilisateur?

Par exemple, j'ai un petit script Bash que j'exécute en tant que root:

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

Cependant, la fonction user_func n'est pas définie pour l'utilisateur Vagrant, uniquement pour Root, et ne peut pas être exécutée.

Mon autre option serait d'avoir plusieurs lignes de

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

Ou, exécutez plusieurs commandes ex:, su vagrant -c 'cmd1; cmd2; cmd3;'mais je préférerais ne pas avoir l'excédent, surtout lorsque vous essayez d'exécuter plus de 5 commandes en tant qu'utilisateur Vagrant.

Est-il possible de passer une fonction à un autre utilisateur à partir du même script (par exemple, ne pas créer un script sur le disque en tant qu'utilisateur différent, puis exécuter ce script généré)? Ou existe-t-il une autre option que j'envisage?

Réponses:


10

On dirait que vous devez d' exportabord définir cette fonction:

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

devrait faire l'affaire.

Le -findique exportqu'il s'agit d'un nom de fonction plutôt que d'un nom de variable. Citant de help export:

Marque chaque NOM pour l'exportation automatique vers l'environnement des commandes exécutées ultérieurement. ....

Options:

 -f   refer to shell functions

Comme l'ont souligné Peter et Stéphane dans les commentaires, cela suppose deux choses:

  1. Que votre sucommande n'écrasera pas l'environnement de l'utilisateur
  2. C'est vagrantle shell de connexion bash. Sinon, vous pouvez utiliser la suligne de commande alternative fournie par Stéphane:

    su vagrant -c 'bash -c user_func'

C'est en fait exactement ce que j'espérais. Je ne savais pas que vous seriez en mesure d'exporter la fonction. Cela a fonctionné comme je l'espérais après avoir édité l'exemple de script. Merci!
gdieckmann

1
Bien, mais ne fonctionnera pas dans les cas où l' suemporte sur l'environnement.
peterph

1
Notez que cela ne fonctionne que si le shell de connexion de vagrantest bash. Sinon,su vagrant -c 'bash -c user_func'
Stéphane Chazelas

6

C'est un peu hackish, mais vous pouvez imprimer la définition de la fonction à l'intérieur du sommand passé suet ensuite vous pouvez bien sûr l'utiliser.

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

Cela fonctionnera même si pour une raison quelconque, l'environnement du shell généré par susera écrasé, car il place la définition après l'initialisation du shell. Si vous écrivez la fonction de manière suffisamment compatible, elle fonctionnera même lorsque les deux utilisateurs en question utiliseront des shells différents.


+1 Truc vraiment sympa! Mais juste une question, l' suenvironnement du shell peut-il être écrasé par des facteurs externes? Je veux dire, dans ce cas, vous avez un contrôle complet sur la suligne de commande car elle est dans un script. Comment écraser l'environnement de son nouveau shell?
Joseph R.

Par exemple, le shell généré par supeut effectuer une initialisation de l'environnement. De plus, sului-même peut dépouiller certains de l'environnement de l'appelant pour renforcer un peu la sécurité (bien que cela soit généralement fait par des alternatives plus puissantes comme sudo).
peterph

0

Ce n'est pas un script que vous avez, c'est une fonction. Il semble cependant que vous souhaitiez un script. Faites un bon script et mettez-le, selon vos besoins, soit dans /usr/local/bin, soit dans /home/vagrant/bin, et que vous devriez pouvoir par exemplesu vagrant -c '/home/vagrant/bin/myscript.sh'


C'est une fonction dans un exemple de script. Mon espoir était d'inclure tout ce que je veux faire dans ce script unique (les commandes s'exécutent en tant que root et en tant qu'utilisateur Vagrant), et de ne pas avoir un script distinct pour l'utilisateur Root et un script distinct pour l'utilisateur Vagrant.
gdieckmann

0

Une autre façon un peu plus portable de faire cela (pas de dépendance bash) est que votre script s'appelle lui-même et que son comportement change en fonction du contexte (uid) ou des paramètres. des exemples de cela sont donnés dans la documentation pour supermontrer où ils montrent un script qui a besoin d'autorisations root, s'appelant lui-même via super lorsqu'il n'est pas root.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.