내가 맞다면 명령 대체, 프로세스 대체, 파이프 및 백그라운드 작업은 원래 셸이 아닌 하위 셸에서 자체적으로 지정된 명령을 실행합니다.
그러나 명령이 jobs
또는 인 경우 dirs
해당 출력은 원래 셸에서 직접 실행될 때와 정확히 동일합니다.
echo $( jobs )
cat <(jobs)
jobs | less
echo $( dirs )
cat <(dirs)
dirs | less
dirs &
왜 그런 겁니까? 서브셸이 원본 셸에서 작업 및 디렉터리 스택을 상속하기 때문입니까, 아니면 jobs
및 이 dirs
서브셸이 아닌 원본 셸에서 실행되고 있기 때문입니까?
하지만
jobs &
아무것도 출력하지 않습니다. 왜 다른 명령과 다른가요? 감사해요.
답변1
이 답변의 첫 번째 부분은 과 내장되어 있으므로 일반적으로 bash는 서브 쉘을 호출하는 대신 직접 실행합니다 jobs
.dirs
$(jobs)
파이프나 명령 대체( )나 프로세스 대체( )가 있는 경우에도 마찬가지이다 <(jobs)
.
jobs &
백그라운드에서 명령을 실행하거나( ) 명시적으로 서브셸을 요청하는 경우( . 사용 ) ( jobs )
는 그렇지 않습니다 .
이것은 질문의 마지막 부분을 설명합니다. 서브셸에서 실행 하면 jobs
서브셸 자체에 대한 작업이 표시됩니다.
다음은 이 개념을 잘 보여주는 예입니다.
$ sleep 1001 &
[1] 15927
$ sleep 1002 &
[2] 15940
$ jobs
[1]- Running sleep 1001 &
[2]+ Running sleep 1002 &
$ ( sleep 1003 & jobs )
[1]+ Running sleep 1003 &
$ jobs
[1]- Running sleep 1001 &
[2]+ Running sleep 1002 &
jobs
서브셸에서 실행할 때 해당 서브셸에 대한 작업 만 표시되는 것을 볼 수 있습니다 (이 경우).sleep 1003
이제 요약하자면 문제의 중간 부분을 해결해야 합니다. 이것이 dirs &
바로 (하위 쉘에서 실행되는 것처럼 ( dirs )
) 여전히 Pushd 스택에 저장된 디렉터리를 표시하는 이유입니다.
DIRSTACK
이는 쉘이 디렉토리 목록을 특수 배열 변수로 내보내고 이 변수가 서브쉘에 의해 상속되기 때문인 것으로 나타났습니다 . (자세한 내용은DIRSTACK
여기.)
이것이 어떻게 작동하는지 보여주는 한 가지 방법은 pushd
하위 쉘에서 사용하고 원래 쉘의 디렉토리 스택에 어떻게 영향을 주지 않는지 확인하는 것입니다.
$ dirs
~
$ pushd ~/tmp
~/tmp ~
$ ( dirs; pushd / >/dev/null; dirs )
~/tmp ~
/ ~/tmp ~
$ dirs
~/tmp ~
나는 이것이 당신이 요청한 모든 문제를 해결해야 한다고 믿습니다.
고쳐 쓰다jobs | less
:bash에는 현재 셸에서 명령을 실행할 수 있는 특별한 조항이 있습니다 jobs
(다른 내장 명령은 그렇지 않습니다.)
코드에는 하위 쉘을 생성하지 않고 실행하고 출력을 다른 명령으로 jobs_hack
파이프할 수 있도록 나중에 검사되는 변수에 검사가 저장 되어 있습니다.jobs
바라보다여기이 기능을 구현하는 소스 코드의 관련 부분을 이해하십시오. (배쉬 4.4부터)