gpt4 book ai didi

linux - 我如何在Linux中对Shell进行多项工作

转载 作者:太空宇宙 更新时间:2023-11-04 04:43:23 24 4
gpt4 key购买 nike

我是Linux的初学者,只是对工作和流程组有一些疑问。

我的教科书说:“ Unix外壳程序使用作业的抽象来表示由于评估单个命令行而创建的进程。在任何时间点,最多有一个前台作业和零个或多个后台作业。

可以说我们有这个简单的shell代码(我省略了一些不重要的代码,例如setup argv等):
enter image description here

enter image description here

当我们输入第一个命令时,例如:./exampleProgram &

Q1-是否创造工作?如果是,工作包含什么过程?

调用shellex.c的main(),因此在执行第15行时:fork()创建一个新的子进程,假设父进程为p1,而新创建的子进程为c1
如果是后台作业,那么我们可以在提示符下键入另一个命令./anotherProgram &并输入enter

Q2-我很确定,现在它只是p1和c1,而p1在执行第15行时再次执行第二条命令:fork(),
我们有p1,c1和新创建的c2,我的理解正确吗?

Q3-有几份工作?仅仅是包含p1,c1和c2的一项工作吗?

Q4-如果它只是一项工作,那么当我们继续键入新命令时,我们将只有一个工作包含一个父进程p1和许多子进程c1,c2,c3,c4 ...
那么为什么我的教科书上说壳牌可以做多个工作呢?以及为什么最多有一个前台作业和零个或多个后台作业。

最佳答案

关于这个话题,有很多话要说,其中一些可以作为答案,而大多数都需要进一步阅读。

对于第一季度,我从概念上说是的,但是作业不是自动的,作业跟踪和控制也不是不可思议的。我在您显示的代码片段中看不到任何逻辑,例如建立并维护一个工作表。我了解这只是一个示例,因此工作控制逻辑可能在其他地方。作业控制是常见的现有Unix Shell的功能,但是如果人们从头开始编写新的Unix Shell,则需要添加作业控制功能作为代码/逻辑。

对于第二季度,您所说的方式不是我所说的。在第一次调用fork()之后,是的,有一个p1和一个c1,但是首先要认识到p1和c1是同一程序(shellex)的不同实例。仅在execve()的调用正在运行之后。 exampleProgram创建fork()的子实例,并且shellex导致execve()的子实例被shellex替换(在RAM中)(假定为exampleProgram的值)。

父母在“处死”孩子方面没有真正意义,在argv[0]上替换孩子的过程没有真正意义,只是为了让他们前进。父级启动子级,并可能等待子级执行完成,但实际上,父级及其子进程的整个层次结构都各自独立执行,由内核执行。

但是可以,如果告诉运行的程序应该在后台运行,则execve()将接受进一步的输入,并且在下一次调用shellex时,将有两个子进程的父fork()。再次,首先,子c2将是shellex的实例,可以通过shellex快速替换为已命名的任何程序。

(关于在后台运行,execve()是否具有这种效果取决于示例代码中名为&的函数内部的逻辑。我熟悉的Shell使用parseline()表示“在后台运行“,但这并没有什么特别的或不可思议的。新编写的Unix shell可以以其他方式做到这一点,即尾随&或前导+或shell作者决定执行的任何操作。

对于Q3和Q4,首先要认识到的是,您正在调用BG:的父级是您所显示的Shell程序。因此,不,p1不会成为工作的一部分。

在Unix中,作业是作为单个管道的一部分执行的进程的集合。因此,一项工作可以包含一个或多个过程。此类进程仍附加到运行它们的终端,但可能在前台(正在运行和交互式),已挂起或在后台(正在运行而不是交互式)。

one process, foreground    : ls -lR
one process, background : ls -lR &
one process, background : ls -lR, then CTRL-Z, then bg
many processes, foreground : ls -lR | grep perl | sed 's/^.*\.//'
many processes, background : ls -lR | grep perl | sed 's/^.*\.//' &


要凭经验查看作业与流程,请在后台运行管道(上述5个示例中的第5个),并且在运行时使用 p1为您显示进程ID和进程组ID。例如,在我的Mac版本的bash上,这是:

$ ls -lR | grep perl | sed 's/^.*\.//' &
[1] 2454 <-- job 1, PID of the sed is 2454

$ ps -o command,pid,pgid
COMMAND PID PGID
vim 2450 2450 <-- running in a different tab
ls -lR 2452 2452 }
grep perl 2453 2452 }-- 3 PIDs, 1 PGID
sed s/^.*\.// 2454 2452 }


与外壳和终端的此附件相反,守护程序从两者分离。启动守护程序时,父级使用 ps启动子进程,但随后退出,仅使子级运行,并且现在具有父级PID1。子级关闭 fork()stdin和< cc>,因为它们没有意义,因为守护程序运行“无头”。

但是在外壳程序中,父级(又是外壳程序)保持运行 stdout ing(前台子程序)或不运行 stderr ing(后台子程序),并且子级通常保留使用 wait()wait()stdin(尽管它们可能会重定向到文件等)

而且,外壳程序可以调用子外壳程序,当然,运行的任何程序都可以 stdout自己的子进程,依此类推。因此,流程的层次结构会变得很深。如果没有其他特定操作,子进程将与其父进程位于同一进程组中。

以下是一些文章,供您进一步阅读:

What is difference between a job and a process in Unix?

https://unix.stackexchange.com/questions/4214/what-is-the-difference-between-a-job-and-a-process

https://unix.stackexchange.com/questions/363126/why-is-process-not-part-of-expected-process-group

Bash Reference Manual; Job Control

Bash Reference Manual; Job Control Basics

关于linux - 我如何在Linux中对Shell进行多项工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53331232/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com