macos - 在未完成的情况下从应用程序获取标准输出
问题描述
我有这个用 shell 脚本运行的游戏。游戏在终端运行时,会主动打印“连接到服务器”或“断开连接”等信息。
const app = Application.currentApplication()
app.includeStandardAdditions = true
const terminalOutput = app.doShellScript('pathToGame');
console.log(terminalOutput);
此代码仅在应用程序停止/退出时打印出来。只打印最后一条语句。我试图找到一种方法来打印每条语句。无论是在日志文件中还是作为返回值,它都会在进程运行时打印一些内容,而无需停止/退出它。
01:21:22: Application Running
01:21:23: Request connection to "ip address"
01:21:24: Connected to server "ip address"
01:45:01: Disconnected from server "ip address"
//Here my script would detect and try to log in again
例如:我打开游戏。游戏打印“应用程序正在运行”,现在有了该值,我知道游戏已打开,我可以告诉我的脚本登录。然后,如果游戏以某种方式打印“与服务器断开连接”,我的应用程序将检测到该标准输出并将下降进入它将尝试再次登录的功能。
在应用程序仍在运行时获取标准输出是可能的吗?
解决方案
仅使用普通的 JXA 这样做是不可能的,因为这样做doShellScript
有些非常有限。
仍然可以利用 Objective-C 桥实现完整的流程执行。以下是我如何在项目中将命令作为子进程执行以获取附加的终端列。
// Import `Foundation` to be able use `NSTask`.
ObjC.import('Foundation');
// Launch `NSTask` `tput cols` to get number of cols.
const { pipe } = $.NSPipe;
const file = pipe.fileHandleForReading;
const task = $.NSTask.alloc.init;
task.launchPath = '/bin/sh';
task.arguments = ['-c', 'tput cols'];
task.standardOutput = pipe;
task.launch; // Run the task.
let data = file.readDataToEndOfFile; // Read the task's output.
file.closeFile;
// Parse the task's output.
data = $.NSString.alloc.initWithDataEncoding(data, $.NSUTF8StringEncoding);
const result = ObjC.unwrap(data); // Unwrap `NSString`.
return parseInt(result, 10);
对于您的情况,请查看https://developer.apple.com/documentation/foundation/pipe/1414352-filehandleforreading以查看有关如何从pipe.fileHandleForReading
.
以下是我的示例解决方案,尽管它尚未经过测试。
// Import `Foundation` to be able use `NSTask`.
ObjC.import('Foundation');
// Launch `NSTask`.
const { pipe } = $.NSPipe;
const file = pipe.fileHandleForReading;
const task = $.NSTask.alloc.init;
task.launchPath = '/bin/sh';
task.arguments = ['-c', 'pathToYourGame'];
task.standardOutput = pipe;
task.launch; // Run the task.
let data;
for(;;) {
data = file.availableData; // Read the task's output.
if(!data) {
file.closeFile;
break;
}
// Parse the task's output.
data = $.NSString.alloc.initWithDataEncoding(data, $.NSUTF8StringEncoding);
const result = ObjC.unwrap(data);
// Process your streaming data.
doSomething(result);
}
推荐阅读
- python-3.x - 如何获得带符号的十六进制值?
- vba - 我只想将数字从一张纸复制到另一张纸上
- python - 尝试使用在第二个类中从该类调用另一个函数的类函数时出现“AttributeError”
- spring-boot - 在 Spring Boot 中返回响应消息
- c - 我看不懂这段代码?这是正常的还是我还没准备好?
- javascript - Moment 验证仅适用于 React Native 中的某些设备
- imacros - 需要帮助 imacros 代码向 quora 上的作者请求前 25 个“回答请求”
- javascript - 将数组转换为哈希图。如何写得更好
- flutter - 在颤动中将前缀文本插入数据库
- animation - GtkDrawingArea / cairo 视觉故障