groovy - 如何在 Groovy 中将进程的 stdout、stderr 和 stdin 重定向到文件或从文件重定向,就像在 Bash shell 中一样?

标签 groovy scripting groovyshell

我正在将 Bash shell 脚本移植到 Groovy。大多数构造都可以轻松转换(例如,将 mkdir "$foo" 转换为 foo.mkdir()。但是,我对此感到困惑:

#!/bin/bash
sleep 60 > /tmp/output.log 2>&1 < /dev/null

运行时,让我们检查一下sleep的文件描述符:

$ ls -l /proc/$(pgrep sleep)/fd
total 0
lr-x------ 1 user user 64 Feb 25 13:40 0 -> /dev/null
l-wx------ 1 user user 64 Feb 25 13:40 1 -> /tmp/output.log
l-wx------ 1 user user 64 Feb 25 13:40 2 -> /tmp/output.log

可以通过这种方式在 Groovy 中运行进程(根据 this page ):

#!/usr/bin/groovy
def log = new FileOutputStream("/tmp/output.log")
def sleep = "sleep 60".execute()
sleep.waitForProcessOutput(log, log)

以及sleep的文件描述符:

$ ls -l /proc/$(pgrep sleep)/fd
total 0
lr-x------ 1 user user 64 Feb 25 13:41 0 -> pipe:[522455]
l-wx------ 1 user user 64 Feb 25 13:41 1 -> pipe:[522456]
l-wx------ 1 user user 64 Feb 25 13:41 2 -> pipe:[522457]

可以看出,文件描述符与其他东西(可能是 Groovy 进程)相关联。因为这将用于长期运行的流程,所以我想去掉 Groovy 作为中间人。

所以,我的问题:如何将文件重定向到 stdinstdoutstderr 到文件,以便外部进程可以分离并且Groovy不需要运行吗?

编辑:这个问题不是capture process output in Groovy 重复,因为该问题涉及重定向 stdoutstderr到 Groovy 进程本身的 stdoutstderr。从 @tim_yates 的回答可以看出,这是完全不同的事情。

最佳答案

ProcessBuilder.redirectOutput()可以解决这个问题since Java 7 。而且由于它是标准 Java,因此也可以在 Groovy 中使用。

#!/usr/bin/groovy
def sleep = new ProcessBuilder('sleep', '60')
                    .redirectOutput(new File('/tmp/output.log'))
                    .redirectErrorStream(true)
                    .redirectInput(new File('/dev/null'))
                    .start();

结果:

$ ls -l /proc/$(pgrep sleep)/fd
total 0
lr-x------ 1 user user 64 Feb 26 11:44 0 -> /dev/null
l-wx------ 1 user user 64 Feb 26 11:44 1 -> /tmp/output.log
l-wx------ 1 user user 64 Feb 26 11:44 2 -> /tmp/output.log

ProcessBuilder.start() 返回一个 java.lang.Process,它由 Groovy 修饰。 waitForOrKill 等方法仍然有效。

关于groovy - 如何在 Groovy 中将进程的 stdout、stderr 和 stdin 重定向到文件或从文件重定向,就像在 Bash shell 中一样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28717454/

相关文章:

linux - 用于 Linux/Unix 的脚本语言的简单作业调度程序

jenkins - Groovy:读取数组中文件的内容并为某些内容进行 grep

grails - 无法启动Grail应用程序

groovy - 如何使用 SOAPUI 解压缩 GET 响应

groovy - 如何检查列表是否包含子列表

Java 编译器拒绝带有参数化内部类的变量声明

powershell - Hyper-V脚本无法识别远程虚拟机

linux - 将格式从 %Y%m%d%H%M% 更改为另一种格式

java - 使用 groovy 脚本引擎(GroovyClassLoader)运行包含新行 "\n"的 java 代码时出现 GroovyCastException

java - 在运行时将 Groovy 脚本导入另一个 Groovy 脚本