programing

$PATH 변수에서 중복 경로 제거

magicmemo 2023. 5. 26. 20:50
반응형

$PATH 변수에서 중복 경로 제거

$PATH 변수에서 동일한 경로를 6번 정의했습니다.

나는 그것이 작동하는지 확인하기 위해 로그아웃한 것이 아닙니다.

중복을 제거하려면 어떻게 해야 합니까?

$PATH 변수는 다음과 같습니다.

echo $PATH

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin:/home/flacs/Programmes/USFOS/bin

어떻게 재설정해야 합니까?

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

실행하기만 하면 됩니다.

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

시스템 및 사용자 요구에 맞는 .vmsrc, bash.vmsrc, /etc/profile에 영구적으로 변경하려면 현재 세션에 대한 것입니다.

참고: Linux용입니다.새로운 코더들을 위해 이것을 분명히 할 것입니다.(', ') = 이것들을 설정하려고 하지 마십시오.

Bash를 사용하는 경우 디렉터리를 제거하려는 경우에도 다음 작업을 수행할 수 있습니다./home/wrong/dir/의 신의에서.PATH변수:

PATH=`echo $PATH | sed -e 's/:\/home\/wrong\/dir\/$//'`

Linux: $PATH 변수에서 중복 경로 제거

Linux From Scratch에는 /etc/profile에 기능이 있습니다.

# Functions to help us manage paths.  Second argument is the name of the
# path variable to be modified (default: PATH)
pathremove () {
        local IFS=':'
        local NEWPATH
        local DIR
        local PATHVARIABLE=${2:-PATH}
        for DIR in ${!PATHVARIABLE} ; do
                if [ "$DIR" != "$1" ] ; then
                  NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
                fi
        done
        export $PATHVARIABLE="$NEWPATH"
}

이 기능은 중복되지 않도록 경로에 추가하기 위해 다음 기능과 함께 사용됩니다.

pathprepend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}"
}

pathappend () {
        pathremove $1 $2
        local PATHVARIABLE=${2:-PATH}
        export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1"
}

단순한 사용법은 그냥 주는 것입니다.pathremove제거할 디렉토리 경로 - 그러나 정확하게 일치해야 합니다.

$ pathremove /home/username/anaconda3/bin

경로에서 해당 디렉터리의 각 인스턴스가 제거됩니다.

중복이 없는 디렉토리를 경로에 배치하려면 특정한 경우에 대해 다른 기능 중 하나만 사용할 수 있습니다.

$ pathprepend /usr/local/sbin
$ pathappend /usr/local/bin
$ pathappend /usr/sbin
$ pathappend /usr/bin
$ pathappend /sbin
$ pathappend /bin
$ pathappend /usr/games

그러나 가독성이 문제가 되지 않는 한, 현 시점에서는 다음을 수행하는 것이 좋습니다.

$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

위의 내용이 인간에게 알려진 모든 껍질에서 작동합니까?

저는 위와 같은 일을 할 것이라고 생각합니다.sh,dash,그리고.bash적어도.저는 그것이 작동하지 않는다는 것을 알면 놀랄 것입니다.csh,fish', orksh'에서입니다. 윈도우 명령 셸이나 파워셸에서 작동할지 의문입니다.

Python을 사용하는 경우 다음과 같은 명령어가 직접 요청된 작업을 수행해야 합니다(즉, 중복 경로 제거).

