You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Mac OS X的Xcode中创建可管道使用的命令行工具?

没问题!我来一步步教你在Mac的Xcode里创建能直接通过管道「|」接收输入的命令行工具——核心其实就是让你的程序能读取标准输入(stdin),而不是只依赖命令行参数。下面是具体操作步骤:

第一步:在Xcode创建命令行工具项目
  1. 打开Xcode,点击「Create a new Xcode project」
  2. 在模板列表里选「Command Line Tool」(位于macOS > Application分类下)
  3. 填写项目名称(比如MyPipeTool),选择你熟悉的语言(Swift、C、Objective-C都可以,这里以Swift为例),然后点击「Create」
第二步:编写读取stdin的核心代码

管道传递的内容会直接进入程序的标准输入,所以我们只需要读取stdin的内容,处理后再输出到标准输出(stdout)即可。

Swift 示例代码

替换默认的main.swift内容为:

import Foundation

// 读取管道传来的所有输入内容
let inputData = FileHandle.standardInput.readDataToEndOfFile()

// 将二进制数据转成UTF-8字符串
if let inputString = String(data: inputData, encoding: .utf8) {
    // 这里写你的业务逻辑,比如把输入内容转为大写
    let processedContent = inputString.uppercased()
    // 输出处理后的内容到标准输出(可以继续通过管道传递给其他工具)
    print(processedContent)
} else {
    print("错误:无法解析输入内容")
}

C 语言示例代码

如果用C语言,替换main.c内容为:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char * argv[]) {
    char buffer[1024];
    // 逐行读取标准输入,直到遇到EOF(管道内容传递结束时会触发)
    while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
        // 这里写处理逻辑,比如输出每行内容的前缀
        printf("处理后:%s", buffer);
    }
    return EXIT_SUCCESS;
}
第三步:编译并测试工具
  1. Cmd+B编译项目,编译成功后,在左侧导航栏的「Products」文件夹里找到你的工具(比如MyPipeTool
  2. 右键点击工具,选择「Show in Finder」,找到可执行文件的路径
  3. 为了方便全局调用,你可以把这个可执行文件复制到/usr/local/bin目录(需要管理员权限,用sudo cp MyPipeTool /usr/local/bin
  4. 现在就可以用管道测试了:
    # 测试Swift示例:输入小写字符串,输出大写
    echo "hello pipe tool" | MyPipeTool
    # 输出应该是:HELLO PIPE TOOL
    
    # 测试C示例:读取文件内容并添加前缀
    cat test.txt | MyPipeTool
    
额外技巧:实时流处理(可选)

如果你的工具需要实时处理输入(比如逐行读取并立即输出,而不是等全部内容传完),可以用Swift的readabilityHandler实现:

import Foundation

let stdin = FileHandle.standardInput
// 设置实时读取回调
stdin.readabilityHandler = { handle in
    let data = handle.readData(ofLength: 1024)
    if let input = String(data: data, encoding: .utf8) {
        // 实时处理每行输入
        input.split(separator: "\n").forEach { line in
            print("实时输出:\(line)")
        }
    }
}

// 保持程序运行,等待输入
RunLoop.main.run()

这样你可以在终端输入内容,每敲一次回车就会立即得到处理结果。

和xargs的区别补充

你提到的xargs是把标准输入的内容转换成命令行参数,传递给其他工具;而我们自己写的工具是直接读取标准输入,不需要中转,比如:

  • 用xargs的方式:cat file.txt | xargs my-tool(my-tool接收的是file.txt里的内容作为参数)
  • 我们写的工具:cat file.txt | my-tool(my-tool直接读取file.txt的内容作为输入)

内容的提问来源于stack exchange,提问作者deek5

火山引擎 最新活动