在未完成的情况下从应用程序获取stdout



我用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

例如:我打开游戏。游戏打印"应用程序正在运行",现在有了这个值,我知道游戏是打开的,我可以告诉我的脚本登录。然后,如果游戏打印"与服务器断开连接",我的应用程序将检测到stdout,并将进入一个尝试再次登录的功能。

在应用程序仍在运行时获取stdout是否可行?

仅使用普通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查看有关如何从CCD_ 2接收数据的文档。

以下是我的示例解决方案,尽管它还没有经过测试。

// 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);
}

最新更新