Passare una funzione a un altro utente in Bash?


11

Esiste un modo per passare una funzione da un utente a un altro utente?

Ad esempio, ho un piccolo script Bash che eseguo come root:

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

Tuttavia, la funzione user_func non è definita per l'utente Vagrant, solo per Root e non può essere eseguita.

L'altra mia opzione sarebbe quella di avere più righe di

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

Oppure, esegui più comandi ex:, su vagrant -c 'cmd1; cmd2; cmd3;'ma preferirei non avere l'eccesso, specialmente quando tento di eseguire più di 5 comandi come utente Vagrant.

È possibile passare una Funzione a un altro utente dallo stesso script (es. Non creare uno script sul disco come un altro utente e quindi eseguire quello script generato)? O c'è un'altra opzione che sto trascurando?

Risposte:


10

Sembra che tu debba exportprima definire quella funzione:

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

dovrebbe fare il trucco.

Il -fdice exportche si tratta di un nome di funzione piuttosto che un nome di variabile. Citando da help export:

Contrassegna ogni NOME per l'esportazione automatica nell'ambiente di comandi eseguiti successivamente. ....

Opzioni:

 -f   refer to shell functions

Come sottolineato da Peter e Stephane nei commenti, questo presuppone due cose:

  1. Che il tuo sucomando non sovrascriverà l'ambiente dell'utente
  2. Questa vagrantè la shell di login bash. In caso contrario, è possibile utilizzare la suriga di comando alternativa fornita da Stephane:

    su vagrant -c 'bash -c user_func'

Questo è esattamente quello che speravo. Non avevo capito che saresti stato in grado di esportare la funzione. Questo ha funzionato proprio come speravo che avrebbe fatto dopo aver modificato lo script di esempio. Grazie!
gdieckmann,

1
Bello, ma non funzionerà nei casi in cui susovrascrive l'ambiente.
peterph

1
Nota che funziona solo se la shell di login di vagrantè bash. In caso contrario,su vagrant -c 'bash -c user_func'
Stéphane Chazelas il

6

È un po 'hacker, ma è possibile stampare la definizione della funzione all'interno del sommand passata sue quindi è possibile utilizzarla.

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

Funzionerà anche se per qualche motivo l'ambiente della shell generato suverrà sovrascritto, poiché inserisce la definizione dopo l'inizializzazione della shell. Se si scrive la funzione in modo sufficientemente compatibile, funzionerà anche quando i due utenti in questione utilizzano shell diverse.


+1 Trucco davvero pulito! Solo una domanda, l' suambiente della shell può essere sovrascritto da fattori esterni? Voglio dire, in questo caso hai il controllo completo sulla suriga di comando poiché è in uno script. Come si può sovrascrivere l'ambiente della sua nuova shell?
Joseph R.,

Ad esempio, la shell generata da supotrebbe eseguire l'inizializzazione dell'ambiente. Inoltre sustesso potrebbe spogliare un po 'dell'ambiente del chiamante per rafforzare un po' la sicurezza (anche se questo di solito è fatto da alternative più potenti come sudo).
peterph

0

Non è uno script che hai, è una funzione. Sembra che tu voglia una sceneggiatura, però. Crea uno script corretto e inseriscilo, come richiesto dalle tue esigenze, in /usr/local/bin, o in /home/vagrant/bin, e di quanto dovresti essere in grado, ad esempiosu vagrant -c '/home/vagrant/bin/myscript.sh'


È una funzione all'interno di uno script di esempio. La mia speranza era di includere tutto ciò che volevo fare all'interno di questo singolo script (i comandi vengono eseguiti come Root e come utente Vagrant) e non avere uno script separato per l'utente Root e uno script separato per l'utente Vagrant.
gdieckmann,

0

Un altro modo un po 'più portatile per farlo (nessuna dipendenza da bash) è fare in modo che lo script si chiami da solo e che il suo comportamento cambi in base al contesto (uid) o ai parametri. esempi di questo sono riportati nella documentazione per supercui mostrano uno script che necessita di permessi di root, chiamando se stesso tramite super quando non root.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.