web-dev-qa-db-ja.com

PATHにパスを正しく追加するにはどうすればよいですか?

新しいパスをPATH環境変数に追加する必要がある場所を知りたいのですが。これは.bashrc(たとえば)を編集することで実現できることはわかっていますが、その方法は明確ではありません。

こちらです:

export PATH=~/opt/bin:$PATH

それともこれ?

export PATH=$PATH:~/opt/bin
994
Paolo

シンプルなもの

PATH=$PATH:~/opt/bin

または

PATH=~/opt/bin:$PATH

末尾に~/opt/binを追加するかどうか(他のすべてのディレクトリの後に検索され、同じ名前のプログラムが複数のディレクトリにある場合)または最初に(他のすべてのディレクトリの前に検索される)に応じて)。

同時に複数のエントリを追加できます。 PATH=$PATH:~/opt/bin:~/opt/node/binまたは注文のバリエーションは問題なく機能します。行の先頭にexportを入れないでください。複雑になるためです(下記の「bash以外のシェルに関する注意」を参照)。

PATHが多くの異なるコンポーネントによって構築されている場合、重複したエントリになる可能性があります。 Unixが検出するホームディレクトリパスを追加する方法を参照してください。awkコマンドで重複した$ PATHエントリを削除します 重複を追加しないようにするか削除します。

ちなみに、一部のディストリビューションでは、存在する場合は自動的に~/binをPATHに入れます。

どこに置くか

PATHを変更する行を~/.profileに、または~/.bash_profileに変更してください。

~/.bash_rcはどのプログラムにも読み込まれず、~/.bashrcはbashのインタラクティブなインスタンスの構成ファイルであることに注意してください。 ~/.bashrcには環境変数を定義しないでください。 PATHなどの環境変数を定義する適切な場所は~/.profile(またはbash以外のシェルを気にしない場合は~/.bash_profile)です。 を参照してください。これらの違いと、どちらを使用すればよいですか?

/etc/environment~/.pam_environmentには入れないでください。これらはシェルファイルではないため、$PATHのような置換を使用することはできません。これらのファイルでは、変数をオーバーライドするだけで、追加することはできません。

一部のシステムスクリプトの潜在的な複雑化

変数がすでに環境にある場合は、exportは必要ありません。変数の値の変更は環境に反映されます。¹PATHは、ほとんど常に環境にあります。すべてのUNIXシステムは、それを非常に早い段階で設定します(通常、実際には最初のプロセスです)。

ログイン時に、PATHがすでに環境内にあり、すでにいくつかのシステムディレクトリが含まれていることを信頼できます。ある種の仮想環境のセットアップ中に早期に実行される可能性があるスクリプトを作成している場合は、PATHが空でなくエクスポートされていることを確認する必要がある場合があります。PATHがまだ設定されていない場合次に、PATH=$PATH:/some/directoryのようなものはPATH:/some/directoryに設定し、最初の空のコンポーネントは現在のディレクトリを意味します(.:/some/directoryなど)。

if [ -z "${PATH-}" ]; then export PATH=/usr/local/bin:/usr/bin:/bin; fi

Bash以外のシェルに関する注意

Bash、ksh、zshでは、exportは特別な構文であり、PATH=~/opt/bin:$PATHexport PATH=~/opt/bin:$PATHはどちらも正しく機能します。ダッシュ(多くのシステムでは/bin/sh)のような他のBourne/POSIXスタイルのシェルでは、exportは通常のコマンドとして解析され、2つの違いがあります。

ダッシュのような砲弾では export PATH=~/opt/bin:$PATH PATHをリテラル文字列~/opt/bin/:に設定し、その後に最初のスペースまでのPATHの値を続けます。 PATH=~/opt/bin:$PATH(最小限の割り当て) 引用符を必要としない で正しいことを行います。移植可能なスクリプトでexportを使用する場合は、export PATH="$HOME/opt/bin:$PATH"、またはPATH=~/opt/bin:$PATH; export PATH(またはPATH=$HOME/opt/bin:$PATH; export PATH)を記述する必要があります。 export var=valueを受け入れ、チルド拡張を行いませんでした)。

¹ これは、Bourneシェル(実際のBourneシェルでは、最新のPOSIXスタイルのシェルではない)には当てはまりませんでしたが、最近、このような古いシェルに遭遇することはほとんどありません。

どちらの方法でも機能しますが、同じことはしません。PATHの要素は左から右にチェックされます。最初の例では、~/opt/binの実行可能ファイルは、たとえば/usr/binにインストールされた実行可能ファイルよりも優先されます。これは、必要な場合とそうでない場合があります。

