왜 `test.sh & | test.sh`가 틀렸어

왜 `test.sh & | test.sh`가 틀렸어

test.sh아래와 같은 이름의 bash 스크립트가 있습니다 .

#!/bin/bash

while :
do
    echo xxx
    sleep 1
done

./test.sh & | ./test.sh왜 나에게 오류가 발생하는지 모르겠습니다 : -bash: syntax error near unexpected token |', while ./test.sh | ./test.sh./test.sh | ./test.sh &work.

답변1

그것은 단순히 쉘에서 허용되지 않습니다문법:

%start  complete_command
%%
complete_command : list separator
                 | list
                 ;
list             : list separator_op and_or
                 |                   and_or
                 ;
...

pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command
                 ;
...
separator_op     : '&'
                 | ';'
                 ;

목록을 어떻게 종료하거나 종료할 수 있는지 확인하세요 &. ;목록은 다른 프로덕션의 일부가 될 수 없는 Complete_command의 일부일 뿐입니다.

그것은 단지 문법상의 문제일 뿐입니다. 와 { foo & }의미상 유사한 것처럼 foo &(괄호와 달리 중괄호는 명령을 그룹화하는 데만 사용되며 자체적으로 하위 쉘이나 어떤 종류의 범위도 생성하지 않습니다) 후자가 허용되는 경우 { foo & } | bar와 의미상 유사한 것으로 간주할 수 있습니다. foo & | bar문법으로.

따라서 귀하의 예에 대한 해결 방법은 다음과 같습니다.

{ ./test.sh & } | ./test.sh

&대화 형 셸에서 실행하면~ 아니다만들기백그라운드 작업, 그러나 파이프라인의 오른쪽은 항상 서브셸에서 실행되고 서브셸의 명령은 작업 제어가 비활성화된 상태에서 실행되므로 명령을 비동기적으로 실행하면 됩니다.

이는 다음과 유사합니다.

(sleep 3600 &)

&서브셸의 비동기 목록( 로 종료되는 명령 )은 stdin이 에서 리디렉션되고 /dev/null해당 SIGINTSIGQUIT신호는 무시된 상태로 실행됩니다. 백그라운드에서 계속 실행되지만 일반 작업에서처럼 , 기타 등을 사용하여 fg포 그라운드로 가져올 수는 없습니다. disown또한 중지되거나 종료될 때 알림을 받지 않습니다.

스크립트에서는 작업 제어가 비활성화된 상태로 스크립트가 실행되므로 이는 전혀 차이가 없습니다.

그러나 배경의 출력을 파이프하려는 경우직업전경으로직업인터렉티브쉘에서 제가 생각할 수 있는 유일한 이식 가능한 솔루션은 명명된 파이프를 사용하는 것입니다.

$ mkfifo fifo
$ command | filter1 > fifo &  # this is the background job
$ < fifo sed 10q | filter2    # this is the foreground job

관련 정보