为什么我的 $PATH 中会出现重复的条目?

为什么我的 $PATH 中会出现重复的条目?

我正在使用 Ubuntu 9.10 (karmic)。并且,它~/.pam_environment看起来如下所示。

PATH            DEFAULT=${PATH}:~/Adobe/Reader9/bin:~/texlive/2009/bin/x86_64-linux
GIT_EDITOR      DEFAULT=vim
MANPATH         DEFAULT=${MANPATH}:~/texlive/2009/texmf/doc/man
INFOPATH        DEFAULT=${INFOPATH}:~/texlive/2009/texmf/doc/info

但是,echo $PATH返回了如下所示的重复条目。

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:~/Adobe/Reader9/bin:~/texlive/2009/bin/x86_64-linux:~/Adobe/Reader9/bin:~/texlive/2009/bin/x86_64-linux

我尝试在文件中用DEFAULT替换。但是,这没有帮助。OVERRIDE~/.pam_environment

有人知道我的出了什么问题吗~/.pam_environment

答案1

问题似乎源于每次调用时pam_env默认读取用户~/.pam_environment。许多登录方法(我的机器上的 cron、lightdm、lightdm-autologin、login、sshd 和 su)调用pam_env两次:一次读取/etc/environment~/.pam_environment文件,一次读取/etc/default/locale文件。在这两种情况下都没有user_readenv设置标志,因此pam_env读取并执行~/.pam_environment两次。

要解决此问题,请转到您的/etc/pam.d目录,然后将以下内容添加到pam_env使用该选项调用的每一行中envfile=/etc/default/locale

user_readenv=0

答案2

检查您的/etc/pam.d/是否pam_env.so没有以某种方式加载两次,例如 在session和 在 中auth

答案3

确切地说,这不是一个答案,但可能对有重复问题的人有用


从我在 Stack Overflow 上收到的接受答案开始:如何在 shell 脚本中操作 $PATH 元素?我开发了一套稍大的工具。这里的大部分功劳应该归功于乔纳森莱夫勒他为我提供了撰写这些文章时所使用的模型。

添加但不重复

# Insure that a path element exists by adding it to the end if it does not
#
#   $1 name of the shell variable to set (e.g. PATH)
#   $3 the path element that we want to insure exists
function insure_path () {
    local path=$1
    local list=$(eval echo '$'$path)
    local pat=$2

    checkstr=$(echo "$list" | tr ":" "\n" | grep -Fm 1 "$pat")
    if [ "$checkstr" ] 
    then
        true
    else
        export $path=$(echo $list:$pat | sed -e 's|\(:\):*|\1|g' -e 's|:$||' -e'
s|^:||')
    fi
}

# Insure that a path element exists by adding it to the front if it does not
#
#   $1 name of the shell variable to set (e.g. PATH)
#   $2 the path element that we want to insure exists
function insure_path_front () {
    local path=$1
    local list=$(eval echo '$'$path)
    local pat=$2

    checkstr=$(echo "$list" | tr ":" "\n" | grep -Fm 1 "$pat")
    if [ $checkstr ] 
    then
        true
    else
        export $path=$(echo $pat:$list | sed -e 's|\(:\):*|\1|g' -e 's|:$||' -e'
s|^:||')
    fi
}

删除现有重复项

# Remove duplicates from a path. Preferes the ealiest instance of each
# duplicate because this preserves the semantics of the existing path
#
#   $1 name of the shell variable to set (e.g. PATH)
function unduplicate_path () {
    local path=$1
    local list=$(eval echo '$'$path)
    local split_list=$(echo "$list" | tr ":" " ")
    local tempp=""
    # Build the new version of $path from scrath
    for p in $split_list
    do
        insure_path_back tempp $p
    done
    # Now replace the existing version
    export $path=$tempp
}

答案4

另一种不麻烦的解决方法/etc/pam.d是使用临时变量组合,OVERRIDE如下所示:

PATH                DEFAULT=${PATH} OVERRIDE=${PAM_ENV_PREV_PATH}
PAM_ENV_PREV_PATH   DEFAULT=${HOME}/.local/bin:${HOME}/.dotnet/tools:${PATH}

在第一轮中PAM_ENV_PREV_PATH不存在,因此PATH仍为相同值。在第二轮中,PAM_ENV_PREV_PATH第一轮中已经存在,因此PATH将改用该值。

相关内容