Eine Funktion in Bash an einen anderen Benutzer übergeben?


11

Gibt es eine Möglichkeit, eine Funktion von einem Benutzer an einen anderen Benutzer zu übergeben?

Zum Beispiel habe ich ein kleines Bash-Skript, das ich als Root ausführe:

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

Die user_func-Funktion ist jedoch nicht für den Vagrant-Benutzer definiert, sondern nur für Root und kann nicht ausgeführt werden.

Meine andere Option wäre, mehrere Zeilen von zu haben

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

Oder führen Sie mehrere Befehle aus su vagrant -c 'cmd1; cmd2; cmd3;', z. B., aber ich würde es vorziehen, nicht den Überschuss zu haben, insbesondere wenn Sie versuchen, mehr als 5 Befehle als Vagrant-Benutzer auszuführen.

Ist es möglich, eine Funktion innerhalb desselben Skripts an einen anderen Benutzer zu übergeben (z. B. kein Skript auf der Festplatte als anderer Benutzer zu erstellen und dann das generierte Skript auszuführen)? Oder gibt es eine andere Option, die ich übersehen habe?

Antworten:


10

Klingt so, als müssten Sie zuerst exportdiese Funktionsdefinition ausführen:

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

sollte den Trick machen.

Das -fsagt, exportdass dies eher ein Funktionsname als ein Variablenname ist. Zitat aus help export:

Markiert jeden NAME für den automatischen Export anschließend ausgeführter Befehle in die Umgebung. ....

Optionen:

 -f   refer to shell functions

Wie Peterph und Stephane in den Kommentaren betonten, setzt dies zwei Dinge voraus:

  1. Dass Ihr suBefehl die Benutzerumgebung nicht überschreibt
  2. Das ist vagrantdie Login-Shell bash. Wenn nicht, können Sie sudie von Stephane bereitgestellte alternative Befehlszeile verwenden:

    su vagrant -c 'bash -c user_func'

Genau das habe ich mir erhofft. Ich wusste nicht, dass Sie die Funktion exportieren können. Dies funktionierte genau so, wie ich es mir nach der Bearbeitung des Beispielskripts erhofft hatte. Vielen Dank!
Gdieckmann

1
Schön, funktioniert aber nicht, wenn sudie Umgebung außer Kraft gesetzt wird.
Peterph

1
Beachten Sie, dass es nur funktioniert, wenn die Login-Shell von vagrantist bash. Wenn nicht,su vagrant -c 'bash -c user_func'
Stéphane Chazelas

6

Es ist ein bisschen hackisch, aber Sie können die Definition der Funktion innerhalb des Befehls drucken, der an übergeben wurde, suund sie dann natürlich verwenden.

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

Dies funktioniert auch dann, wenn aus irgendeinem Grund die Umgebung der von erzeugten Shell suüberschrieben wird, da die Definition nach der Shell-Initialisierung eingefügt wird. Wenn Sie die Funktion kompatibel genug schreiben, funktioniert sie sogar, wenn die beiden fraglichen Benutzer unterschiedliche Shells verwenden.


+1 Wirklich ordentlicher Trick! Nur eine Frage: Kann die suUmgebung der Shell durch externe Faktoren überschrieben werden? Ich meine, in diesem Fall haben Sie die vollständige Kontrolle über die suBefehlszeile, da sie in einem Skript enthalten ist. Wie kann die Umgebung der neuen Shell überschrieben werden?
Joseph R.

Beispielsweise kann die von erzeugte Shell sueine Initialisierung der Umgebung durchführen. Auch suselbst kann ein Teil der Umgebung des Anrufers entfernt werden, um die Sicherheit ein wenig zu erhöhen (obwohl dies normalerweise durch leistungsfähigere Alternativen wie sudo) erfolgt.
Peterph

0

Das ist kein Skript, das Sie haben, es ist eine Funktion. Es hört sich jedoch so an, als ob Sie ein Skript möchten . Erstellen Sie ein geeignetes Skript und fügen Sie es je nach Bedarf entweder in /usr/local/binoder in ein /home/vagrant/bin, und dann sollten Sie in der Lage sein, zsu vagrant -c '/home/vagrant/bin/myscript.sh'


Es ist eine Funktion in einem Beispielskript. Meine Hoffnung war es, alles, was ich tun möchte, in dieses einzelne Skript aufzunehmen (Befehle werden als Root und als Vagrant-Benutzer ausgeführt) und kein separates Skript für den Root-Benutzer und kein separates Skript für den Vagrant-Benutzer zu haben.
Gdieckmann

0

Eine andere, etwas portablere Möglichkeit, dies zu tun (keine Bash-Abhängigkeit), besteht darin, dass Ihr Skript sich selbst aufruft und sein Verhalten basierend auf dem Kontext (UID) oder den Parametern ändert. Beispiele hierfür finden Sie in der Dokumentation, in der superein Skript angezeigt wird, für das Root-Berechtigungen erforderlich sind.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.