如何在 Swift 中停止打印终端

How can I stop printing Terminal in Swift

我想让下面的代码适用于 Swift,代码在没有 /dev/null 2>&1 的情况下也能正常工作,只要我添加 /dev/null 2>&1,它就不起作用,我该如何添加正确吗?

let task = Process()
task.executableURL = URL(fileURLWithPath: "/bin/bash/dev/null 2>&1")
task.arguments = ["-c", """
                    echo "Hello, world!"
                    cd ${HOME}
                    cd Desktop
                    mkdir "New Folder"
                    echo "Folder is Successfully created!"
                    """]
task.launch()

这里有两个主要问题:

  1. 你想要 运行 的二进制文件的可执行文件 URL 需要指向二进制文件——它不能带参数,因为 /bin/bash/dev/null 2>&1 不是有效路径在磁盘上。如果要运行/bin/bash,可执行文件URL只能包含/bin/bash
  2. 您尝试执行的重定向也没有完全正确地写出。简要地:
      bash 中的
    • 2>&1 表示“请将 stderr (2) 指向 stdout (1) 当前指向的位置”
    • 为了首先重定向 stdout,仅仅指定 /dev/null 是不够的——你需要告诉 bash “请将 stdout 指向 /dev/null”,这是用 shorthand >/dev/null 完成的(注意前导 > 意思是“重定向”)

这些重定向的语法是实际 shell 的一部分,您 运行ning,虽然 bash 可能理解 >/dev/null,这不适用于所有进程。

您可以请求此 bash 重定向的一种方法是将重定向请求包含在您正在 运行 的 shell 脚本中(即,您传递给-c)。这开始进入 bash 的细节以及它如何处理重定向,但是一个如何实现这个的例子:

task.arguments = ["-c", """
                        exec >/dev/null 2>&1
                        # The rest of your script.
                        """]

exec 行导致 bash 影响重定向,并且它在脚本的其余部分保持活动状态。解释细节可能超出范围,但请查看 How to redirect output of an entire shell script within the script itself? 了解更多信息。

但是:

而不是这种 bash 特定的方法,一个不那么脆弱且更具表现力的方法就是在 [=39] 上显式设置 .standardOutput.standardError 属性=] 本身。您可以从 bash 外部重定向 stdoutstderr 以及以下内容:

let task = Process()
task.executableURL = URL(fileURLWithPath: "/bin/bash")
task.arguments = ["-c", "..."]
task.standardOutput = FileHandle.nullDevice // Equivalent to /dev/null
task.standardError = FileHandle.nullDevice
task.launch()

.standardInput, .standardOutput, and .standardError on a Process 帮助指导流程输入的来源和输出的去向。默认情况下,这些是 inherited 从你当前的进程(这就是为什么你甚至在你自己的输出中看到 bash 的输出开始),但你可以分配a FileHandle 将输出写入文件,或设置 a Pipe 以便能够直接读取输出。

以上重定向适用于任何进程,而不仅仅是 bash,建议您使用这些语义属性而不是依赖 bash 解析。


如果您不关心具体重定向到 /dev/null,您可以选择 关闭 进程的 stdoutstderr 通过传递在 nil 而不是 FileHandle.nullDevice:

task.standardOutput = nil
task.standardError = nil

对于这个特定的应用程序,此分配将与重定向到 /dev/null 具有相同的效果:脚本的输出将被静音。

技术上 它们之间存在差异(如果脚本正在检查其 stdoutstderr 被输出到的位置),但在最常见的用例,这将是等效的。考虑将其用作直接引用 FileHandle.nullDevice 的“简化”。