`test.sh & | test.sh` 오류가 발생하는 이유는 무엇입니까?

`test.sh & | test.sh` 오류가 발생하는 이유는 무엇입니까?

다음과 같은 이름의 bash 스크립트가 있습니다 test.sh.

#!/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 &작동합니다.

답변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되고 SIGINT합계 SIGQUIT신호가 무시됩니다. 백그라운드에서 계속 실행되지만 일반 jobs 에서처럼 , they 등을 사용하여 fg전경으로 가져올 수는 없습니다. disown또한 서비스가 중지되거나 종료될 때 알림을 받지 않습니다.

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

하지만 파이프를 통해 배경을 출력하려면일하다프런트로 가세요일하다안에인터렉티브쉘에서 제가 생각할 수 있는 유일한 휴대용 솔루션은 명명된 파이프를 사용하는 것입니다.

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

관련 정보