How is the process based on Linux system calls based?

What does a process process (like in Bash) look like in terms of Linux system calls?


The purpose of my question is that I do not understand why the bash manual says

asynchronous commands are invoked in a subnet environment,

(if I'm right, “asynchronous commands” means running commands in the background), while using strace, I found that the parent shell process first calls clone()to create a subshell, which is the copy itself, and then the subshell calls execve()to replace the subshell itself with a run command in the background.

It is like launching a foreground. I do not see the command being called in the subshell. If I am right, calling a command in a subshell means that the subshell calls clone()to create a subitem, and then subsubshell calls execve()to replace subsubshell itself with a command to run in the background. But in fact, the subshell does not name clone().

For instance,

On Ubuntu, I run datebash in an interactive shell whose pid is 6913 and at the same time it traces the bash shell from another interactive bash shell on strace.

At startup, datethe trace output of the first 6913 shell in the second shell:

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

At startup, date &the trace output of the first shell 6913 in the second shell:

$ 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)
+4
2

clone()

. bash , fork, . execute_cmd.c:

/* If this is a simple command, tell execute_disk_command that it
     might be able to get away without forking and simply exec.
     This means things like ( sleep 10 ) will only cause one fork.
     If we're timing the command or inverting its return value, however,
     we cannot do this optimization. */

syscall date date & , a wait.

, bash, - . let i++ let i++ & , bash, , , , .

+1

" " , - " POSIX". .

" " - , , fork, , :

$ VAR=value &
[1] 15479
[1]+  Done                    VAR=value
$ echo $VAR
$

, .

, , POSIX , , , . .

, , , , . , sort -u file | grep foo .

. , . , .

Ctrl-Z TTY, SIGTSTP . ( waitpid ), , , TTY.

, , , : - , . bg . Ctrl-Z a SIGTSTP, , . bg , . , TTY, SIGTTIN :

$ cat &
[1] 12620
$ bg
[1]+ cat &
$     # hit Enter 
[1]+  Stopped                 cat
$ bg
[1]+ cat &
$     # hit Enter
[1]+  Stopped                 cat

cat tty, , , SIGTTIN TTY , . , Ctrl-Z/SIGTSTP, , . , bg (), . cat (, SIGCONT), cat TTY, " , : SIGTTIN ". cat .

+1

All Articles