我需要一些帮助,因为我没有得到任何东西。根据我从Internet上读到的内容,当我们执行shell脚本或者在括号中运行命令时会创建一个子shell:( )
我尝试使用仅包含以下命令的脚本来测试它:
ps -f
当我运行它时,我看到以下结果:
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
哪个好,因为我看到我的bash进程为我的脚本产生了另一个bash进程。
但是当我这样做时:
( ps -f )
它产生:
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
因此,如果括号产生子shell,为什么它不会显示在进程中?为什么ps -f
被视为另一个过程?每个命令都作为一个单独的进程运行吗?
答案 0 :(得分:4)
看起来你已经抓住了bash
进行了一些优化。如果一个子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
但是,添加第二个命令,比如:
(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
使用子shell的主要原因之一是您可以对一组命令执行I / O重定向等操作,而不是单个命令,但如果您的子shell只包含一个命令,则没有太多理由真正分叉新的bash流程首先。
至于ps
作为一个过程计算,它会有所不同。您使用的许多命令如ls
,grep
,awk
都是外部程序。但是,也有像cd
,kill
这样的内置组件。
您可以使用bash
命令确定type
中的命令:
$ type ps
ps is hashed (/bin/ps)
$ type cd
cd is a shell builtin
答案 1 :(得分:1)
问题的主要部分是:
每个命令都作为一个单独的进程运行吗?
YES!每个命令都没有内置到bash中(如declare
等),作为单独的进程运行。它是如何工作的?
当你输入ps
然后按回车键时,bash会分析你输入的内容,做通常的事情,如全局,变量扩展等等,最后当它是外部命令时
forks
本身。 分叉意味着,在分叉之后立即,你将两个 相同 {{1}进程(每个进程ID具有不同的进程ID(PID)) - 称为" parent"和"孩子",这两个正在运行的bash
程序之间的唯一区别是,"父母"获取(从bash
返回值)孩子的PID,但孩子不知道父母的PID。 (孩子的叉子返回0)。
fork
) - 使用ps
调用。 exec
。当然,当bash转向fork时,还要做很多其他事情,比如I / O重定向,打开 - 关闭文件句柄,改变孩子的信号处理以及许多其他事情。