"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-subshel​​l-environment環境以外の変数がコマンド置換によって呼び出されたサブシェルに渡されるのはなぜですか?

上記の質問を理解しようとした1つの方法は次のとおりですstrace。ただし、それを使用せずに違いを説明できますstrace

私はRunningbash -c dateとRunningという2つの状況を考えています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&2つ以上の違いがあるようです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)
    

ベストアンサー1

おすすめ記事