Exécution d'une commande sans hériter de l'environnement du parent

14

Existe-t-il un moyen d'exécuter une commande "comme si" elle se trouvait dans une nouvelle session de connexion?

J'ai déjà essayé env -i. Cependant, je ne veux pas traiter de diverses variables ENV que je dois définir ou désactiver.

J'ai également essayé bash -c "some command"et bash -l -c "some commmand", mais ils copient tous l'environnement actuel.

Le plus proche que je suis venu est une solution ghetto: ssh me@localhost "some command"

dgo.a
la source
Utilisez /bin/bash --loginpour obtenir ce comportement. Je l'utilise par exemple pour obtenir un bon $PATH.
Daniel Beck
C'est l'équivalent de /bin/bash --lce que j'ai déjà essayé. Il copie l'environnement d'origine. Essayez: export SOME_VAL=something. Alors /bin/bash --login. Alors env | grep SOME_VAL. La valeur sera là.
dgo.a

Réponses:

12

Voici une réponse qui ne nécessite pas les privilèges sudo ou le mot de passe de l'utilisateur, mais fournit toujours un environnement comme celui que vous obtiendriez lors d'une nouvelle connexion.

env -i HOME="$HOME" bash -l -c 'your_command'

Exemple:

$ export ABC=123
$ env -i HOME="$HOME" bash -l -c 'env' | grep ABC
$ env HOME="$HOME" bash -l -c 'env' | grep ABC
ABC=123

Décomposer cela pour une explication:

  1. env -i HOME="$HOME": Efface l'environnement. Le -imet en place un environnement vide sans aucune variable . Ceci est problématique car cela signifie que si vous essayez de l'exécuter naïvement, bash -lil ne chargera pas votre .bash_profileetc., car il HOMEn'est pas défini. Pour atténuer cela, nous passons explicitement HOME="$HOME", créant un environnement où HOME(et seulement HOME) est défini.

  2. bash -l -c ...: Exécute la commande souhaitée dans un shell de connexion. Vous aurez besoin d'un shell de connexion pour cela, car nous partons d'un environnement propre et devons tout recharger.

Notamment:

  • Cela ne nécessite pas de privilèges sudo (la sudoversion le fait).
  • Cela ne nécessite pas de taper le mot de passe de l'utilisateur (la suversion le fait).
  • Cela ne nécessite pas d'exécuter un serveur SSH et d'avoir une clé sans mot de passe qui peut être utilisée pour se reconnecter à la machine (la sshversion le fait).
Elliott Slaughter
la source
Merci, Elliott. Cela semble si simple et évident ... maintenant que cela m'a été signalé.
dgo.a
12
su -l $USER

sudo -u $USER -i

Pour quelque chose d'encore plus agressif env -i bash, mais cela désactive tout, y compris $ HOME et $ TERM.

user1686
la source
2
Merci! La deuxième commande me donne exactement ce que je veux. J'ai cherché pendant plus de 2 heures et je n'ai rien trouvé proche de votre réponse. Sur la base de votre réponse, je suis retourné man sudoet j'ai constaté: "si l'utilisateur cible est le même que l'utilisateur appelant, aucun mot de passe n'est requis." (Le susemble toujours demander un mot de passe.) Je suis tellement idiot d'avoir oublié quelque chose de si simple dans le premier paragraphe d'une manpage :( J'ai évité sudo en premier lieu parce que je supposais qu'il demandait toujours un mot de passe. Merci encore une fois!
dgo.a
1
juste un indice pour les autres ... si vous $USERêtes connecté, vous devrez vous connecter en tant que root, puis en sudo -u ...tant qu'utilisateur. Si vous faites simplement en sudo -utant qu'utilisateur, vous hériterez.
Adam Gent
cela ne fonctionne évidemment pas si vous n'y avez pas sudoaccès. Existe-t-il une méthode alternative qui ne nécessite pas sudo?
user5359531
@ user5359531: Oui - su -l $USER.
user1686
1
qui demande un mot de passe; Je suis connecté via l'authentification par clé ssh, donc je ne sais même pas quel est le mot de passe. Et une invite de mot de passe va tuer la capacité de script. Jusqu'à présent, son apparence ssh $USER@localhost <command>fonctionne mieux
user5359531