이 bash 명령을 실행할 때 순서가 중요한 이유는 무엇입니까?


10

bash 쉘과 관련하여 이해할 수없는 일부 불일치가있는 것 같습니다.

내가 실행하면 :

ls;date;time

세 개의 쿼리 결과가 순서대로 표시됩니다.

그러나 날짜 및 시간 위치를 바꾸면 오류 메시지가 나타납니다.

그래서 내가 실행하면 :

ls;time;date

오류 메시지는 다음과 같습니다 bash: syntax error near unexpected token 'date'..

누군가 이것을 설명 할 수 있습니까?


문제는 time;datevs에 date;time있습니다. 이것은 파이프 라인 입력 bashtime출력으로 생성 된 마지막 문자 에 문제가있는 것 같습니다 . 다른 터미널 에뮬레이터에서 테스트 된 결과는 다음과 같습니다.-[Bash] $ date; time # [OK] $ time; date # [ NotOK ] bash : 예상치 않은 토큰 근처의 구문 오류`date '$ time # 유일한 오류는 어떤 날짜의 결과. -[Csh] $ 날짜; 시간 # [OK] $ 시간; 날짜 # [OK]-[Tcsh] $ 날짜; 시간 # [OK] $ 시간; 날짜 # [OK]-[Ksh] $ 날짜; 시간 # [ OK] $ time; date # [OK]
Mostafa Shahverdy

오류 메시지에 대한 설명으로 답변을 업데이트했습니다. 이것이 당신이 찾고있는 답인지 확인하십시오.
zwets

답변:


10

time파이프 라인 의 명령은 /usr/bin/time바이너리가 아니라 bash time내장입니다. man time와 비교하십시오 help time. 당신이 보는 오류는 bash가 time인수 를 구문 분석하지 못하는 것 입니다. 존재하거나 줄 바꿈이어야합니다. 첫 번째 예에서는 개행이지만 두 번째 예에는 없습니다.

반면에, 달리기를 원한다면

ls;date;'time'

또는

ls;'time';date

여기서 따옴표 'time'는 예약어로서의 상태를 취소 한 다음 bash는 행을 구문 분석하는 데 아무런 문제가 없습니다. 이제 목록에서 세 개의 명령을 구문 분석하여 순서대로 실행 /usr/bin/time하며 두 경우 모두 사용 오류를보고합니다.

추가

time ; date오류가 발생 하지만 time ; ; date그렇지 않은 것으로 관찰되었습니다 . 가능한 설명은 time ;bash에 의해 동등한 것으로 해석 된다는 것 입니다 time <newline>. time ; ; date그런 다음 식이 time ;및 의 목록으로 구문 분석됩니다 date.

이것은 두 번째가 싱글 톤리스트로 파싱되고 그 뒤에 리스트 뒤에 허용되는 세미콜론 (옵션) 이라는 해석 time ;과 일치하며 또한 time ; ;합법적 이라는 관찰과 일치 time ;합니다.

따라서 왜 time ; date오류 bash: syntax error near unexpected token 'date'가 발생 하는지 설명하는 또 다른 방법은 time에서 분리하는 세미콜론 을 소비하는 것입니다 date. timebash 예약어 이기 때문에 그렇게 할 수 있습니다 .


좋은 설명 감사합니다! 그러나이 동작은 다시 버그처럼 보입니다 time. NULL 명령을 허용하고 세미콜론은 목록을 구분 time해야 하므로 IMO 명령은 세미콜론을 "소비"해서는 안됩니다. 인수를 취할 수있는 다른 내장 명령은 이러한 종류의 동작을 나타내지 않습니다.
주선

@arrange 복잡한 문제는 시간이 널 명령 (모든 것을 명확하게 했음)을 허용하지 않으며 명령 대신 개행 만 허용한다는 것 입니다. 따라서 time;date어떤 해석에서도 실제로 문법적으로 잘못되었습니다. 그러나 time ;time ; ;다음 불법 것이다. 여부를 논의 할 수있다 time'의 행동이 버그 단지 (가 문서화되지 않은 입니다 내부적으로 일관성이)하지만, 버그 리포트는 확실히 장소에있을 것입니다. 기꺼이 제출 하시겠습니까?
zwets

글쎄, 나는 소스 (bash4.2 : parse.y : lines 1205-1221)를 보았고 거기에 time by itself can time a null command그렇게되어있다 $$ = make_simple_command (x, (COMMAND *)NULL);. 버그를 신고에 관해서는 나는 8) 확실하지 않다
준비