特に、安全の観点から、前面にパスを追加することは危険です。なぜなら、誰かが~/opt/binへの書き込みアクセス権を取得できれば、たとえば、別のlsを置くことができるからです。そこに、気づかずに/bin/lsの代わりに使用する可能性があります。 sshと同じか、ブラウザまたは選択肢を想像してみてください(パスに。を入れると、同じことが3倍になります)。

88
Ulrich Schwarz

私は質問2で混乱しています(無関係な問題が原因だったため、質問から削除されたため):

別の行にさらにパスを追加する実行可能な方法は何ですか?最初はこれでうまくいくと思った:

export PATH=$PATH:~/opt/bin
export PATH=$PATH:~/opt/node/bin

ただし、2番目の割り当てでは~/opt/node/binが追加されるだけでなく、以前に割り当てられたPATH全体も追加されるため、そうではありません。

これは可能な回避策です。

export PATH=$PATH:~/opt/bin:~/opt/node/bin

ただし、読みやすくするために、1つのパスに1つの割り当てを指定することをお勧めします。

あなたが言うなら

PATH=~/opt/bin

それはallで、PATHに含まれます。 PATHは単なる環境変数であり、PATHに追加したい場合は、必要な内容で変数を再構築する必要があります。つまり、質問2の例として挙げているのは、質問の要点を完全に見逃していない限り、まさにあなたがしたいことです。

私はコードで両方のフォームを使用しています。欠落している可能性のあるディレクトリに対応するために、作業中のすべてのマシンにインストールする次のような一般的なプロファイルがあります。

export PATH=/opt/bin:/usr/local/bin:/usr/contrib/bin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11
# add optional items to the path
for bindir in $HOME/local/bin $HOME/bin; do
    if [ -d $bindir ]; then
        PATH=$PATH:${bindir}
    fi
done
39
Carl Cravens

Linuxは、$PATH環境変数を使用して実行可能な検索パスを決定します。ディレクトリ/ data/myscriptsを$PATH環境変数の先頭に追加するには、以下を使用します。

PATH=/data/myscripts:$PATH

そのディレクトリをパスの最後に追加するには、次のコマンドを使用します。

PATH=$PATH:/data/myscripts

ただし、スクリプト内で環境変数を設定すると、その変更はスクリプト内でのみ有効になるため、上記の説明では不十分です。この制限を回避する方法は2つしかありません。

  • スクリプト内で環境変数をエクスポートすると、スクリプトによって呼び出されるすべてのプログラム内で有効になります。スクリプトを呼び出したプログラム内では効果がないことに注意してください。
  • スクリプトを呼び出すプログラムが呼び出しの代わりにインクルードすることでそうする場合、スクリプトの環境変更は呼び出しプログラム内で有効になります。このようなインクルードは、dotコマンドまたはsourceコマンドで実行できます。

例:

$HOME/myscript.sh
source $HOME/myscript.sh

包含には、基本的に「呼び出し」スクリプトに「呼び出された」スクリプトが組み込まれています。これはCの#includeのようなものです。そのため、「呼び出し」スクリプトまたはプログラム内で効果的です。ただし、もちろん、呼び出し元のプログラムから呼び出されるプログラムやスクリプトでは効果がありません。これを呼び出しチェーン全体で有効にするには、exportコマンドを使用して環境変数の設定に従う必要があります。

例として、bashシェルプログラムは、ファイル.bash_profileの内容をインクルードによって組み込んでいます。 .bash_profileに次の2行を配置します。

PATH=$PATH:/data/myscripts
export PATH

これらの2行のコードを効果的にbashプログラムに配置します。したがって、bash内では、$ PATH変数に$HOME/myscript.shが含まれます。exportステートメントのため、bashによって呼び出されるプログラムには、変更された$PATH変数があります。また、bashプロンプトから実行するプログラムはすべてbashによって呼び出されるため、bashプロンプトから実行するすべてのプログラムに対して新しいパスが有効になります。

要点は、パスに新しいディレクトリを追加するには、シェルに含まれているスクリプト内の$ PATH環境変数にディレクトリを追加または追加する必要があり、$PATH環境変数をエクスポートする必要があります。

詳細 ここ

25
Steve Brown

しばらくの間、重複を心配する必要なくパスに要素を追加するのに役立つ2つの関数pathaddpathrmを手元に置いてきました。

pathaddは、単一のパス引数とオプションのafter引数を取り、これらが指定された場合はPATHに追加され、そうでない場合は先頭に追加されます。

ほとんどすべての状況で、パスに追加する場合は、パスに既に存在するものをすべて上書きする可能性があります。そのため、デフォルトで先頭に追加することにしました。

pathadd() {
    newelement=${1%/}
    if [ -d "$1" ] && ! echo $PATH | grep -E -q "(^|:)$newelement($|:)" ; then
        if [ "$2" = "after" ] ; then
            PATH="$PATH:$newelement"
        else
            PATH="$newelement:$PATH"
        fi
    fi
}

