PATH(環境変数)のワイルドカード文字

PATH(環境変数)のワイルドカード文字

私のホームディレクトリにローカルに多くのアプリがインストールされています。グローバルに使用できるように、次のPATH場所に追加しました.bashrc

PATH="$PATH:/home/user/apps/app1/bin"
PATH="$PATH:/home/user/apps/app2/bin"
PATH="$PATH:/home/user/apps/appn/bin"

新しいアイテムをすべて追加する必要がないようにするにはどうすればよいですか?私はこれを試していますが、動作しません。

PATH="$PATH:/home/user/apps/*/bin"

ノート:ループを使用して追加できることを知っていますが、PATH変数が大きすぎるのが心配で、どういうわけかワイルドカードを使用できるかどうかを知りたいです。

答え1

ワイルドカード文字は$PATH拡張されません。 ~によるとバッシュマニュアル、パスは次のとおりです。

コロンで区切られたリスト目次シェルは次のコマンドを探します。

(私の強調)。

反対方向から来て、命令検索・実行部マニュアルの一部は次のとおりです。

名前がシェル関数でも組み込み関数でもなく、スラッシュを含まない場合、Bashは$ PATHのすべての要素を検索します。目次その名前の実行可能ファイルが含まれています。

...(私の強調) - パス要素の特別な処理については言及せず、単にディレクトリでなければならないということです(現状のまま)。

bash変数のサイズ制限が何であるかはまだわかりません。利用可能なメモリのようです。 PATHはエクスポートする必要はありませんが、多くの人がエクスポートした場合は、他の環境変数とパラメータで調整する必要がありますgetconf ARG_MAX(参照:https://unix.stackexchange.com/a/124422/117549)。 bashはハッシュテーブルを使用して以前に見つかったコマンドの場所を(セッションごとに)記憶するため、大きなPATHディレクトリは多くのパフォーマンスオーバーヘッドを引き起こすべきではありません。

個々のアプリケーションディレクトリをPATHに追加することに制限(視覚的または技術的)がある場合は、各アプリケーションのすべてのファイルをリンクできる "symlink"ディレクトリをPATHに追加することをお勧めします。

答え2

追加は、パスが次のディレクトリから実行可能ファイルを検索することを/home/user/apps/*/bin意味します(完全に有効なパス、Unixでは文字1がファイル名またはディレクトリ名に使用されるのを防ぐことはできません)。パスが書き込み内容と一致するときに追加できます。以下を使用するディレクトリ:$PATH/home/user/apps/*/bin*/home/user/apps/*/bin

path+=( /home/user/apps/*/bin(N-/) )

zshでは、変数はcshの配列にバインドされ、$PATHglob修飾子を使用してnullglobだけでなく、ディレクトリタイプファイル(またはディレクトリへのシンボリックリンク)に拡張を制限できます。$path-/N

重複したエントリを削除するために a を実行することもできますtypeset -U pathU一意のエントリの場合)。

where は配列として公開され、fishnullglob と同様の動作は、以下で使用される glob に適用されます。$PATHset

set PATH $PATH /home/user/apps/*/bin

(ファイル形式に限定されない)目次しかし)。

POSIXlyでは、いつでも次のことができます。

for dir in /home/user/apps/*/bin; do
  [ -d "$dir" ] && PATH="${PATH:+$PATH:}$dir"
done

それにもかかわらず、後で/home/user/apps/にさらにディレクトリが追加された場合、そのディレクトリは$PATH.

ksh93では、ルールを使用してこれらの魔法のような効果を得ることができます。

