Runing a command without inheriting parent's environment

11,147

Solution 1

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).

Solution 2

su -l $USER

sudo -u $USER -i

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

Share:
11,147

Related videos on Youtube

dgo.a
Author by

dgo.a

Updated on September 18, 2022

Comments

  • dgo.a
    dgo.a over 1 year

    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 not-so-clean solution:

    ssh me@localhost "some command"`
    
    • dgo.a
      dgo.a almost 13 years
      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
    dgo.a almost 13 years
    Thanks! 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!
  • Adam Gent
    Adam Gent almost 11 years
    just 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.
  • user5359531
    user5359531 almost 7 years
    this does not work, obviously, if you do not have sudo access. Is there an alternative method that does not require sudo?
  • user1686
    user1686 almost 7 years
    @user5359531: Yes – su -l $USER.
  • user5359531
    user5359531 almost 7 years
    that 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
  • Melab
    Melab over 6 years
    @grawity Do you have a better answer to user5359531's question?
  • Elliott Slaughter
    Elliott Slaughter almost 6 years
    @Melab: See this answer.