2009-09-08 7 views

答えて

3

本当にシンプルで素朴な何か:あるものは何でもあなたが探しているものを

echo "$PATH"|grep -q whatever && echo "found it" 

&&の代わりに、$?を変数に入れるか、適切なifステートメントを使用できます。

制限事項は次のとおりです。

  • を上記の「ビン」は、あなたのパスにないという事実にもかかわらず、/、「ビン」に一致すると、それはおそらくそれを見つけるしてみてください(大きい方のパスの部分文字列にマッチしますビンと/ usr/binにされている)
  • 上記自動的〜

やPerlワンライナーを使用してのようなショートカットが拡大しません。

perl -e 'exit(!(grep(m{^/usr/bin$},split(":", $ENV{PATH}))) > 0)' && echo "found it" 

これにはまだシェル拡張が行われないという制限がありますが、部分文字列が一致すると失敗しません。 (上記は "/usr/bin"と一致しています。

+1

JasonWoofの回答のように、行とコロンの先頭と末尾の一致は、部分文字列一致の制限を処理します。大抵の人は、割り当てられたときに展開することを許可する(例えば、 'PATH ="〜/ bin:$ PATH "')ので、チルドの展開は一般的な問題ではありませんが、必要ならば置換で扱うことができます。 – Cascabel

+2

ニース、誰か3.5年後にこれをdownvoted。そして、コメントを残さなかった。ラメ。 –

+0

私はコロンでパターンをラッピングするgrepソリューションを使用しています。 – elias

102

grepを使用すると、残念ですが、REメタキャラクタを含むようなものを探していると困ることがあります。この問題は、bashの組み込みの[[コマンドで完璧に解決することができます。$ PATHの拡大と検索するためのパスの両方の前にコロンを追加すると、サブストリングの一致の問題を解決し

if [[ ":$PATH:" == *":$HOME/bin:"* ]]; then 
    echo "Your path is correctly set" 
else 
    echo "Your path is missing ~/bin, you might want to add it." 
fi 

注意。パスを二重引用符で囲むと、メタキャラクターの問題を回避できます。ここで

+4

'$ HOME/bin'が' $ PATH'の先頭または末尾にある場合、両端にコロンがある可能性は低いです。 –

+8

私はあなたの異議を理解しているかどうか分からない。たとえば、$ PATHが/ usr/bin:/ bin:/ usr/sbin:/ sbin:/ home/fred/binの場合、 "/ usr/bin:/ bin:/ usr/sbin:/ sbin:/ home/fred/bin: "*と一致します:"/home/fred/bin: "* –

+6

あなたはそうです。私は "$ PATH"の周りにコロンの役割を見ることに失敗しました。ごめんなさい。 –

10

grepせずにそれを行う方法は次のとおりです。

if [[ $PATH == ?(*:)$HOME/bin?(:*) ]] 

ここで重要なのは、コロンを作ることであると?()構文を使用して、オプションのワイルドカード。そここの形式のメタ文字を持つ任意の問題になることがありますが、引用符を含める場合、これは、彼らが行くところであるべきではない:これはマッチ演算子(=~)ので、構文を使用して、それを行うための別の方法がある

if [[ "$PATH" == ?(*:)"$HOME/bin"?(:*) ]] 

よりgrep年代のようなものです:

if [[ "$PATH" =~ (^|:)"${HOME}/bin"(:|$) ]] 
+0

'?(:*)'は[拡張グロブ](https://mywiki.wooledge.org/glob#extglob)パターンであり、ほとんどのプラットフォームで明示的に有効にする必要があります( 'shopt -s extglob')。 – tripleee

0

$PATHは、ディレクトリのリストを記述:で区切られた文字列のリストです。ディレクトリは、/で区切られた文字列のリストです。 2つの異なる文字列が同じディレクトリ(たとえば、$HOME~、または/usr/local/bin/usr/local/bin/など)を指している可能性があります。だから私たちは比較/チェックしたいもののルールを修正する必要があります。私は、物理的なディレクトリではなく、文字列全体を比較/確認することをお勧めしますが、重複して後ろにある/を削除してください。

まず、重複を削除し、$PATHから/を末尾:

 
echo $PATH | tr -s/| sed 's/\/:/:/g;s/:/\n/g' 

は今$dはあなたがチェックしたいディレクトリが含まれているとします。前のコマンドをパイプして$d$PATHにチェックします。

 
echo $PATH | tr -s/| sed 's/\/:/:/g;s/:/\n/g' | grep -q "^$d$" || echo "missing $d" 
0

ディレクトリが現在のPATHにリストされている場合、次のシェル機能を使用してレポートを作成しました。この関数はPOSIXと互換性があり、DashやBash(Bash特有の機能に依存することなく)などの互換シェルで動作します。

これには、相対パスを絶対パスに変換する機能が含まれています。これにはreadlinkまたはrealpathユーティリティが使用されますが、付属のディレクトリに..やその他のリンクがパスのコンポーネントとして含まれていない場合、これらのツールは必要ありません。これ以外に、この関数はシェルの外部にプログラムを必要としません。

# Check that the specified directory exists – and is in the PATH. 
is_dir_in_path() 
{ 
    if [ -z "${1:-}" ]; then 
    printf "The path to a directory must be provided as an argument.\n" >&2 
    return 1 
    fi 

    # Check that the specified path is a directory that exists. 
    if ! [ -d "$1" ]; then 
    printf "Error: ‘%s’ is not a directory.\n" "$1" >&2 
    return 1 
    fi 

    # Use absolute path for the directory if a relative path was specified. 
    if command -v readlink >/dev/null ; then 
    dir="$(readlink -f "$1")" 
    elif command -v realpath >/dev/null ; then 
    dir="$(realpath "$1")" 
    else 
    case "$1" in 
     /*) 
     # The path of the provided directory is already absolute. 
     dir="$1" 
     ;; 
     *) 
     # Prepend the path of the current directory. 
     dir="$PWD/$1" 
     ;; 
    esac 
    printf "Warning: neither ‘readlink’ nor ‘realpath’ are available.\n" 
    printf "Ensure that the specified directory does not contain ‘..’ in its path.\n" 
    fi 

    # Check that dir is in the user’s PATH. 
    case ":$PATH:" in 
    *:"$dir":*) 
     printf "‘%s’ is in the PATH.\n" "$dir" 
     return 0 
     ;; 
    *) 
     printf "‘%s’ is not in the PATH.\n" "$dir" 
     return 1 
     ;; 
    esac 
} 

:$PATH:を用いて部分は、所望の経路はPATHの最初または最後のエントリである場合、パターンも一致することを確実にします。この巧妙なトリックはthis answer by Glenn Jackman on Unix & Linuxに基づいています。

0

grepのような外部ユーティリティを使用する必要は絶対にありません。ここで私が使ってきたものがあります。これはBourneシェルのレガシーバージョンでさえも移植可能でなければなりません。

case :$PATH: # notice colons around the value 
    in *:$HOME/bin:*) ;; # do nothing, it's there 
    *) echo "$HOME/bin not in $PATH" >&2;; 
esac 
関連する問題