명령을 직접 실행하는 것과 백그라운드에서 명령을 실행하는 것을 비교해 보세요.

명령을 직접 실행하는 것과 백그라운드에서 명령을 실행하는 것을 비교해 보세요.

우분투에서는 datepid 6913을 사용하는 대화형 bash 쉘에서 실행 중이며, .trace를 통해 다른 대화형 bash 쉘에서 해당 bash 쉘을 추적하고 있습니다 strace.

dateTrace를 이용하여 직접 실행하는 방법을 알고 싶습니다 .여기추적 출력의 경우) 및 배경(참조여기추적 출력의 경우):

run 을 실행하면 date두 번째 셸에서 첫 번째 셸 6913을 추적한 결과는 다음과 같습니다.

$ sudo strace -f -e trace=process -p 6913
[sudo] password for t: 
Process 6913 attached
clone(Process 12918 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f457c05ca10) = 12918
[pid  6913] wait4(-1,  <unfinished ...>
[pid 12918] execve("/bin/date", ["date"], [/* 66 vars */]) = 0
[pid 12918] arch_prctl(ARCH_SET_FS, 0x7ff00c632740) = 0
[pid 12918] exit_group(0)               = ?
[pid 12918] +++ exited with 0 +++
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 12918
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12918, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffea6781518, WNOHANG|WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child processes)

run 을 실행하면 date &두 번째 셸에서 첫 번째 셸 6913을 추적한 결과는 다음과 같습니다.

$ sudo strace -f -e trace=process -p 6913
Process 6913 attached
clone(Process 12931 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f457c05ca10) = 12931
[pid 12931] execve("/bin/date", ["date"], [/* 66 vars */]) = 0
[pid 12931] arch_prctl(ARCH_SET_FS, 0x7f530c5ee740) = 0
[pid 12931] exit_group(0)               = ?
[pid 12931] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12931, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED|WCONTINUED, NULL) = 12931
wait4(-1, 0x7ffea6780718, WNOHANG|WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child processes)

run 을 실행하면 echo $b &두 번째 셸에서 첫 번째 셸 6913을 추적한 결과는 다음과 같습니다.

$ sudo strace -f -e trace=process -p 6913
Process 6913 attached
clone(Process 31319 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f457c05ca10) = 31319
[pid 31319] exit_group(0)               = ?
[pid 31319] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=31319, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED|WCONTINUED, NULL) = 31319
wait4(-1, 0x7ffea6780718, WNOHANG|WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child processes)

run 을 실행하면 { date; } &두 번째 셸에서 첫 번째 셸 6913을 추적한 결과는 다음과 같습니다.

$ sudo strace -f -e trace=process -p 6913
Process 6913 attached
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f457c05ca10) = 31294
Process 31294 attached
[pid 31294] clone(Process 31295 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f457c05ca10) = 31295
[pid 31294] wait4(-1,  <unfinished ...>
[pid 31295] execve("/bin/date", ["date"], [/* 67 vars */]) = 0
[pid 31295] arch_prctl(ARCH_SET_FS, 0x7f78b7f0b740) = 0
[pid 31295] exit_group(0)               = ?
[pid 31295] +++ exited with 0 +++
[pid 31294] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 31295
[pid 31294] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=31295, si_status=0, si_utime=0, si_stime=0} ---
[pid 31294] wait4(-1, 0x7ffea67811d8, WNOHANG, NULL) = -1 ECHILD (No child processes)
[pid 31294] exit_group(0)               = ?
[pid 31294] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=31294, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED|WCONTINUED, NULL) = 31294
wait4(-1, 0x7ffea6780718, WNOHANG|WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child processes)

질문:

  1. 명령을 실행하는 한 date직접 실행하고 백그라운드에서 실행하는 것은 동일한 작업을 수행하는 것 같습니다.

    명령을 직접 실행하는 경우 원래 bash 셸 자체는 6913 이고 명령은 clone()12918 복제됩니다 .execve()

    백그라운드에서 명령을 실행하면 원래 bash 셸 clone()자체가 6913이고 그 복제본이 12931 execve()명령입니다.

    둘 다 clone()한 번만 호출됩니다. 그들 사이의 차이점은 무엇입니까?

  2. 명령이 외부인지 내장인지는 중요하지 않습니다. 예를 들어 실행 date&과 실행은 echo $b &모두 한 번 호출됩니다 clone(). 왜 그런 차이가 있습니까?

  3. running date &과 를 비교해 보세요 { date; } &. Bash 매뉴얼에는 중괄호가 하위 쉘을 생성하지 않는다고 나와 있습니다. 추적 출력이 다른 이유:

    • 추적 출력에는 단 하나의 클론(6913 생성 12931)과 클론 12931 date&만 있습니다 .clone()execve() date
    • 추적 출력에는 두 개의 클론(6913이 31294를 생성하고, 31294가 31295를 생성)과 마지막 클론이 31295가 { date; }&있습니다 .clone()clone()execve() date
  4. 백그라운드에서 실행되는 명령(예: date&)은 상위 쉘의 하위 쉘에서 실행되기 때문에 상위 쉘의 로컬 변수에 액세스할 수 있는 반면, 직접 실행되는 명령은(예: date) 하위 쉘에서 실행되지 않기 때문에 액세스할 수 없습니다. 상위 쉘의 서브쉘. 추적된 출력을 사용하여 차이점을 설명할 수 있습니까?

    $ b=1
    $ { echo $b; } &
    [1] 31214
    1
    

    이는 b환경 변수가 아닌 상위 셸에 대한 로컬 변수입니다. 하위 셸은 &상위 셸의 복사본에서 생성되므로 상위 셸의 값을 미러링합니다. 나는 다음에서 이 예제를 만들었습니다.bb1또 다른백그라운드 대신 명령 대체를 사용하며, 둘 다 명령을 실행하기 위한 하위 쉘을 생성합니다.

관련 정보