$ PATH=$( python -c "
import os
path = os.environ['PATH'].split(':')
print(':'.join(sorted(set(path), key=path.index)))
" )

하나의 라이너(여러 줄 문제를 회피하기 위한 것):

$ PATH=$( python -c "import os; path = os.environ['PATH'].split(':'); print(':'.join(sorted(set(path), key=path.index)))" )

위에서는 이후의 중복 경로를 제거합니다.이전의 중복 경로를 제거하려면 역방향 목록의 인덱스를 사용하고 다시 역방향으로 이동합니다.

$ PATH=$( python -c "
import os
path = os.environ['PATH'].split(':')[::-1]
print(':'.join(sorted(set(path), key=path.index, reverse=True)))
" )

다음은 PATH를 정리하는 한 줄 코드입니다.

  • PATH 순서를 방해하지 않고 중복만 제거합니다.
  • : 및 empth PATH를 정상적으로 처리합니다.
  • 특수 문자가 사용되지 않으므로 이스케이프가 필요하지 않습니다.
  • 사용하다/bin/awk합니다 ㅠㅠㅠ PATH ㅠㅠㅠㅠㅠ

    export PATH="$(echo "$PATH" |/bin/awk 'BEGIN{RS=":";}
    {sub(sprintf("%c$",10),"");if(A[$0]){}else{A[$0]=1;
    printf(((NR==1)?"":":")$0)}}')";
    
  1. 그저.echo $PATH
  2. 텍스트 편집기에 세부 정보 복사
  3. 원치 않는 항목 제거
  4. PATH= # pass new list of entries

중복 경로를 제거하려면 여러 perl5/bin 경로에 문제가 있어 얼마 전에 작성한 스크립트를 사용합니다.

#!/bin/bash
#
# path-cleanup
#
# This must be run as "source path-cleanup" or ". path-cleanup"
# so the current shell gets the changes.

pathlist=`echo $PATH | sed 's/:/\n/g' | uniq`

# echo "Starting PATH: $PATH"
# echo "pathlist: $pathlist"
unset PATH
# echo "After unset, PATH: $PATH"
for dir in $pathlist
do
    if test -d $dir ; then
        if test -z $PATH; then
            PATH=$dir
        else
            PATH=$PATH:$dir
        fi
    fi
done
export PATH
# echo "After loop, PATH: $PATH"

그리고 마지막에 제 프로필에 넣었습니다.저는 BASH를 거의 독점적으로 사용하기 때문에 다른 쉘에서는 사용해본 적이 없습니다.

Bash에서는 ${var/find/place}만 가능합니다.

PATH=${PATH/%:\/home\/wrong\/dir\//}

또는 이 경우(교체 비트가 비어 있으므로) 다음과 같이 하십시오.

PATH=${PATH%:\/home\/wrong\/dir\/}

제가 먼저 왔는데 파라미터 확장이 있을 것 같아서 다른 제품으로 갔습니다.sed보다 쉽네요!

변수의 자리 표시자 문자 또는 단어를 Bash의 다른 변수의 값으로 대체하는 방법은 무엇입니까?

이러한 중복 경로를 어떻게 PATH 변수에 추가했습니까?은 당신의 다중합니다야편 중 한 것이 틀림없습니다.. (으)로. (.)로..tcshrc또는.bashrc(예: 특정 시스템/쉘에 따라 달라집니다.수정 방법은 파일을 다시 편집하고 중복 경로를 제거하는 것입니다.

파일을 편집하지 않은 경우 대화형으로 PATH를 수정해야 합니다.이 경우 변경사항이 "고정"되지 않습니다. 즉, 다른 셸을 열거나 로그아웃했다가 다시 로그인하면 변경사항이 자동으로 사라집니다.

일부 시스템 전체 구성 파일도 있지만 이러한 파일을 수정했을 가능성은 낮으므로 개인 홈 디렉토리에서 파일을 변경할 가능성이 높습니다(경로 집합에 정착한 후 변경 내용을 영구적으로 변경하려는 경우).

간편한 복사 붙여넣기 템플릿을 위해 다음 Perl 스니펫을 사용합니다.

PATH=`echo $PATH | perl -pe s:/path/to/be/excluded::`

이렇게 하면 대체 연산자의 슬래시를 피할 수 있습니다.

간편하고 완벽한 솔루션

다음은 이 인기 있는 답변의 버전과 추가 설명입니다.중복되거나 원하지 않는 PATH 구성 요소를 수동으로 제거해야 합니다.이것은 매우 우아하지는 않지만 종종 훨씬 단순하고 바보 같은 것일 수 있습니다.

  1. echo $PATH > path.txt에 기록합니다. 텍스트 파일에 기록합니다.
  2. path 경로 사용).txt 편집(예: 사용)nano path.txt)
  3. export PATH=$(cat path.txt)합니다.
  4. rm path.txt합니다.

참고: 이는 현재 세션에 대한 것입니다. PATH를 영구적으로 변경하려는 경우 bash 설정 파일(예: ~/.bashrc)을 조정해야 합니다.

셸이 Bash라고 가정하면 다음을 사용하여 경로를 설정할 수 있습니다.

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

하지만 레본이 다른 대답에서 말했듯이, 당신이 셸을 종료하는 즉시 변경 사항이 사라질 것입니다.당신은 아마도 당신의 것을 설정하기를 원할 것입니다.PATH~/.bash_profile또는~/.bashrc.

값을 "편집"할 수 있는 표준 도구는 없습니다.$PATH(즉, "존재하지 않는 폴더만 추가" 또는 "이 폴더 제거").

다음에 로그인할 때 경로를 확인하려면 다음을 사용합니다.telnet localhost(또는)telnet 127.0.0.1그러면 사용자 이름과 암호를 묻는 메시지가 나타납니다.

그러면 새 로그인 셸(즉, 현재 환경에서 아무것도 상속하지 않는 완전히 새로운 로그인 셸)이 제공됩니다.

값을 확인할 수 있습니다.$PATHrc 파일이 정확해질 때까지 편집합니다.중요한 파일을 변경한 후 다시 로그인할 수 있는지 여부를 확인하는 데도 유용합니다.

터미널에서 아래 코드를 실행하여 java PATH=$(tr : '\n' <<"$PATH" | grep -x -v "/usr/lib/bin" | paste -sd:) 여기서 솔루션을 삭제합니다.

이 기능은 경로 중복 제거에 효과적이며 순서를 유지합니다.

### remove dups in $PATH keeping order
# https://sites.google.com/site/jdisnard/path-dupes
    
function path_de-dup() {

  declare -A SPATH
  local RET_VAL
  local A

  local OIFS=$IFS
  IFS=':'
  for A in ${PATH}
  do
    [ -z "${SPATH[${A}]}" ] || continue

    # By this point no dupe was found
    SPATH[${A}]=${#SPATH[*]}

    # Reconstruct the $PATH
    if [ -z "$RET_VAL" ]
     then RET_VAL="$A"
    else RET_VAL="${RET_VAL}:${A}"
    fi

  done
  IFS=$OIFS
  PATH=$RET_VAL
  export PATH
}

경로의 시작 부분에 새 디렉터리를 추가하고 디렉터리가 아닌 구성 요소를 제거하며 나머지 디렉터리의 순서를 변경하지 않고 중복 항목을 제거하는 함수를 정의했습니다.

function add_path() {
  readarray -t patharray < <(echo $PATH | tr ':' '\n')
  uniqpath=()
  for dir in "${@}" "${patharray[@]}"; do
    if [ -d "${dir}" ] && [[ ! "${uniqpath[@]}" =~ "${dir}" ]]; then
      uniqpath+=("${dir}")
    fi
  done
  IFS=: eval 'PATH="${uniqpath[*]}"'
}

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

$ export ORACLE_HOME=/u01/app/oracle/product/19.0.0.0/dbhome_1
$ add_path $ORACLE_HOME/bin $ORACLE_HOME/OPatch
$ echo $PATH
/u01/app/oracle/product/19.0.0.0/dbhome_1/bin:/u01/app/oracle/product/19.0.0.0/dbhome_1/OPatch:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

위의 Alex Jolig와 GreenFox의 원라이너를 기반으로 AWK가 대본이 예상했던 위치에 있지 않다는 불만(내 Mac에서는 그렇지 않음)으로 시작했습니다.

if [[ -x /usr/bin/awk ]]; then
  export PATH="$(echo "$PATH" | /usr/bin/awk 'BEGIN { RS=":"; } { sub(sprintf("%c$", 10), ""); if (A[$0]) {} else { A[$0]=1; printf(((NR==1) ?"" : ":") $0) }}')"
  echo $PATH
else
  echo "AWK is not located at /usr/bin/awk" # for the truly paranoid
fi

이것을 다시 원라이너로 변환하면,

if [[ -x /usr/bin/awk ]]; then export PATH="$(echo "$PATH" | /usr/bin/awk 'BEGIN { RS=":"; } { sub(sprintf("%c$", 10), ""); if (A[$0]) {} else { A[$0]=1; printf(((NR==1) ?"" : ":") $0) }}')" ; fi

이렇게 하면 AWK가 예상되는 위치에 있는지 확인할 수 있으며 .bashrc 또는 .zshrc 파일의 끝에 이 줄을 놓기만 하면 됩니다.

PATH=echo $PATH | sed 's/:/\n/g' | sort -u | sed ':a;N;$!ba;s/\n/:/g'

언급URL : https://stackoverflow.com/questions/11650840/remove-redundant-paths-from-path-variable

반응형