如何使用 sudo 命令保留所有环境变量

如何使用 sudo 命令保留所有环境变量

示例命令如下,以普通用户身份运行

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

因为PATH环境包含一条指向这个实例的路径python(而不是指向/usr/bin/python)。

我希望能够使用相同的环境变量运行 python 命令,因此

sudo which python

而是返回/usr/bin/python。使用-E选项将得到相同的结果。

如何以 root 权限运行 python 命令,但保留环境变量。我不想使用 sudo 命令指定所有变量,我猜只“复制”变量PATH就足够了。

换句话说,问题是:如何使用 运行 Python 命令sudo,该命令具有PATH与我当前作为普通用户所拥有的定义相同的定义?

答案1

如果你使用"!env_reset"取消设置选项和“安全路径“没有在你的 sudoer 文件中设置,那么选项“env_check”和“环境删除“可以将 PATH 从重置豁免中删除(即,它们充当黑名单条目)。

更可能的原因是系统 /etc/bashrc 或您自己的 .bashrc 正在将 PATH 重置为某个标准值(而不是根据需要添加到现有路径)。

在我自己的“系统” bashrc 中(我将其保存在 /etc/local 中,并在系统 bashrc 之后调用),我尽量不使用登录时定义的某些函数覆盖传入的路径:

# 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

我通过以下方式致电他们:

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

当然,如果问题出在你的发行版的 bashrc 中,你可以提交一个错误... ;-)

(这假设您没有使用“-i”调用 sudo,这表示从新环境开始)。

值得一提的是,在我的各种配置文件、bashrc 和 env 文件及其子文件的开头和结尾处……以及在我的发行版版本中(升级时必须重新添加)。我放置了通常不活动的调试节。开头:

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

并结束:

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

然后,如果我需要调试这样的问题,我可以触摸 /tmp/debug_local,它会为我的系统上的所有用户创建嘈杂的登录(通常只有我在该系统上)。

另外,如果你激活“-x”正在改变你的 PS4 线路:

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

(以上都是一行,用反斜杠分隔 - 它也是注释,即取消注释即可使用)

相关内容