$ PATH変数から冗長パスを削除します


125

$ 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

どこで6回定義しましたか?どのファイルで?
hovanessyan 2012


回答:


122

あなただけを実行します:

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

変更したい場合は、.bashrc、bash.bashrc、/ etc / profile-システムとユーザーのニーズに合ったものに追加してください。

注:これはLinux用です。新しいコーダーのためにこれを明確にします。( `、 ')SET =これらを試行しないでください。


はい、bash.bashrcに永続的に設定しました。それで、コマンドはこのようなものでなければなりませんか? echo 'export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games' >> ~/.bashrc
チャールズヘンドリー

お使いのOSに応じて、一連の構成が実行されるということです。PATH変数が後で上書きされないようにする必要があります。(1人のユーザーに対して)これを行う最も簡単な方法は、ユーザーの個人用.bashrcで上書きすることです。これは通常、ユーザーのホームディレクトリにあります。
hovanessyan 2012

1
コマンドはPATHを-$ PATH(PATHの現在の値)+文字列/ usr / local / sbin:/ usr / local / bin:/ usr / sbin:/ usr / bin:/ sbin:/ bin:/に設定しますusr / gam‌ es。文字列だけが必要な場合は、コマンドから$ PATH +セミコロン(:)を削除します。エコーを使用するか、ファイル〜/ .bashrcを手動で編集するかは関係ありません。
hovanessyan 2012

bash.bashrcファイルは/ etcフォルダーにあります。ただし、$ PATH変数は表示されないため、どこで編集すればよいかわからない
charles hendry

最初のコメントでは、/ etc / bash.bashrcではなく〜/ .bashrc(引用:>>〜/ .bashrc)にエコーします。特定のユーザーのPATHを変更する場合は、/ home / <ユーザーの名前> /。bashrcファイルで編集します。/etc/bash.bashrcはすべてのユーザーに適用されます。
hovanessyan 2012

70

Bashを使用している場合、たとえば、変数/home/wrong/dir/からディレクトリを削除したい場合は、次のことも実行できPATHます。

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

1
除外したい/ etc / profileにディレクトリが追加されたが、/ etcへの書き込みアクセス権がないため、これは私にとって便利でした。ありがとう:)
Samizdis 2014

13
Protip:sed式で別のデリミネーターを使用して、\ /エスケープを回避できます:PATH=$(echo $PATH | sed -e 's|:/home/wrong/dir|$||')
iNecas

4
このトリックは、新しいPATHをすぐに取得したい場合、および現在の端末からログアウトしたくない場合に役立ちます。ただし、混乱を避けるために、PATH echo $PATH | sed -e 's/:\/home\/wrong\/dir\/$//'に割り当てる前に、PATH生成コマンド(つまり)を試してみてください。
バイオサイバーマン、

2
削除するパスがたまたま最初のパスである場合、これは機能しません$PATH。これを使用してください:PATH=$(echo :$PATH: | sed -e 's,:/home/wrong/dir:,:,g' -e 's/^://' -e 's/:$//')
Robin Hsu

$ PATH=エコー$ PATH |が機能しませんでした sed -e 's /:\ / scratch \ / sjn \ / anaconda \ / bin \ / python \ / $ //' ``による/ scratch / sjn / anaconda / bin / pythonの削除
Mona Jalal

13

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

これにより、そのディレクトリの各インスタンスがパスから削除されます。

パスにディレクトリが必要だが、冗長性がない場合は、他の関数の1つを使用するだけで済みます。たとえば、特定のケースでは:

$ 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で動作すると想定します。で機能しないことを知って驚いたでしょうcshfish', or ksh`。私はそれがWindowsコマンドシェルまたはPowershellで動作することを疑います。

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

+1。pathremove()は、csh、ksh、bashなどのすべてのシェルフレーバーで機能しますか?ところで、RHELの/ etc / profileにはpartremove()はありませんが、pathmunge()しかありません。
Tagar

1
@Tagar他のすべてのシェルとの互換性については保証しません。私はあなたが使っているどんなシェルでもそれをテストすることを勧めます、そしてそれがあなたのシェルで動かないなら、あなたがそれをインストールしてあればPythonを使うことができます-私は方法を説明するために答えにいくつかのPythonを追加しました。
アーロンホール

「3.5.3 Shell Parameter Expansion」を正しく読んだ場合、これ${!PATHVARIABLE}は一種の変数の間接参照ですが、ここでどのように機能するかわかりません。説明して頂けますか?
loxaxs

@loxaxsこれは、これらのbash関数のローカル変数であり、local組み込み関数で宣言されています(関数内でのみ使用できます)。さらに質問がある場合は、サイトで新しい質問をする必要があります(最初に検索してから確認してください)正確な複製を作成するわけではありません...)。
アーロンホール