pathrm() {
    PATH="$(echo $PATH | sed -e "s;\(^\|:\)${1%/}\(:\|\$\);\1\2;g" -e 's;^:\|:$;;g' -e 's;::;:;g')"
}

これらをPATH環境を変更したいスクリプトに入れてください。

pathadd "/foo/bar"
pathadd "/baz/bat" after
export PATH

パスが既に存在する場合は、パスに追加しないことが保証されています。確認したい場合は/baz/batが最初です。

pathrm "/baz/bat"
pathadd "/baz/bat"
export PATH

これで、パスが2倍になることなく既にパスにある場合、どのパスも前面に移動できます。

20
Brett Ryan

他のディストリビューションについて話すことはできませんが、Ubuntuには/ etc/environmentというファイルがあります。これは、すべてのユーザーのデフォルトの検索パスです。私のコンピューターは私だけが使用しているので、スクリプトに追加した一時的な追加でない限り、必要なディレクトリをパスに入れます。

10
Jim Bradley

PATH=/a/b:$PATHを使用すると、PATHへのパスを追加する「正しくない」方法と見なされる場合があります。

  1. 実際にはディレクトリではないパスを追加します。
  2. 同じ形式でPATHにすでにあるパスを追加します。
  3. 相対パスを追加します(検索される実際のディレクトリは、現在の作業ディレクトリを変更すると変わるため)。
  4. すでにPATHにあるパスを別の形式で追加します(つまり、シンボリックリンクまたは..を使用することによるエイリアス)。
  5. 4を行わない場合は、PATHの他のエントリを上書きするために、パスをPATHの前に移動しないでください。

この(Bashのみの)関数は、上記の状況(例外を除き、以下を参照)で「正しいこと」を実行し、エラーコードを返し、人間に対してNiceメッセージを出力します。エラーコードとメッセージは、不要な場合は無効にできます。

prepath() {
    local usage="\
Usage: prepath [-f] [-n] [-q] DIR
  -f Force dir to front of path even if already in path
  -n Nonexistent dirs do not return error status
  -q Quiet mode"

    local tofront=false errcode=1 qecho=echo
    while true; do case "$1" in
        -f)     tofront=true;       shift;;
        -n)     errcode=0;          shift;;
        -q)     qecho=':';          shift;;
        *)      break;;
    esac; done
    # Bad params always produce message and error code
    [[ -z $1 ]] && { echo 1>&2 "$usage"; return 1; }

    [[ -d $1 ]] || { $qecho 1>&2 "$1 is not a directory."; return $errcode; }
    dir="$(command cd "$1"; pwd -P)"
    if [[ :$PATH: =~ :$dir: ]]; then
        $tofront || { $qecho 1>&2 "$dir already in path."; return 0; }
        PATH="${PATH#$dir:}"        # remove if at start
        PATH="${PATH%:$dir}"        # remove if at end
        PATH="${PATH//:$dir:/:}"    # remove if in middle
    fi
    PATH="$dir:$PATH"
}

例外は、この関数は他の方法でPATHに追加されたパスを正規化しないため、パスの非正規エイリアスがPATHにある場合、重複が追加されます。相対パスはPATHに渡されたときに明らかな意味がありますが、既にパス内にある場合、現在の作業ディレクトリが何であるかわからないため、すでにprepathにあるパスを正規化しようとするのは難しい提案です。追加されたとき。

7
cjs

PATH環境変数に新しいパスを追加するには:

export PATH=$PATH:/new-path/

この変更を、開いているすべてのシェルに適用するには、シェルが呼び出されたときにシェルがsourceとなるファイルに変更を追加します。異なるシェルでは、これは次のようになります。

  • Bashシェル:〜/ .bash_profile、〜/ .bashrcまたはprofile
  • Kornシェル:〜/ .kshrcまたは.profile
  • Zシェル:〜/ .zshrcまたは.zprofile

例えば.

# export PATH=$PATH:/root/learning/bin/
# source ~/.bashrc
# echo $PATH

上記の出力では、提供されたパスを確認できます。

7
Amit24x7

私(Mac OS X 10.9.5)の場合、パス名(例:/mypathname)をファイル/etc/pathsに追加するとうまくいきました。

編集する前に、echo $PATHは次を返します:

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

/etc/pathsを編集してシェルを再起動すると、$ PATH変数に/pathnameが追加されます。実際、echo $PATHは次を返します:

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/mypathname

/mypathname$PATH変数に追加されたことが起こりました。

6
faelx

これが私の解決策です:

PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '!x[$0]++' | sed "s/\(.*\).\{1\}/\1/")

末尾を残さない素敵な簡単なワンライナー:

5
AJ.