简体   繁体   English

为什么(ps -f)不创建子shell但只创建一个单独的进程?

[英]Why does (ps -f) create no subshell but a separate process?

I need some help because I don't get something. 我需要一些帮助,因为我没有得到任何东西。 From what I read from Internet, a subshell is created when we execute a shell script or if we run command in brackets: ( ) 从我从Internet读取的内容,当我们执行shell脚本或者在括号中运行命令时,会创建一个子shell :( ( )

I tried to test this with a script which contains only the following command: 我尝试使用仅包含以下命令的脚本来测试它:

ps -f

When I run it I see the following result: 当我运行它时,我看到以下结果:

ID      PID  PPID  C STIME TTY          TIME CMD 
me     2213  2160  0 08:53 pts/14   00:00:00 bash 
me     3832  2213  0 18:41 pts/14   00:00:00 bash 
me     3833  3832  0 18:41 pts/14   00:00:00 ps -f

Which is good, because I see that my bash process has spawned another bash process for my script. 哪个好,因为我看到我的bash进程为我的脚本产生了另一个bash进程。

But when I do: 但当我这样做时:

( ps -f )

it produces: 它产生:

UID     PID  PPID  C STIME TTY          TIME CMD 
me     2213  2160  0 08:53 pts/14   00:00:00 bash 
me     3840  2213  0 18:46 pts/14   00:00:00 ps -f

So if brackets spawn a subshell why it is not shown in the processes? 因此,如果括号产生子shell,为什么它不会显示在进程中? And why does ps -f is counted as another process? 为什么ps -f被算作另一个过程? Does every command run as a separate process? 每个命令都作为一个单独的进程运行吗?

It seems you've caught bash in a little bit of an optimization. 看来你已经在一点点优化中抓住了bash if a subshell contains only a single command, why really make it a subshell? 如果子shell只包含一个命令,为什么要真正使它成为子shell?

$ ( ps -f )
UID        PID  PPID  C STIME TTY          TIME CMD
jovalko  29393 24133  0 12:05 pts/10   00:00:00 bash
jovalko  29555 29393  0 12:07 pts/10   00:00:00 ps -f

However, add a second command, say : (the bash null command, which does nothing) and this is the result: 但是,添加第二个命令,例如: bash null命令,什么都不做),这是结果:

$ ( ps -f ; : )
UID        PID  PPID  C STIME TTY          TIME CMD
jovalko  29393 24133  0 12:05 pts/10   00:00:00 bash
jovalko  29565 29393  0 12:08 pts/10   00:00:00 bash
jovalko  29566 29565  0 12:08 pts/10   00:00:00 ps -f

One of the main reasons to use a subshell is that you can perform operations like I/O redirection on a group of commands instead a single command, but if your subshell contains only a single command there's not much reason to really fork a new bash process first. 使用子shell的主要原因之一是您可以对一组命令执行I / O重定向等操作而不是单个命令,但如果您的子shell只包含一个命令,则没有太多理由真正分叉新的bash进程第一。

As to ps counting as a process, it varies. 至于ps计数的过程中,各不相同。 Many commands you use like ls , grep , awk are all external programs. 您使用的许多命令,如lsgrepawk都是外部程序。 But, there are builtins like cd , kill , too. 但是,也有内置像cdkill等。

You can determine which a command is in bash using the type command: 您可以使用type命令确定bash中的命令:

$ type ps
ps is hashed (/bin/ps)
$ type cd
cd is a shell builtin

The main part of the question is: 问题的主要部分是:

Does every command run as a separate process? 每个命令都作为一个单独的进程运行吗?

YES!. 是!。 Every command what isn't built-in into bash (like declare and such), runs as separate process. 没有内置到bash中的每个命令(如declare等)都作为单独的进程运行。 How it is works? 它是如何工作的?

When you type ps and press enter, the bash analyze what you typed, do usual things as globbing, variable expansionas and such, and finally when it is an external command 当你输入ps并按回车时,bash会分析你输入的内容,做通常的事情,如globbing,变量扩展等等,最后当它是一个外部命令

  • the bash forks itself. bash forks自己。

The forking mean, than immediatelly after the fork, you will have two identical bash processes (each one with different process ID (PID)) - called as "parent" and "child", and the only difference between those two running bash programs is, than the "parent" gets (return value from the fork ) the PID of the child but the child don't know the PID of the parent. 分叉意味着,在fork之后立即执行两个 相同的 bash进程(每个进程具有不同的进程ID(PID)) - 称为“父”和“子”,这两个运行的bash程序之间的唯一区别是,而“父”得到(从fork返回值)孩子的PID,但孩子不知道父母的PID。 (fork for the child returns 0). (孩子的叉子返回0)。

  • after the fork, (bash is written this way) - the child replaces itself with the new program image (such: ps ) - using the exec call. 在fork之后,(bash以这种方式编写) - 子代替自己的新程序图像(例如: ps ) - 使用exec调用。
  • after this, the child bash of course doesn't exist anymore, and running only the newly executed command - eg the ps . 在此之后,子bash当然不再存在,并且只运行新执行的命令 - 例如ps

Of course, when the bash going to fork itself, do many other things, like I/O redirections, opens-closes filehandles, changes signal handling for the child and many-many other things. 当然,当bash进行自我分支时,还要执行许多其他操作,例如I / O重定向,打开 - 关闭文件句柄,更改孩子的信号处理以及许多其他事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在分组命令中执行简单命令不分叉子shell进程,而复合命令将执行此操作 - Why does executing a simple command in a grouping command does not fork a subshell process, and the compound command will do it 为什么ps o / p在管道之后列出grep进程? - Why does ps o/p list the grep process after the pipe? 为什么从子shell开始后台进程/为什么parens(someCommand&)? - Why start a background process from a subshell / why parens in (someCommand &)? 等待子shell进程完成 - Wait for subshell process to complete linux:为什么如果你通过管道将 ps 传送到 grep,grep 过滤器正在处理输出? 管道是如何工作的? - linux: why if you pipe ps to grep, grep filter is in process output ? How does pipe works? 为什么shell命令“{command1; command2:}&“打开子shell? - Why does shell command “{ command1; command2: } &" open a subshell? Linux 命令“ps”中的参数 -f 是什么意思? - What does parameter -f mean with Linux command 'ps'? 为什么env不打印PS1变量? - Why env does not print PS1 variable? 在subshel​​l下创建的文件不保留subshel​​l的umask设置 - File created under subshell does not keep subshell's umask setting 为什么这个程序会创建一个僵尸进程,我该如何解决? - why does this program create a zombie process and how do I fix it?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM