예를 들어 다음 명령이 작동하지 않습니다.
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 토큰입니다. 대조적으로, 인용되지 않은 (x
ksh는 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 test
help [[
외부 명령 [
( 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는 키워드 - 아마 쉘의 구문 분석 트리 키워드는 공백으로 묘사되어야 함을 요구한다