"bash -c"를 사용하거나 사용하지 않고 셸에서 명령을 실행하는 것의 차이점은 무엇입니까?

"bash -c"를 사용하거나 사용하지 않고 셸에서 명령을 실행하는 것의 차이점은 무엇입니까?

bash -c <command>bash 쉘에서 직접 명령을 실행하는 것과 bash 쉘에서 명령을 실행하는 것의 차이점은 무엇입니까? 내 질문의 목적은 bash -c쉘이 아닌 쉘에서 명령을 실행하는 방법을 알고 싶다는 것입니다 . 이 정보는 이전 질문에 대해 생각하는 데 도움이 될 수 있습니다.https://unix.stackexchange.com/questions/261595/do-a-bash-script-and-bash-c-command-run-in-a-subshell-environment, 그리고환경이 아닌 변수가 명령 대체를 통해 호출된 하위 쉘에 전달되는 이유는 무엇입니까?

위의 질문을 이해하려고 노력한 한 가지 방법은 다음과 같습니다 strace. 그러나 그것을 사용하지 않고도 차이점을 설명할 수 있습니다 strace.

저는 Running bash -c date과 Running 이라는 두 가지 상황을 고려합니다 bash -c 'date&'.

  1. bash -c datepid 6913의 bash 쉘에서 실행하고 다른 쉘에서 해당 쉘을 추적하면 다음과 같습니다 .

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

    Bash 쉘(아래 참조)에서 실행하는 것과 비교할 때 date차이점은 clone()첫 번째 줄과 다음 사이에 추가 줄이 있다는 것입니다 execve() date.

    execve("/bin/bash", ["bash", "-c", "date"], [/* 66 vars */]) = 0
    

    차이점은 무엇을 의미하나요?

    date대신 실행 결과를 추적하십시오 bash -c date.

    $ 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)
    
  2. bash -c 'date&'pid 6913의 bash 쉘에서 실행하고 다른 쉘에서 해당 쉘을 추적하면 다음과 같습니다 .

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

    bash 쉘(아래 참조)에서 실행하는 것과 비교하면 date&두 가지 이상의 차이점이 있는 것 같습니다 execve.

    execve("/bin/bash", ["bash", "-c", "date&"], [/* 66 vars */]) = 0
    

    또한 하위 프로세스 생성, 즉 하위 프로세스 execve() date와 하위 프로세스를 정렬합니다 execve() /bin/bash.

    차이점은 무엇을 의미하나요?

    date&대신 런타임 추적 출력 bash -c 'date&':

    $ 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)
    

관련 정보