예를 들어 다음 명령이 작동하지 않습니다.
if [[-e xyz]]; then echo File exists;fi
ksh는 다음 오류를 제공합니다
[[-e: command not found
"[[-"가 모호하기 때문입니까?
예를 들어 다음 명령이 작동하지 않습니다.
if [[-e xyz]]; then echo File exists;fi
ksh는 다음 오류를 제공합니다
[[-e: command not found
"[[-"가 모호하기 때문입니까?
답변:
같은 설명서가 나타나기 때문에 가장 간단한 설명은 것 [[ expression ]]사이의 공간이 있어야한다 그래서 [[와 expression닫는 ]]. 물론 우리는 더 깊이 살펴볼 수 있습니다. 쉘은 다소 복잡한 문법을 가지고 있으며 "단어 분리"라는 개념에 크게 의존합니다. 특히 ksh (1) 수동 상태는 다음과 같습니다.
쉘은 입력을 단어로 분리하여 입력 구문 분석을 시작합니다. 일련의 문자 인 단어는 따옴표없는 공백 문자 (공백, 탭 및 줄 바꿈) 또는 메타 문자 (<,>, |,;, &, (및))로 구분됩니다. 구분 단어 외에도 공백과 탭은 무시되고 개행은 일반적으로 명령을 구분합니다.
따라서 매뉴얼에 명시된 바와 같이 일련의 문자 [[-e는 쉘 단어로 간주됩니다. ksh내장 및 특수 연산자 ( for또는 같은 while) 목록에서 이러한 명령을 찾은 다음 외부 명령을 찾고 voilà를 찾을 수 없으므로 명령을 찾을 수 없다는 오류 메시지가 표시됩니다.
이 경우 [[특수 메타 문자도 아닙니다. 만약 그렇다면, 그 -e부분은 그 자체에 [[-e대한 주장이 아니라 쉘 단어로 간주 될 [[것입니다. 그러나 [[복합 명령으로 설명되며 설명서에는 다음과 같이 나와 있습니다.
복합 명령은 다음 예약어를 사용하여 작성됩니다.이 단어는 따옴표가없고 명령의 첫 번째 단어로 사용되는 경우에만 인식됩니다 (즉, 매개 변수 지정 또는 재 지정이 앞에 올 수 없음).
따라서 [[복합 명령으로 인식 되려면 명령 또는 명령 목록의 첫 번째 단어 여야합니다. "단어"의 이전 정의에 따라 공백, 탭 또는 줄 바꿈으로 구분해야 함을 의미합니다. 단어 / 인수.
당신은에 요청했습니다 의견 : "할 수없는 이유는 파서 정지, 발견 즉시로"[[ "패턴 및 취급이 조건부 명령의 시작으로?" 짧은 대답은 아마도 1) [구문이 원래 외부 명령 이기 때문에 구문의 영향이고 POSIX 표준 준수의 경우 오늘날에도 외부 명령으로 존재하기 때문이며 2) 쉘 파서가 그렇게 작성 되었기 때문일 것입니다. 쉘 파서는 공백이 아닌 다른 특수 문자를 인식 echo $((2+2))하고 (echo foobar)완벽하게 작동합니다. 어쩌면 미래에 ksh개발이 재개되거나 포크 또는 클론이있는 것처럼 보일 때 (예 : mksh또는 pdksh) 누군가가 공백없는 구문을 구현할 것입니다 [[-e.
[[에서 "예약어"( Shell Command Language의 2.9 절 참조 ). POSIX 정의에 따라 예약어는 공백으로 구분해야합니다. 반대로 (2.9 절의 표준 상태는 "표현에는 토큰 <blank>이 필요하지 않은 곳 (토큰 중 하나가 연산자 인 경우)에 토큰 사이의 간격이 포함되어 있음"이 나와 있습니다. 관련 설명을 참조하십시오 : POSIX 쉘 문법 : 왜 중괄호 그룹은 최초의 우주 그러나 서브 쉘합니까를 필요가 없다?char키워드입니다하지만 당신은 여전히 쓸 수 없습니다 charsomeletter = 'A';및보고 후 정지 파서를 기대합니다 char.
i--<=++j있으며 컴파일러는로 구문 분석하는 데 아무런 문제가 없습니다 i -- <= ++ j.
_). KSH을 갖는다 (int로서 연산자 및 (echo hello)로 파싱한다 ( echo hello ). 그것은했다 if, {, [[, 등의 키워드 와 ifx, {x그리고 [[x각각의 토큰입니다 - 방법과 같은 charsomeletter하나의 C 토큰입니다. 대조적으로, 인용되지 않은 (xksh는 i--C에서 두 개의 토큰이 어떻게되는지와 같이 두 개의 토큰입니다. 개념적 으로 연산자라는 의미 는 Bourne 스타일 쉘 (ksh와 같은)과 C가 다릅니다. 그러나 Peter A. Schneider는 실제 어휘 유사성.
주목해야 할 [것은 명령이며 [[bash 및 ksh 의 쉘 키워드 는를 기반으로 한다는 것 입니다 [.
[[와 유사한 방식으로 사용됩니다 [. 때로는 당신도 대체 할 수 [ ]와 [[ ]]행동의 변화없이. 을 사용 [하면 명령과 마찬가지로 명령과 인수 사이에 공백이 필요합니다. 동일하게 적용됩니다 [[.
우리는 단지 가지고 있었다 /usr/bin/[. 이제 대부분의 셸은 [효율성을 위해 내장되었지만 구문은 동일합니다. 제공 쉘에서 [[A와, 그 기능을 더욱 다양한 대안을 [.
[bash에 대한 설명은 다음과 같습니다 .
$ help [
[: [ arg... ]
Evaluate conditional expression.
This is a synonym for the "test" builtin, but the last argument must
be a literal `]', to match the opening `['.
따라서 ( 마지막 으로 논쟁 을 기대하는 것을 제외하고 [)와 같습니다 . 그것에 대해 더 자세히 알려줄 것입니다. 이것을와 비교할 수 있습니다 .test]help testhelp [[
외부 명령 [( man \[)에 대한 매뉴얼 페이지도 있습니다 .
의 경우
if [[-e
[없습니다 [[. 전체 단어 [[-e입니다.if [[-e그것을 참 / 거짓에 대한 테스트합니다. 그래서 명령 않는 [[-e존재를? "[[-"가 모호하기 때문입니까?
예. 아님 [[-e쉘이 이해하는 것은 아무것도 없으므로 쉘이 자체 명령이라고 가정합니다. ;-)
[[-e는 잠재적으로 유효한 (이상해 보이는 경우) 명령 이름입니다.
공간은 델리 미네 이터 이며 필수입니다. 당신이 볼 수 있듯이 shellcheck:
$ shellcheck gmail-browse-msgs-algorithm.sh
In gmail-browse-msgs-algorithm.sh line 847:
[[$Today != "${DaysArr[ i + DAY_DELETED_ON_NDX ]}" ]] && continue
^-- SC1035: You need a space after the [[ and before the ]].
(ksh와 bash는 모두 [[공백없이 작동하며 작동하지 않습니다. Shellcheck는 해당 버기 라인을 포함하는 유사한 ksh 및 bash 스크립트로 출력을 정확하게 제공합니다.)
델리 미네 이터가 필요한 이유는 토큰 및 사전과 관련이 있습니다.
ksh쉘에 대해 물었습니다 . Bash는 [[운영자 ksh에게이 질문에서 운영자를 빌려 주지만 그들의 행동은 동일하지만 행동과 내부 ksh와는 약간의 차이가 있기 때문에 가정에주의를 기울일 것 bash입니다. 쉘 검사가 bash 스크립트에서 작동하기 때문에 ksh 스크립트에 적합한 도구 일 필요는 없습니다. 다른 조개에 접근하면서 그냥 뭔가 마음에 유지
[[내장 규칙 을 강조하기 위해 shellcheck를 사용하여 기회 주의적이었습니다 . 나는 그것이 오류를 발견 할 수 ksh있는 쉘이라는 것을 결코 추론하지 않았다 shellcheck. 나는 다른 사람들 이 서로 다른 두 가지 통역사를 이해 ksh하고 이해하기를 바란다 bash. 언급 해 주셔서 감사합니다. 또한 외부 명령 인 [[내장 bash 도 주목할 가치가 [있습니다.
[는 bash에 내장되어 있습니다 :) manpages.ubuntu.com/manpages/bionic/man7/bash-builtins.7.html 그러나 당신은 멀지 않습니다- [또는 test외부 명령이 필요합니다. 원래 Bourne 쉘 시절에는 [실제로는 외부 명령 이었지만 /usr/bin/[POSIX는 외부 명령 이어야 하기 때문에 오늘날에도 여전히 존재합니다. pubs.opengroup.org/onlinepubs/009695399/utilities/test.html POSIX에 필요한 것은 거의 없습니다 내장 된 pubs.opengroup.org/onlinepubs/009695399/idx/sbi.html 내장 [은 효율성을위한 것입니다
ksh; hashbang 또는을 사용하십시오 -s ksh. BTW, KSH 및 배쉬있다 [["내장"그러나 A의 키워드 는 달리, [A는, 쉘 내장 . (ksh : whence -v [ [[; bash type [ [[:) 내장 명령과 외부 명령은 구문 적으로 비슷합니다. 한 가지 [[다른 점은 인수에서 일부 확장 [을 [[억제 한다는 것 입니다. 인수로는 내장 기능이 아니기 때문에 내장 기능으로 {는 불가능했습니다. 이 이유가 될 수있다 {x(또는 [[x) 홀수 하나의 토큰 Feel로 서비스를 제공합니다. 내장과 키워드는 어휘 적이지만 구문 적으로 비슷 하지 않다고 말하는 것이 옳습니다 . @SergiyKolodyazhnyy
[[-e쉘 확장에 참여할 수 있기 때문에
echo [[-e]*
편지와 함께 시작하는 모든 파일을 나열하기 위해 [하고 e있는 경우 포괄적으로)를, 그것은 완전한 엉망이 될 것입니다 [및 ]특수 문자는 일반 공백 지배 단어 분할에 참여하지 않았다.
[[A는 키워드 - 아마 쉘의 구문 분석 트리 키워드는 공백으로 묘사되어야 함을 요구한다