파이프와 명령에 대해 내가 이해한 바에 따르면, bash는 각 명령을 취하고, 각 명령에 대한 프로세스를 생성하고, 이전 명령의 표준 출력을 다음 명령의 표준 입력과 연결합니다.
예를 들어, "ls -lsa | grep feb"에서 bash는 두 개의 프로세스를 생성하고 "ls -lsa"의 출력을 "grep feb"의 입력에 연결합니다.
Bash에서 "sleep 30 &"와 같은 백그라운드 명령을 실행하면 해당 명령을 실행하는 백그라운드 프로세스의 pid를 얻게 됩니다. 놀랍게도 "ls -lsa | grep feb &"라고 쓰면 bash는 하나의 PID만 반환합니다.
이것을 어떻게 설명해야 할까요? "ls -lsa"와 "grep feb"를 동시에 실행하는 하나의 프로세스가 있습니까? 여러 프로세스가 생성되었지만 그 중 하나만 pid를 얻습니까?
답변1
백그라운드에서 작업을 실행하면 bash는 하위 프로세스의 프로세스 ID, 즉 작업에서 실행 중인 명령의 프로세스 ID를 인쇄합니다. 작업이 더 많은 하위 프로세스를 생성하는 경우 상위 셸과는 아무런 관련이 없습니다.
something1 | something2 &
백그라운드 작업이 파이프라인(예: eg가 아닌 형식의 명령 { something1 | something2; } &
)인 경우 POSIX에서 강력히 권장하고 bash를 포함한 대부분의 셸에서 수행되는 최적화가 있습니다. 파이프라인의 각 요소는 다음의 하위 프로세스로 직접 실행됩니다. 원래 껍질. POSIX 요구사항은바꾸다$!
이 경우 파이프라인의 마지막 명령으로 설정됩니다. 대부분의 셸에서 마지막 명령은 파이프라인의 다른 명령과 마찬가지로 원래 프로세스의 하위 명령입니다.
을 실행하면 ls -lsa | grep feb
세 가지 프로세스가 관련됩니다. 파이프의 왼쪽을 실행하는 프로세스(파이프 설정을 완료한 다음 실행하는 하위 셸 ls
), 파이프의 오른쪽을 실행하는 프로세스(파이프를 완성하는 하위 셸) 설정 후 실행 grep
) 및 대기 파이프라인 완료의 원래 프로세스입니다.
프로세스를 추적하여 진행 상황을 관찰할 수 있습니다.
$ strace -f -e clone,wait4,pipe,execve,setpgid bash --norc
execve("/usr/local/bin/bash", ["bash", "--norc"], [/* 82 vars */]) = 0
setpgid(0, 24084) = 0
bash-4.3$ sleep 10 | sleep 20 &
…
sleep
두 번째 항목이 어떻게 보고되고 저장되는지 확인하세요 $!
. 하지만 프로세스 그룹 ID는 첫 번째 항목입니다 sleep
. Dash에는 ksh 및 mksh에 없는 동일한 특징이 있습니다.
답변2
2개의 프로세스를 생성합니다. &
두 번째 프로세스의 PID를 표시합니다 . 아래 예.
$ echo $$
13358
$ sleep 100 | sleep 200 &
[1] 13405
$ ps -ef|grep 13358
ec2-user 13358 13357 0 19:02 pts/0 00:00:00 -bash
ec2-user 13404 13358 0 19:04 pts/0 00:00:00 sleep 100
ec2-user 13405 13358 0 19:04 pts/0 00:00:00 sleep 200
ec2-user 13406 13358 0 19:04 pts/0 00:00:00 ps -ef
ec2-user 13407 13358 0 19:04 pts/0 00:00:00 grep --color=auto 13358
$