이 문제는 bash 관련 문제입니다. 이렇게 time ; date에서 일을 ksh93하고 mksh도에 불구하고, 오류없이 ksh 거기에 time키워드.
Sergiy Kolodyazhnyy 2012

2

Bash는 time명령 줄을 구문 분석 할 때 내장을 특수한 경우로 취급합니다 .

bash 맨 페이지에서 읽을 수 있듯이 입력 한 줄은 먼저 목록으로 나뉩니다.

pipeline ; pipeline

파이프 라인은 다음과 같습니다.

[time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]

또는 우리의 경우 간단히 :

time command

즉, 시간이 있으면 명령도 있어야합니다 .

[ time줄 바꿈이 뒤따 를 수있는 특별한 경우가 있지만 여기에는 적용되지 않습니다.]

따라서 우리의 경우에는 다음이 있습니다.

time;date

두 개의 파이프 라인으로 분할됩니다.

1. time
2. date

파이프 라인 1은 time명령 이 없기 때문에 제대로 구성되지 않았습니다 . 따라서 오류가 발생했습니다.

명령 행 time은 여기에서도 작동하지 않습니다.

$ /usr/bin/time;date
Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]

bash는 이것을 예상대로 2 개의 파이프 라인으로 구문 분석합니다.

1. /usr/bin/time
2. date

그리고 /usr/bin/time논쟁없이 달리기를 거부합니다. 이것은 /usr/bin/timebash 의 오류가 아닌 오류입니다.

백틱이 작동하는 이유는 백틱이 time파이프 라인 내에서 특수 요소로 해석되지 않기 때문입니다.

즉, 백틱으로 :

`time`;date

두 개의 파이프 라인으로 구문 분석됩니다.

1. `time`
2. date

우리의 경우 파이프 라인은 다음과 같습니다.

[time] command

문제는 처음 time에는 명령이 없었기 때문에 허용되지 않았다는 것입니다. 그러나 이제 우리는 단순히 다음 명령을 갖습니다.

`time`

(가) 이전하지 않고 time는 이후 그 평균 백 틱 time이 아닌 이전 단어로, 명령으로 해석됩니다.

따라서 bash는 내장 time인수를 인수없이 실행합니다 . 출력이 없으며 오류가 없습니다.

참고 :

`time`

실제로 내장 의 결과 를 실행합니다 time. 즉, time내장 된 stdout에서 생성하는 모든 것을 실행합니다 . 그러나 time자체적으로 stdout에 아무것도 쓰지 않기 때문에 작동하는 것처럼 보입니다.

마지막으로, 이것이 작동한다는 것이 주목되었습니다.

time ; ; date

슬프게 설명 할 수없는 :)


나는 당신의 설명이 더 낫다고 생각하지만 여전히 나에게는 이상하게 보입니다. ;dategives bash: syntax error near unexpected token ;하지만 but time ;dategives bash: syntax error near unexpected token date이므로 bash는 내장 된 시간 이후의 명령을 "; date"로 처리하지 않는 것 같습니다. 흥미롭게도 time ; ; date작동합니다.
정렬

예, @arrange에게 감사합니다. 정말 이상합니다. 답변을 약간 업데이트하겠습니다.
cdmackay

좋아, @arrange, 다시 작성했다. 그래도 마지막은 설명 할 수 없어 ... 한숨
cdmackay

@cdmackay 당신은 백틱과 따옴표를 섞고 있습니다. 에 의해 인용 'time' 이 예약 된 단어로 그 의미를 잃는다. 백틱 하면 출력이 명령에 연결되는 서브 쉘에서 실행됩니다. 이것은 토론과 관련이 없습니다. 사실, 당신의 예는 `time\';date청구의 반대를 증명 :이 해야 하기 때문에 당신의 추론에 의해 오류를 줄 /usr/bin/time인수가 필요합니다. 그것이 수행되지 않는 이유는 그것이 실행되는 서브 쉘에서 time다시 예약어이기 때문입니다 .
zwets

@arrange 둘 다 구문 오류이며 둘 다 같은 곳 근처에 있는 것으로보고 있으므로 불일치가 보이지 않습니다. 구문 오류 토지에 들어가면 파서가 그 길을 알 것으로 기대할 수 없습니다. 파서의 구문을 필요로한다면, 유효한 구문뿐만 아니라 모든 가능한 불법 구문구문 도 알아야합니다 . 이는 정의상 불가능합니다.
zwets
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.