원격 호스트의 위치 경로에 대한 와일드카드

원격 호스트의 위치 경로에 대한 와일드카드

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 ]]패턴 일치 연산자를 사용할 수 있습니다 .bashzsh

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. 이를 지원합니다( zshPCRE 라이브러리 사용, 자체 구현 사용).ksh93zshksh93

  • zsh:

    set -o rematchpcre
    remote='^(?!:)(?:(?!\[)[^/:]*@)?(?:\[(?:(?!]:)[^/])*\]|(?!\[)[^/:]*):'
    if [[ $path =~ $remote ]]; then
      some code
    fi
    
  • ksh93:

    remote='(?P:^(?!:)(?:(?!\[)[^/:]*@)?(?:\[(?:(?!]:)[^/])*\]|(?!\[)[^/:]*):)'
    if [[ $path =~ $remote ]]; then
      some code
    fi
    

(단순화될 수 있다면 놀라지 않을 것입니다).

관련 정보