누군가 이 스크립트의 이유를 설명할 수 있나요?
echo one &&
echo two &
echo three &&
echo four
나에게주세요
[1] 3692
three
four
one
two
[1]+ Done echo one && echo two
당연히 백그라운드 프로세스 이후의 모든 내용이 먼저 출력되고, 그 다음에는 백그라운드 프로세스 이전의 코드 줄이 시간순으로 인쇄됩니다. 나는 내가 쓰려고 했던 대본에서 그것을 우연히 발견했지만, 그것이 왜 그렇게 되었는지 알 수 없었습니다(비록 그 뒤에 약간의 독창성이 있을 것이라고 추측하지만).
나는 괄호를 사용하여 이것을 방지할 수 있다는 것을 발견했습니다:
echo one &&
(echo two &)
echo three &&
echo four
주어진
one
two
three
four
그리고
echo one &&
(sleep 2 && echo two &)
echo three &&
echo four
주어진
one
three
four
two
두 번째 줄은 백그라운드에서 대기 상태이므로 첫 번째 줄이 이미 실행 중인 동안 출력됩니다.
그런데 왜 괄호가 이런 효과를 가져오는 걸까요?
추가 질문: 괄호가 배경 PID 출력을 방해하는 이유는 무엇입니까?
답변1
echo one && echo two & echo three && echo four
기억하세요. 이것은 다음과 같이 구문 분석됩니다.
echo one && echo two &
echo three && echo four
나는 이 echo
명령이 성공했다고 가정합니다(전체 디스크의 파일로 리디렉션하는 등의 극단적인 경우에만 실패함). 따라서 이 코드 조각은 두 가지 작업을 병렬로 실행합니다. 하나는 행의 합계를 인쇄 one
하고 다른 하나는 행 의 two
합계를 인쇄합니다 . 합계 와 합계 의 분산은 보장되지 않으며 시스템, 셸 및 호출마다 다를 수 있습니다. 이와 같은 간단한 예를 사용하면 부하가 적은 시스템에서 재현 가능한 결과를 볼 수 있지만 이는 신뢰할 수 있는 것이 아닙니다.three
four
one
two
three
four
echo one && (echo two &) echo three && echo four
구문 분석을 변경했습니다. 여기서는 명령만 echo two
백그라운드에서 실행됩니다. 이렇게 하면 가 one
먼저 출력되고 before와 마찬가지로 three
항상 before가 되지만 four
위치는 two
after 어디에나 있을 수 있습니다 one
.
셸은 기본 셸 프로세스에서 시작된 경우에만 백그라운드 프로세스에 대한 메시지를 인쇄하고, 하위 셸에서 시작된 경우에는 해당 메시지를 인쇄하지 않습니다. 괄호는 하위 쉘을 생성하므로 (echo two &)
쉘이 메시지를 인쇄하지 않습니다. 이렇게 하면 백그라운드 프로세스가 생성되지만 백그라운드는 생성되지 않습니다.일하다.
echo one && (sleep 2 && echo two &) echo three && echo four
이 코드 조각에서 백그라운드 작업은 출력하기 전에 2초 동안 휴면 상태입니다 two
. 이로 인해 two
및 이후에 출력이 있을 가능성이 매우 높습니다(실제로 보장되지는 않음) .three
four
답변2
1 부
echo one &&
echo two &
echo three &&
echo four
이는 다음과 같이 다시 작성할 수 있습니다.
echo one && echo two &
echo three && echo four
three
처음에 and 를 얻는 이유는 단순히 and 를 인쇄하는 것보다 four
서브셸에서 one
and 를 처리하고 실행하는 데 시간이 더 오래 걸리기 때문입니다 .two
three
four
이렇게 보면 더 확실하게 알 수 있어요
echo one && echo two &
sleep 1
echo three && echo four
이 경우, 당신은 one
과 를 얻습니다 two
. 잠시 후에 당신은 three
과 를 얻습니다 four
.
원래 시나리오에서는 및 가 and 의 출력 one
과 혼합되지 않을 것이라는 보장이 없으며 또는 같은 단어가 삽입되는 경우에도 가능합니다.two
three
four
thonreee
twfouro
2 부
echo one &&
(echo two &)
echo three &&
echo four
이는 다음과 같이 다시 작성할 수 있습니다.
echo one && (echo two &)
echo three && echo four
여기서 일어나는 일은 one
즉시 인쇄한 다음 two
서브셸에서 트리거된다는 것입니다. 그런 다음 다음 줄이 (연속적으로) 실행되어 three
sum 을 생성합니다 four
. 특별한 경우 서브쉘은 two
출력하기 전에 인쇄할 수 있을 만큼 충분히 작고 빠릅니다. three
그러나 이에 대한 보장은 없습니다.
세 번째 부분
명령문을 하위 쉘로 그룹화합니다. & 기호는 &
명령문에 대해 작동하지만 이 경우 두 명령을 함께 연결하는 데 사용했으므로 &&
단일 명령문으로 처리해야 합니다.
echo one; echo two
어쩌면 대신 사용해야 할까요 echo one && echo two
? 그들은 매우 다릅니다. 세미콜론은 ;
두 명령을 구분하여 독립적으로 순차적으로 실행됩니다. 이중 앰퍼샌드는 &&
두 명령을 함께 연결합니다.논리 AND, 첫 번째가 성공적으로 완료될 때까지 두 번째가 실행되지 않도록 합니다. false; echo yes
, false && echo yes
, 및 을 비교합니다 true && echo yes
. 그런 다음 &&
(논리 AND) 그리고 ||
(논리적 또는).
보너스
서브쉘에는 작업 제어가 없으므로 작업 제어 알림이 손실됩니다.