「PATH」変数にワイルドカード文字を追加できますか?

「PATH」変数にワイルドカード文字を追加できますか?

想像する:

親フォルダには、実行可能ファイルやソースプログラムを含む多くのサブフォルダ(数百など)が含まれています。たとえば、親フォルダには、、...など、/opt/app1/bin/多くのサブフォルダが含まれています。変数にすべてを追加すると、1行あたりの文字数制限を超えるか、非常に扱いにくい場合があります!mod1mod2modnPATH

dogbaneユーザーの答えを見るとわかります。ディレクトリ内のすべてのディレクトリを選択するワイルドカードとは何ですか?それ:

  1. ワイルドカードを*/使用してディレクトリを一致させることができます。
  2. ワイルドカード文字を**/*/使用してディレクトリとサブディレクトリを一致させることができます。

変数/opt/app1/bin/**/*/に項目を追加すると、サブフォルダから実行可能ファイルが検索されますか?PATHこれは合併症を引き起こしますか?

答え1

シェルには1行に文字制限はありません。あなたが考えることができるのは、コマンドラインの長さと現在の環境変数セットとその値が大きすぎると外部コマンドを実行できないことです。これは、外部コマンドを実行する場合(つまり、シェルが他の実行可能ファイルをexec()起動するためにCライブラリの機能の1つを使用する必要がある場合)にのみ適用される制限です。変数値を設定しても外部コマンドは実行されません。

PATH変数を使用すると、シェルは変数に対してファイル名拡張を実行しないため、変数にファイル名のグローブパターンをそのまま追加することはできません。

追加できます拡張PATH個々の項目が区切られていることを確認するには、ファイル名globbingパターンを変数に追加します:。値のディレクトリパス区切り文字PATHはコロンであるため、このパス名リストに含まれる名前にはコロンを含めることはできません。

シェルでは、bashパターンに/opt/app1/bin/**/*/次のものを使用できます。

shopt -s globstar failglob

IFS=:$IFS

set -- /opt/app1/bin/**/*/
PATH=$PATH:"$*"

IFS=${IFS#?}

これは、位置引数のリストをワイルドカードパターンが拡張される拡張パス名のリストに設定します(必要に応じて配列を使用できますが、より多くの入力が必要です)。これによりリストが展開され、"$*"変数の値の末尾に追加されます。PATH

"$*"セットの最初の文字をIFSコロンで展開すると、リストの要素はコロンで区切られます。

IFSその後、元の値を復元します。

failglobパターンが一致しない場合は、スクリプトを終了するために使用します。PATHパターンと一致せずに持続するには、次のものを使用できます。

shopt -s globstar nullglob

IFS=:$IFS

set -- /opt/app1/bin/**/*/
PATH=$PATH${1+:"$*"}

IFS=${IFS#?}

これは、定義されていない場合、つまりパターンが何も一致しない場合、変更を回避するためにnullglob代わりに使用されます。failglobPATH$1

答え2

はい、追加してください拡張PATH変数に追加すると/opt/app1/bin/**/*/(シェルで拡張を引き起こす適切なオプションを設定したと仮定して**)、そのディレクトリから実行可能ファイルを検索します。

ここの末尾は*/関係ありません。拡張子を使用すると、/opt/app1/bin/**/以下のすべてのサブディレクトリのリストを取得できます/opt/app1/bin

長さ制限は見えません。$ PATHのPOSIX仕様、基本定義 - 環境変数 - その他の環境変数に記載されています。

私が想像できる合併症は次のとおりです。

  • 同じコマンドのブロック - 2つの同じ実行可能ファイル名が与えられ、1つが見つかり、PATHに挿入されます。最初デフォルトでは呼び出される名前になります。

  • 無効なコマンドが見つからないと、追加の遅延が発生します(シェルがコマンドのすべてのディレクトリを検索するため)。

関連情報