如何启动不属于原始流程的新流程?

Bet*_*ker 20 linux macos bash daemon

(OSX 10.7)我们使用的应用程序让我们分配在应用程序中发生某些活动时要调用的脚本.我已经分配了一个bash脚本并且正在调用它,问题是我需要做的是执行一些命令,等待30秒,然后再执行一些命令.如果我有我的bash脚本执行"睡眠30",整个应用程序冻结30秒,同时等待我的脚本完成.

我尝试将30秒等待(和第二组命令)放入一个单独的脚本并调用"./secondScript&"但应用程序仍然在那里停留30秒无所事事.我假设应用程序正在等待脚本和所有子进程终止.

我已经尝试过这些变体来从主脚本中调用第二个脚本,它们都有同样的问题:

  • nohup ./secondScript&
  • ((./ secondScript&)&)
  • (./secondScript&)
  • nohup脚本-q/dev/null secondScript&

我没有能力更改应用程序并告诉它启动我的脚本而不是等待它完成.

我如何启动一个进程(我希望该进程使用脚本语言),以便新进程不是当前进程的子进程?

谢谢,克里斯

ps我尝试了"disown"命令,它也没有帮助.我的主要脚本如下所示:

[initial commands]
echo Launching second script
./secondScript &
echo Looking for jobs
jobs
echo Sleeping for 1 second
sleep 1
echo Calling disown
disown
echo Looking again for jobs
jobs
echo Main script complete
Run Code Online (Sandbox Code Playgroud)

我得到的输出是这样的:

Launching second script
Looking for jobs
[1]+ Running ./secondScript &
Sleeping for 1 second
Calling disown
Looking again for jobs
Main script complete
Run Code Online (Sandbox Code Playgroud)

此时调用应用程序在那里停留45秒,等待secondScript完成.

PPS

如果在主脚本的顶部,我执行"ps",它返回的唯一内容是我在单独的终端窗口中打开的交互式bash会话的进程ID.

$ SHELL的值是/ bin/bash

如果我执行"ps -p $$"它正确告诉我

PID   TTY TIME    CMD
26884 ??  0:00.00 mainScript
Run Code Online (Sandbox Code Playgroud)

如果我执行"lsof -p $$"它会给我各种结果(我没有在这里粘贴所有列,假设它们不相关):

FD   TYPE   NAME
cwd  DIR    /private/tmp/blahblahblah
txt  REG    /bin/bash
txt  REG    /usr/lib/dyld
txt  REG    /private/var/db/dyld/dyld_shared_cache_x86_64
0    PIPE   
1    PIPE   -> 0xffff8041ea2d10
2    PIPE   -> 0xffff 8017d21cb
3r   DIR    /private/tmp/blahblah
4r   REG    /Volumes/DATA/blahblah
255r REG    /Volumes/DATA/blahblah
Run Code Online (Sandbox Code Playgroud)

tha*_*guy 25

在Unix中执行此操作的典型方法是双叉.在bash中,你可以这样做

( sleep 30 & )
Run Code Online (Sandbox Code Playgroud)

(..)创建子进程,并&创建一个孙进程.当子进程终止时,孙进程由init继承.


如果这不起作用,那么您的应用程序不会等待子进程.

它可能正在等待的其他事情包括会话和打开锁定文件:

要创建一个新会话,Linux有一个setsid.在OS X上,您可能能够完成它script,顺便提一下也会创建一个新会话:

# Linux:
setsid sleep 30

# OS X:
nohup script -q -c 'sleep 30' /dev/null &
Run Code Online (Sandbox Code Playgroud)

要查找继承的文件描述符列表,您可以使用lsof -p yourpid,它将输出如下内容:

sleep   22479 user    0u   CHR 136,32      0t0       35 /dev/pts/32
sleep   22479 user    1u   CHR 136,32      0t0       35 /dev/pts/32
sleep   22479 user    2u   CHR 136,32      0t0       35 /dev/pts/32
sleep   22479 user    5w   REG  252,0        0  1048806 /tmp/lockfile
Run Code Online (Sandbox Code Playgroud)

在这种情况下,除了标准FD 0,1和2之外,还有一个fd 5打开一个锁定文件,父级可以等待.

要关闭fd 5,您可以使用exec 5>&-.如果您认为锁定文件本身可能是stdin/stdout/stderr,则可以使用nohup它们将其重定向到其他位置.


tho*_*hom 12

另一种方法是放弃孩子

#!/bin/bash

yourprocess &

disown
Run Code Online (Sandbox Code Playgroud)

据我所知,该应用程序取代了普通的bash shell,因为即使init应该处理这个子进程,它仍在等待进程完成.可能是" 应用程序 "拦截了通常由其完成的孤儿处理init.

在这种情况下,只有一些IPC的并行流程才能提供解决方案(参见我的其他答案)


Joe*_*Joe 11

我认为这取决于您的父进程如何尝试检测您的子进程是否已完成.在我的情况下(我的父进程是gnu make),我成功通过关闭stdout和stderr(略微基于其他人答案),如下所示:

sleep 30 >&- 2>&- &
Run Code Online (Sandbox Code Playgroud)

您也可以关闭标准输入

sleep 30 <&- >&- 2>&- &
Run Code Online (Sandbox Code Playgroud)

或者另外拒绝您的子进程(不适用于Mac)

sleep 30 <&- >&- 2>&- & disown
Run Code Online (Sandbox Code Playgroud)

目前仅在kubuntu 14.04和Mac OSX上使用bash进行测试.