function PATH.get {
  typeset dir
  for dir in ~(N)/home/user/apps/*/bin; do
    [[ :$PATH: = *:"$dir":* || ! -d $dir ]] || PATH=${PATH:+$PATH:}$dir
  done
}

$PATH参照されるたびに計算される値。

zshでは、precmd()フックを使用するか、各プロンプトの前にbash再計算を使用できます$PROMPT_COMMAND


¹またはNULを除くすべての文字、/または問題の文字ではない場合も同様です。

答え3

これにはいくつかのソリューションを使用しました。

1.find動的生成の使用$PATH

これには似ていますが、少し変更されたいくつかの方法を使用しました。次のような構造があるとしましょう。

~/apps
├── foo
│   └── bin
├── bar
│   └── bin
└── blah

私たちはできます...

ㅏ。既存の追加アプリケーション/*/bin/フォルダ$PATH

これは何でも検索しますゴミ箱/ディレクトリ$HOME/アプリケーション/*ロード時にシェルに追加し$PATH、存在しないディレクトリはスキップします。ゴミ箱/サブディレクトリ。

#.bashrc

bins=$(
    find "$HOME/apps/" -maxdepth 2 -type d -name 'bin' \
        | tr '\n' ':' \
        | sed 's/:$//'
)
export PATH="$bins:$PATH"

生産:

/home/user/apps/foo/bin:/home/user/apps/bar/bin:...

b.追加特定のディレクトリ /*/bin/到着$PATH

...各フォルダに関係なくディレクトリ/実際に一つあります。ゴミ箱/内部のサブディレクトリ。これは上記のディレクトリ構造についてアプリケーション/ライト/空追加されます$PATH- 存在しなくても!

これは、ディレクトリの1つが存在しない場合に便利です。一つあるゴミ箱/$PATHサブディレクトリにはありますが、将来の可能性が高いため、シェルを作成した後にシェルに追加するためにシェルを再ロードする必要はありません。

#.bashrc

bins=$(
    find "$HOME/apps/" -maxdepth 1 -type d \
        | sed 's_$_/bin_' \
        | tr '\n' ':' \
        | sed 's/:$//'
)
export PATH="$bins:$PATH"

生産:

/home/user/apps/foo/bin:/home/user/apps/bar/bin:/home/user/apps/blah/bin:...

findコマンドは存在しないディレクトリをしばらく見つけることを試みるので、これはパフォーマンスにとんでもなく無視できる影響を与える可能性があります。感じる存在しないディレクトリをmyに追加することはお勧めできませんが、便宜上、$PATHこれが私が好むオプションです。

2.stow実行ファイルの生成に使用されるシンボリックリンク

stowまさにこの目的のために作られました。私は現在、この設定を使用してすべてのドットファイルをgitリポジトリに保存し、ホームディレクトリにコピーしています。 :)

次のディレクトリ構造がある場合:

.
├── bar
│   └── bin
│       ├── bar-executable-1
│       └── bar-executable-2
├── bin
└── foo
    └── bin
        ├── foo-executable-1
        └── foo-executable-2

あなたはすべてのファイルが欲しいバー/空/*そして金持ち/空/*次に接続ゴミ箱/、以下を実行できます。

cd somedir
stow -v --restow --target bin/ --dir bar/ bin
stow -v --restow --target bin/ --dir foo/ bin

--restow注:新しいシンボリックリンクを再作成する前に古いシンボリックリンクをすべて削除するため、pruneを使用しました。

これで以下が生成されます。

somedir
├── bar
│   └── bin
│       ├── bar-executable-1
│       └── bar-executable-2
├── bin
│   ├── bar-executable-1 -> ../bar/bin/bar-executable-1
│   ├── bar-executable-2 -> ../bar/bin/bar-executable-2
│   ├── foo-executable-1 -> ../foo/bin/foo-executable-1
│   └── foo-executable-2 -> ../foo/bin/foo-executable-2
└── foo
    └── bin
        ├── foo-executable-1
        └── foo-executable-2

その後、単に追加するだけです。特定のディレクトリ/bin/あなたのためPATH

stow使いやすく

もし

  1. 各ディレクトリ内の一意のディレクトリ申請Nディレクトリは単一です。ゴミ箱/目次そして
  2. コンパイルされたコンテンツを移動できます。ゴミ箱/ディレクトリ外のディレクトリアプリケーション/目次

その後、少し簡単なコマンドを使用できますstow

/home/user
├── Desktop
├── Documents
├── Pictures
├── Videos
├── apps
│   ├── bar
│   │   └── bin
│   │       ├── bar-executable-1
│   │       └── bar-executable-2
│   └── foo
│       └── bin
│           ├── foo-executable-1
│           └── foo-executable-2
└── bin
cd
stow -v --restow --target ./ --dir apps/ foo bar

これは基本的に言う「apps」フォルダで「foo」と「bar」という「パッケージ」を探し、シンボリックリンクを使用して両方のパッケージの内容全体を現在のディレクトリにコピーします。。だから全部持っていればアプリケーション/foo/そしてアプリ/バー/シングルだゴミ箱/フォルダを選択すると、次のファイルが作成されます。ゴミ箱/すべてのファイルへのリンクを含む現在のディレクトリのフォルダアプリケーション/foo/bin/そしてアプリ/バー/空/

しかし、他のファイル/フォルダが多い場合アプリケーション/foo/そしてアプリ/バー/ただ一つを除いてゴミ箱/ディレクトリを削除すると、ホームフォルダにもこのすべてのコンテンツが再作成されます。これは望ましくない可能性があるため、最初の例に従う必要がありますstow

https://www.gnu.org/software/stow/manual/html_node/Installing-Packages.html

関連情報