我有一个脚本,我想在某一时刻分叉,因此同一脚本的两个副本正在运行。
例如,我希望存在以下 bash 脚本:
echo $$
do_fork()
echo $$
Run Code Online (Sandbox Code Playgroud)
如果此 bash 脚本确实存在,则预期输出将是:
<ProcessA PID>
<ProcessB PID>
<ProcessA PID>
Run Code Online (Sandbox Code Playgroud)
或者
<ProcessA PID>
<ProcessA PID>
<ProcessB PID>
Run Code Online (Sandbox Code Playgroud)
有什么我可以代替“do_fork()”来获得这种输出的东西,或者让 bash 脚本做一个类似 C 的 fork?
Gil*_*il' 27
是的。分叉拼写为&
:
echo child & echo parent
Run Code Online (Sandbox Code Playgroud)
可能让您感到困惑的是,这$$
不是 shell 进程的 PID,而是原始shell 进程的 PID 。这样做的意义在于,它是$$
特定 shell 脚本实例的唯一标识符:它在脚本执行期间不会更改,并且与$$
任何其他并发运行的脚本不同。获取 shell 进程的实际 PID 的一种方法是sh -c 'echo $PPID'
.
shell 中的控制流与 C 不同。如果在 C 中你会写
first(); fork(); second(); third();
Run Code Online (Sandbox Code Playgroud)
那么一个shell等价物是
after_fork () { second; third; }
first; after_fork & after_fork
Run Code Online (Sandbox Code Playgroud)
简单的 shell 形式first; child & parent
对应于通常的 C 习语
first(); if (fork()) parent(); else child();
Run Code Online (Sandbox Code Playgroud)
&
并且$$
在每个 Bourne 风格的 shell 和 (t)csh 中都以这种方式存在和表现。$PPID
在原始 Bourne shell 中不存在,但在 POSIX 中(所以它在 ash、bash、ksh、zsh 中,...)。
Kei*_*ith 11
是的,它被称为subshells。括号内的外壳代码作为子外壳(fork)运行。然而,第一个 shell 通常会等待子进程完成。您可以使用&
终止符使其异步。看看它的实际效果,如下所示:
#!/bin/bash
(sleep 2; echo "subsh 1")&
echo "topsh"
Run Code Online (Sandbox Code Playgroud)
$ bash subsh.sh
没有本地 bash(或者,据我所知,任何其他典型的 *nix shell)方法来执行此操作。有很多方法可以产生异步执行其他操作的分叉进程,但我认为没有任何遵循 fork() 系统调用的确切语义的方法。
典型的方法是让您的顶级脚本产生只完成您想要拆分的工作的助手。如果你这样做$0 $@ &
或其他什么,你会重新开始,需要以某种方式解决这个问题。
我实际上开始想到几种聪明的方法可以做到这一点......
但是,在我的大脑对此过于痴迷之前,我认为一个很好的规则是:如果您尝试在 shell 中编写一些东西并且它充满了聪明的技巧并且您希望获得更多语言功能,那么是时候切换了到真正的编程语言。
归档时间: |
|
查看次数: |
76895 次 |
最近记录: |