これは本当に興味深い答えです、記事を書いてくれてありがとう!ただし、めちゃくちゃになったPATH変数をクリーンアップするという元の質問は、エレガントに解決されていないようです(もちろん、私は認めます。この関数を使用すると、最初はめちゃくちゃなPATHになってしまいます)。
クリスチャンヘレンツ

9

以下は、PATHをクリーンアップする1行のコードです

  • PATHの順序を乱すことはなく、重複を削除するだけです。
  • 扱い:優雅にempパス
  • 特殊文字は使用されていないため、エスケープは不要
  • /bin/awkPATHが壊れている場合でも機能するように 使用します

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

1
誰かがそれをテストしましたか?安全ですか?
ジョーRR

2
awkがインストールされていない場合は、パスをクリーンアップします。echo$ PATHを使用して、パスをtxtファイルにコピーしてください
Jose Pita

うまくいきません... awkをインストールしましたが、一部の重複が削除されません。
クリスチャンヘレンツ

3
  1. ただ echo $PATH
  2. 詳細をテキストエディタにコピーする
  3. 不要なエントリを削除する
  4. PATH= # pass new list of entries

2

重複するパスを削除したいだけの場合は、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"

そして、最後に〜/ .profileに入れます。私はBASHをほぼ独占的に使用しているので、他のシェルでは試していません。


1
ソリューションの+1。ところで、リストに次々と追加される場合にのみ、重複パスが削除されます。あなたは、変更される可能性が|uniqために|sort|uniqこれを修正するが、これは私が望ましい副作用ではないと思いますパス内のすべてのディレクトリの順序を変更します。
Tagar

1

シェルがBashであると仮定すると、パスを設定できます

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

しかし、レボンが別の答えで言ったように、シェルを終了するとすぐに、変更は失われます。おそらくPATH~/.bash_profileまたはをセットアップする必要があります~/.bashrc


1

bashでは$ {var / find / replace}するだけです

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

または、この場合(置換ビットが空であるため)ちょうど:

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

私は最初にここに来ましたが、パラメーターの拡張があると思ったので、他のウェアに行きましたこれを行う。sedよりも簡単です!。

変数のプレースホルダー文字または単語をBashの別の変数の値に置き換える方法は?


%文字列の終わりが#最初の場合に一致することを意味します。
サブジェントン2015年

0

の価値を「編集」する標準的なツールはありません $PATH(つまり、「まだ存在しない場合にのみフォルダを追加する」または「このフォルダを削除する」)。

次回ログインしたときのパスを確認するには、telnet localhost(またはtelnet 127.0.0.1)を。次に、ユーザー名とパスワードを要求します。

これにより、新しいログインシェル(つまり、現在の環境から何も継承しない完全に新しいシェル)が得られます。

$PATHそこの値を確認し、正しくなるまでrcファイルを編集できます。これは、重要なファイルに変更を加えた後で、再度ログインできるかどうかを確認する場合にも役立ちます。


ユーザー名/パスワードを入力する代わりに、と入力するだけ/bin/bash -iです。手間が大幅に軽減されます。
Ed Heal

0

これらの重複したパスをどのようにPATH変数に追加しましたか?.ファイルの1つを編集しておく必要があります。(.tcshrc、または.bashrc、など特定のシステム/シェルによって異なります)。それを修正する方法は、ファイルを再度編集して、重複するパスを削除することです。

ファイルを編集しておらず、対話形式でPATHを変更している必要があります。その場合、変更は「固定」されません。つまり、別のシェルを開いたり、ログアウトして再度ログインしたりすると、変更は自動的に失われます。

システム全体の設定ファイルもいくつかありますが、それらを変更することはほとんどないため、個人のホームディレクトリのファイルを変更する可能性が高いことに注意してください(一連のパスを確定したら、これらの変更を永続的にする場合)。


0

簡単なコピーと貼り付けのテンプレートには、次のPerlスニペットを使用します。

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

この方法では、置換演算子のスラッシュをエスケープする必要はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.