Runing a command without inheriting parent's environment

14

2

Is there a way to run a command "as if" it is in a new login session?

I've already tried env -i. However, I don't want to deal with various ENV variables I have to set or unset.

I've also tried bash -c "some command" and bash -l -c "some commmand", but they all copy the current environment.

The closest I have come is a ghetto solution: ssh me@localhost "some command"

dgo.a

Posted 2011-08-04T14:49:18.577

Reputation: 631

Use /bin/bash --login to get that behavior. I use it e.g. to get a proper $PATH. – Daniel Beck – 2011-08-04T14:50:40.180

That is the equivalent of /bin/bash --l, which I already tried. It copies the original environment. Try it: export SOME_VAL=something. Then /bin/bash --login. Then env | grep SOME_VAL. The value will be there. – dgo.a – 2011-08-04T15:03:29.670

Answers

12

Here's an answer that doesn't require sudo privileges or the user's password, but still provides an environment like what you'd get on a fresh login.

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

Example:

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

Breaking this down for explanation:

  1. env -i HOME="$HOME": Clears the environment. The -i sets up an empty environment with no variables whatsoever. This is problematic because it means that if you try to naively run bash -l it won't load your .bash_profile etc. because HOME isn't set. To mitigate this, we explicitly pass HOME="$HOME", creating an environment where HOME (and only HOME) is set.

  2. bash -l -c ...: Runs the desired command in a login shell. You'll want a login shell for this because we're starting from a clean environment and need to reload everything.

Notably:

  • This doesn't require sudo privileges (the sudo version does).
  • This doesn't require typing the user's password (the su version does).
  • This doesn't require running an SSH server and having a passwordless key that can be used to log back in to the machine (the ssh version does).

Elliott Slaughter

Posted 2011-08-04T14:49:18.577

Reputation: 271

Thanks, Elliott. It looks so simple and obvious... now that it's been pointed out to me. – dgo.a – 2018-06-26T00:29:52.157

12

su -l $USER

sudo -u $USER -i

For something even more aggressive try env -i bash, but that unsets everything including $HOME and $TERM.

user1686

Posted 2011-08-04T14:49:18.577

Reputation: 283 655

this does not work, obviously, if you do not have sudo access. Is there an alternative method that does not require sudo? – user5359531 – 2017-06-12T14:34:09.680

@user5359531: Yes – su -l $USER. – user1686 – 2017-06-12T14:49:40.400

1that asks for a password; I am logged in via ssh key authentication, so I dont even know what the password is. And a password prompt is going to kill script-ability. So far its looking like ssh $USER@localhost <command> is working better – user5359531 – 2017-06-12T15:30:37.130

@grawity Do you have a better answer to user5359531's question? – Melab – 2017-09-04T00:27:46.317

@Melab: See this answer.

– Elliott Slaughter – 2018-06-22T20:34:35.093

2Thanks! The second command gives me exactly what I want. I searched for more than 2 hours and did not find anything close to your reply. Based on your reply, I went back to man sudo and found: "if the target user is the same as the invoking user, no password is required." (The su seems to always asks for a password.) I'm such a fool to have overlooked something so simple in the first paragraph of a man page :( I avoided sudo in the first place because I assumed it always asked for a password. Thanks again! – dgo.a – 2011-08-04T16:15:23.860

1just a hint for others... if your logged in as $USER you will need to login as root and then sudo -u ... as your user. If you just do sudo -u as the user you will inherit. – Adam Gent – 2013-08-04T21:48:08.067