简体   繁体   English

将命令行工具作为分离的进程启动

[英]Launch Command Line Tool as detached Process

Invoking a command line tool ( bash , ls ) via Process works, but unfortunately it is created as a child process.通过Process调用命令行工具( bashls )可以工作,但不幸的是它被创建为子进程。

I need to start the tool as a separate process, without adding it as a subprocess to my running application.我需要将该工具作为一个单独的进程启动,而不是将它作为子进程添加到我正在运行的应用程序中。

Therefore I tried to start a detached process of bash using launch services with因此,我尝试使用启动服务启动一个分离的bash进程

let ws = NSWorkspace.shared
let url = URL(fileURLWithPath: "/bin/bash")

let app = try ws.launchApplication(at: url, options: [.default], configuration: [
    .arguments: args,
    .environment: env
])

Unfortunately the call doesn't seem to do anything, I guess it only supports app bundles?不幸的是,电话似乎没有做任何事情,我猜它只支持应用程序包? How do I start a process, like eg bash , without creating a child process?如何在不创建子进程的情况下启动进程,例如bash

What I basically try to do is create a short-lived process that executes one thing and exits immediately without having my app as a parent.我基本上尝试做的是创建一个短期进程,该进程执行一件事并立即退出,而无需将我的应用程序作为父进程。

One method would be to create a helper tool that fork s, starts a new session with setsid and invokes the command, but I'd prefer not to rely on an external tool, and forking my own process is out of the question.一种方法是创建一个辅助工具,它fork s,使用setsid启动一个新会话并调用命令,但我不希望依赖外部工具,而且我自己的进程是不可能的。 It is crucial that the invocation is done from a process with ppid=1 .调用是从具有ppid=1的进程完成的,这一点至关重要。

First of all, you can't create a process that isn't a child process.首先,你不能创建一个不是子进程的进程。 The only process that's not a child process is the bootstrap kernel process (PID 0).唯一不是子进程的进程是引导内核进程 (PID 0)。 Every other process is a child of some other process.每个其他进程都是其他进程的子进程。

You can accomplish this by starting the executable running using a Process object (formerly NSTask ) (the easy way) or with one of the traditional UNIX functions ( execle() et. al.), and then just let it run.您可以通过使用Process对象(以前称为NSTask )(最简单的方法)或使用传统的 UNIX 函数之一( execle()execle()启动可执行文件来实现这一点,然后让它运行。

The only thing you have to do is make sure your child process isn't tied to anything that would cause it to block or stop when your application terminates.您唯一需要做的就是确保您的子进程没有绑定到任何会导致它在应用程序终止时阻塞或停止的情况。 Most notably, connect stdin , stdout , and stderr to nothing (see NSFileHandle.fileHandleWithNullDevice ) or something like a file or pipe that is not controlled by your process.最值得注意的是,将stdinstdoutstderr连接到NSFileHandle.fileHandleWithNullDevice (参见NSFileHandle.fileHandleWithNullDevice )或诸如不受进程控制的文件或管道之类的东西。

Start the executable ( task.lanch() ) and then simply discard the Process object;启动可执行文件( task.lanch() ),然后简单地丢弃Process对象; it will continue running on its own.它将继续自行运行。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM