
Bash에서는 문자열에 포함된 경로가 원격 위치를 가리키는지 확인해야 합니다. 다음은 효과가 없습니다 some code
. 실행되지 않습니다. test
( ) 명령에서 와일드카드가 [
작동하는 방식에 대한 일부 정보가 누락된 것 같지만 무엇인지 모르겠습니다. 매뉴얼 페이지는 나에게 도움이되지 않습니다. 내가 뭘 잘못했나요? 이 문제를 어떻게 해결해야 합니까?
path="user@host:/home/user"
if [ "$path" == ?*"@"?*":"?* ]; then
some code
fi
답변1
명령 [
은 명령이며 다른 명령으로 구문 분석됩니다. 이는 다음을 의미합니다.
[ "$path" == ?*"@"?*":"?* ]
glob으로 처리되므로 ?*"@"?*":"?*
패턴과 일치하는 현재 디렉터리의 파일 목록으로 확장됩니다(현재 디렉터리의 파일 목록으로 확장되는 것과 동일 *.txt
).txt
다음과 같이 쓰더라도:
[ "$path" == '?*@?*:?*' ]
와일드카드를 방지하기 위해 명령의 ==
연산자(비표준 버전)가 패턴 일치 연산자가 아닌 문자열 동등 연산자이기 때문에 이는 작동하지 않습니다.=
[
패턴 일치를 수행하려면 다음을 지원하는 ksh
-style [[ x = pattern ]]
패턴 일치 연산자를 사용할 수 있습니다 .bash
zsh
path="user@host:/home/user"
if [[ "$path" = ?*@?*:* ]]; then
some code
fi
또는 더 나은 방법은 POSIX/Bourne sh
case
구성을 사용하는 것입니다.
case $path in
?*@?*:*) some code
esac
이렇게 하면 설치할 필요도 없으며 bash
시스템 표준을 사용하여 sh
스크립트를 해석할 수 있습니다.
이것도 user@host:/home/user
유효하니 참고하세요현지의path (try ) 를 mkdir -p user@host:/home/user
사용하는 동안 원격 경로로 간주되지 않도록 scp
전달해야 합니다 . ./user@host:/home/user
따라서 테스트를 다음과 같이 구체화할 수 있습니다.
case ${path%%@?*:*} in
(*/* | "$path" | "") echo not a remote path;;
(*) echo remote path;;
esac
이렇게 하면 ./x@y:z
원격 경로로 간주되지 않습니다.
scp
경로가 원격인지 확인하는 것과 동일한 작업을 수행하기에는 아직 충분하지 않습니다 . 보고 있다OpenSSH scp
코드, 왼쪽에 no가 있고 아래에 없는 경로가 :
포함 되어 시작하지 않고 포함된 경우 경로는 원격 경로 입니다. 물론 사용자와 호스트 부분은 비어 있으므로 제대로 작동하지 않을 수 있습니다. :
(중간에 남지 않음) 또는 로컬 경로(내부)./
[...]
[::1]
[...]
@
x:
@:
user@[::1/64]:/x
/
:
[...]
[foo@bar:/path
:
[...]
이를 POSIX case
문과 일치시키는 것은 불가능합니다. 정규식을 일치시키려면 와 같은 랩어라운드 연산자를 지원하는 정규식을 사용하는 것이 약간 더 쉽습니다 perl
. 이를 지원합니다( zsh
PCRE 라이브러리 사용, 자체 구현 사용).ksh93
zsh
ksh93
zsh
:set -o rematchpcre remote='^(?!:)(?:(?!\[)[^/:]*@)?(?:\[(?:(?!]:)[^/])*\]|(?!\[)[^/:]*):' if [[ $path =~ $remote ]]; then some code fi
ksh93
:remote='(?P:^(?!:)(?:(?!\[)[^/:]*@)?(?:\[(?:(?!]:)[^/])*\]|(?!\[)[^/:]*):)' if [[ $path =~ $remote ]]; then some code fi
(단순화될 수 있다면 놀라지 않을 것입니다).