Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Example command is as follows, run as a normal user

which python
/home/me/env/development/python 

because the PATH environment contains a path that points out to this instance of python (instead to point to /usr/bin/python).

I want to be able to run a python command with the SAME environment variable, so

sudo which python

which returns /usr/bin/python instead. Using the -E option gives the same result.

How can I run a python command with root-right, but with the environment variables preserved. I do not want to specify them all with the sudo command, and I guess to 'copy' only the PATH variables should be enough.

Question formulated in other words: How can I run a python command with sudo, which has the same PATH definition as I currently have as a normal user?

share|improve this question
1  
Does editing /etc/sudoers to unset the env_reset and maybe secure_path flags help? See man 5 sudoers and here. –  Michael Kjörling Jul 11 '13 at 9:43
    
I tried to include PATH in env_keep, but it did not change the outcome of the test –  Alex Jul 11 '13 at 10:56

1 Answer 1

If you use the "!env_reset" option to unset it and "secure_path" is not set in your sudoer's file, then the options "env_check" and "env_delete" can remove PATH from being exempt from reset (i.e. they function as blacklist entries).

A more likely cause would be that a system /etc/bashrc or your own .bashrc is resetting PATH to some standard value (and not adding to the existing path, as needed).

In my own "system" bashrc (which I keep in /etc/local and is called after the system bashrc), I take pains not to overwrite the passed in path with some functions defined at login:

# used in _path_op below
function empty {
    [[ $# -lt 1 ]] && return -1
    [[ -f $1 && ! -s $1 ]] && return 0
    [[ -d $1 ]] && {
        local -a entries=("$1"/*)
        [[ ${entries[0]} == "$1/*" ]] && return 0
    }
    return 1
}

function _path_has_subpath { [[ ${!1} =~ (:$2:|^$2:|:$2$) ]] ; }

function _path_op {
    (($#<3)) && return 1        # 3rd arg is path to <X>pend
    local fmt="$1" pathname="$2"; shift 2
    while (($#)); do 
        [[ -d $1 ]] && ! empty "$1" && {
            _path_has_subpath "$pathname" "$1" || 
                eval "export $(set $pathname $1; eval "echo $fmt")"
        }
        shift; 
    done    
}

# called with name of path (ex. 'PATH' & one or more sub paths 
# each of these prepend an "assign FORMAT" to the passed-in PATHVAR + pathcomp
function _path_append  { _path_op '$1=\"${!1}:$2\"' "$@" ; }
function _path_prepend  { _path_op '$1=\"$2:${!1}\"' "$@" ; }
typeset -x  _path_append _path_prepend _path_has_subpath _path_op

I call them via:

_path_append PATH /opt/kde3/bin /usr/local/bin "$PATH_HOME/bin" 
_path_prepend PATH "$PATH_HOME/bin/lib"

Of course if the problem is in your distro's bashrc, you might file a bug... ;-)

(this assumes you aren't calling sudo with the "-i" which says to start with a new environment).

FWIW, at the beginning and end of my various profile and bashrc and env files and their subfiles... AND in my distro's versions (have to be readded upon an upgrade). I put debug stanzas that are normally inactive. At beginning:

[[ ${DEBUG:-} || -O /tmp/debug_local ]] && { 
  echo "(${#BASH_LINENO[@]:-""})entering $BASH_SOURCE ..." >&2;
  [[ -O /tmp/debug_local ]] && source /tmp/debug_local ; }

and end:

[[ ${DEBUG:-} || -O /tmp/debug_local ]] && { 
  echo "(${#BASH_LINENO[@]:-""})exiting $BASH_SOURCE ..." >&2;

Then if I need to debug a problem like this, I can touch /tmp/debug_local and it will create noisy logins for all users on my system (which is usually only me on the system I have this on).

Also of use, if you activate "-x" is changing your PS4 line:

#export PS4='>>\
[$(__age)]${BASH_SOURCE:+${BASH_SOURCE[0]}}#i\
${LINENO}${FUNCNAME:+(${FUNCNAME[0]})}> '    

(The above is all one line, split with backslashes -- it is also a comment, i.e. uncomment to use)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.