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
해당 SIGINT
및 SIGQUIT
신호는 무시된 상태로 실행됩니다. 백그라운드에서 계속 실행되지만 일반 작업에서처럼 , 기타 등을 사용하여 fg
포 그라운드로 가져올 수는 없습니다. disown
또한 중지되거나 종료될 때 알림을 받지 않습니다.
스크립트에서는 작업 제어가 비활성화된 상태로 스크립트가 실행되므로 이는 전혀 차이가 없습니다.
그러나 배경의 출력을 파이프하려는 경우직업전경으로직업에인터렉티브쉘에서 제가 생각할 수 있는 유일한 이식 가능한 솔루션은 명명된 파이프를 사용하는 것입니다.
$ mkfifo fifo
$ command | filter1 > fifo & # this is the background job
$ < fifo sed 10q | filter2 # this is the foreground job