/bin/bash
で、ユーザが$ PATH変数に特定のディレクトリを持っていれば、どのように検出されますか?例えばユーザのパスに特定のディレクトリがあるかどうかを検出します
if [ -p "$HOME/bin" ]; then
echo "Your path is missing ~/bin, you might want to add it."
else
echo "Your path is correctly set"
fi
/bin/bash
で、ユーザが$ PATH変数に特定のディレクトリを持っていれば、どのように検出されますか?例えばユーザのパスに特定のディレクトリがあるかどうかを検出します
if [ -p "$HOME/bin" ]; then
echo "Your path is missing ~/bin, you might want to add it."
else
echo "Your path is correctly set"
fi
本当にシンプルで素朴な何か:あるものは何でもあなたが探しているものを
echo "$PATH"|grep -q whatever && echo "found it"
。 &&
の代わりに、$?
を変数に入れるか、適切なif
ステートメントを使用できます。
制限事項は次のとおりです。
やPerlワンライナーを使用してのようなショートカットが拡大しません。
perl -e 'exit(!(grep(m{^/usr/bin$},split(":", $ENV{PATH}))) > 0)' && echo "found it"
これにはまだシェル拡張が行われないという制限がありますが、部分文字列が一致すると失敗しません。 (上記は "/usr/bin
"と一致しています。
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
注意。パスを二重引用符で囲むと、メタキャラクターの問題を回避できます。ここで
'$ HOME/bin'が' $ PATH'の先頭または末尾にある場合、両端にコロンがある可能性は低いです。 –
私はあなたの異議を理解しているかどうか分からない。たとえば、$ PATHが/ usr/bin:/ bin:/ usr/sbin:/ sbin:/ home/fred/binの場合、 "/ usr/bin:/ bin:/ usr/sbin:/ sbin:/ home/fred/bin: "*と一致します:"/home/fred/bin: "* –
あなたはそうです。私は "$ PATH"の周りにコロンの役割を見ることに失敗しました。ごめんなさい。 –
はgrep
せずにそれを行う方法は次のとおりです。
if [[ $PATH == ?(*:)$HOME/bin?(:*) ]]
ここで重要なのは、コロンを作ることであると?()
構文を使用して、オプションのワイルドカード。そここの形式のメタ文字を持つ任意の問題になることがありますが、引用符を含める場合、これは、彼らが行くところであるべきではない:これはマッチ演算子(=~
)ので、構文を使用して、それを行うための別の方法がある
if [[ "$PATH" == ?(*:)"$HOME/bin"?(:*) ]]
よりgrep
年代のようなものです:
if [[ "$PATH" =~ (^|:)"${HOME}/bin"(:|$) ]]
'?(:*)'は[拡張グロブ](https://mywiki.wooledge.org/glob#extglob)パターンであり、ほとんどのプラットフォームで明示的に有効にする必要があります( 'shopt -s extglob')。 – tripleee
$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"
ディレクトリが現在の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に基づいています。
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
JasonWoofの回答のように、行とコロンの先頭と末尾の一致は、部分文字列一致の制限を処理します。大抵の人は、割り当てられたときに展開することを許可する(例えば、 'PATH ="〜/ bin:$ PATH "')ので、チルドの展開は一般的な問題ではありませんが、必要ならば置換で扱うことができます。 – Cascabel
ニース、誰か3.5年後にこれをdownvoted。そして、コメントを残さなかった。ラメ。 –
私はコロンでパターンをラッピングするgrepソリューションを使用しています。 – elias