따르면 이 , 중괄호 명령 목록을 배치하는 것은 현재 셀 환경에서 실행되는리스트를 야기한다. 서브 쉘이 작성되지 않습니다 .
ps
이것을 실제로 사용 하기 위해 사용
이것은 명령 줄에서 직접 실행되는 프로세스 파이프 라인의 프로세스 계층입니다. 4398은 로그인 쉘의 PID입니다.
sleep 2 | ps -H;
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29696 pts/23 00:00:00 sleep
29697 pts/23 00:00:00 ps
이제 명령 행에서 직접 실행되는 중괄호 사이의 프로세스 파이프 라인에 대한 프로세스 계층 구조를 따릅니다. 4398은 로그인 쉘의 PID입니다. 위의 계층 구조와 비슷하여 모든 것이 현재 쉘 컨텍스트에서 실행된다는 것을 증명합니다 .
{ sleep 2 | ps -H; }
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29588 pts/23 00:00:00 sleep
29589 pts/23 00:00:00 ps
sleep
파이프 라인 내부가 중괄호 안에 배치 될 때의 프로세스 계층 구조입니다 (따라서 두 레벨의 중괄호).
{ { sleep 2; } | ps -H; }
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29869 pts/23 00:00:00 bash
29871 pts/23 00:00:00 sleep
29870 pts/23 00:00:00 ps
설명서에서 중괄호 사이의 명령이 현재 쉘 컨텍스트에서 실행된다고 설명 할 때 세 번째 경우 bash
에 실행할 서브 쉘을 작성해야하는 이유는 무엇 sleep
입니까?
답변
파이프 라인에서 모든 명령은 서로 다른 프로세스에서 동시에 파이프로 연결된 stdout / stdin과 함께 실행됩니다.
에서
cmd1 | cmd2 | cmd3
세 명령은 모두 다른 프로세스에서 실행되므로 둘 중 적어도 두 개는 하위 프로세스에서 실행되어야합니다. 일부 쉘은 현재 쉘 프로세스에서 빌드 중 하나를 실행하지만 ( read
파이프 라인이 스크립트의 마지막 명령 과 같은 경우 또는 파이프 라인이 스크립트의 마지막 명령 인 경우), bash
개별 프로세스에서 실행합니다 ( lastpipe
최근 bash
버전 의 옵션 및 일부 특정 조건 제외) ).
{...}
그룹 명령. 해당 그룹이 파이프 라인의 일부인 경우 간단한 명령처럼 별도의 프로세스에서 실행해야합니다.
에서:
{ a; b "$?"; } | c
a; b "$?"
별도의 프로세스인지 평가하려면 셸이 필요하므로 하위 셸이 필요합니다. 셸은 b
해당 그룹에서 마지막으로 실행되는 명령이므로 포크하지 않아도 최적화 할 수 있습니다. 일부 포탄은 그렇게하지만 분명히하지 않습니다 bash
.
답변
중괄호를 중첩하면 새 하위 쉘을 호출해야하는 추가 범위의 범위 지정을 작성하는 것으로 나타납니다. ps -H
출력 에서 Bash의 두 번째 사본에서이 효과를 볼 수 있습니다 .
첫 번째 수준의 중괄호에 명시된 프로세스 만 원래 Bash 셸 범위 내에서 실행됩니다. 중첩 된 중괄호는 자체 범위가 지정된 Bash 셸에서 실행됩니다.
예
$ { { { sleep 20; } | sleep 20; } | ps -H; }
PID TTY TIME CMD
29190 pts/1 00:00:00 bash
5012 pts/1 00:00:00 bash
5014 pts/1 00:00:00 bash
5016 pts/1 00:00:00 sleep
5015 pts/1 00:00:00 sleep
5013 pts/1 00:00:00 ps
복용 | ps -H
믹스 밖으로 것은 단지 우리가 중첩 된 중괄호를 볼 수 있습니다, 우리는 실행할 수있는 ps auxf | less
다른 쉘에서.
saml 29190 0.0 0.0 117056 3004 pts/1 Ss 13:39 0:00 \_ bash
saml 5191 0.0 0.0 117056 2336 pts/1 S+ 14:42 0:00 | \_ bash
saml 5193 0.0 0.0 107892 512 pts/1 S+ 14:42 0:00 | | \_ sleep 20
saml 5192 0.0 0.0 107892 508 pts/1 S+ 14:42 0:00 | \_ sleep 20
saml 5068 0.2 0.0 116824 3416 pts/6 Ss 14:42 0:00 \_ bash
saml 5195 0.0 0.0 115020 1272 pts/6 R+ 14:42 0:00 \_ ps auxf
saml 5196 0.0 0.0 110244 880 pts/6 S+ 14:42 0:00 \_ less
그러나 더 기다립니다!
파이프를 꺼내고이 형식의 명령을 사용하면 실제로 예상되는 것을 볼 수 있습니다.
$ { { { sleep 10; } ; { sleep 10; } ; sleep 10; } } | watch "ps -H"
이제 결과보기 창에서 2 초마다 업데이트가 진행됩니다.
첫 번째는 다음과 같습니다 sleep 10
.
PID TTY TIME CMD
29190 pts/1 00:00:00 bash
5676 pts/1 00:00:00 bash
5678 pts/1 00:00:00 sleep
5677 pts/1 00:00:00 watch
5681 pts/1 00:00:00 watch
5682 pts/1 00:00:00 ps
두 번째는 다음과 같습니다 sleep 10
.
PID TTY TIME CMD
29190 pts/1 00:00:00 bash
5676 pts/1 00:00:00 bash
5691 pts/1 00:00:00 sleep
5677 pts/1 00:00:00 watch
5694 pts/1 00:00:00 watch
5695 pts/1 00:00:00 ps
세 번째는 다음과 같습니다 sleep 10
.
PID TTY TIME CMD
29190 pts/1 00:00:00 bash
5676 pts/1 00:00:00 bash
5704 pts/1 00:00:00 sleep
5677 pts/1 00:00:00 watch
5710 pts/1 00:00:00 watch
5711 pts/1 00:00:00 ps
서로 다른 중첩 레벨의 중괄호에서 호출 되었음에도 불구하고 세 가지 수면은 모두 Bash의 PID 5676 내에 유지됩니다. 따라서 귀하의 문제는 | ps -H
.
결론
| ps -H
파이프 (예 : 파이프)를 사용 하면 추가 하위 셸이 발생하므로 진행중인 문제를 조사 할 때 해당 방법을 사용하지 마십시오.
답변
테스트 결과를 게시 할 것인데, bash는 그룹 명령에 대한 하위 쉘을 파이프 라인의 일부 인 경우 에만 호출합니다. 하위 셸에서.
$ { A=1; { A=2; sleep 2; } ; echo $A; }
2
$ { A=1; { A=2; sleep 2; } | sleep 1; echo $A; }
1