/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 -e 'exit(!(grep(m{^/usr/bin$},split(":", $ENV{PATH}))) > 0)' && echo "found it"
을
여전히 셸 확장을 수행하지 않지만 하위 문자열이 일치해도 실패하지 않는다는 제한이 있습니다. (위의 내용은 명확하지 않은 경우 "/usr/bin
"과 일치 함).
grep
을 사용하면 잔인하며 RE 메타 문자가 포함 된 것을 검색하는 경우 문제가 발생할 수 있습니다. 이 문제는 배쉬의 내장 [[
명령을 완벽하게 해결 될 수있다 : $ 경로의 확장 및 검색 할 수있는 경로를 모두 전에 콜론을 추가하면 문자열 일치 문제를 해결
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"(:|$) ]]
'? (: *)'는 [확장 glob] (https://mywiki.wooledge.org/glob#extglob) 패턴이며 대부분의 플랫폼에서 별도로 명시 적으로 활성화해야합니다 ('shopt -s extglob'). – tripleee
$PATH
는 디렉토리리스트를 설명 :
의해 분리 문자열리스트이다. 디렉토리는 /
으로 구분 된 문자열 목록입니다. 두 개의 다른 문자열은 같은 디렉토리 (예 : $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