从 gjs 读取异步标准输出
read asynchronous stdout from gjs
我正在尝试 运行 来自 gjs 的命令并异步读取输出。
这是我的同步代码
let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null,
['/bin/ls'], null, 0, null);
let out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
var out = out_reader.read_until("", null);
print(out);
这很好用,但如果我尝试异步执行它,它就不起作用
let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null,
['/bin/ls'], null, 0, null);
let out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
function _SocketRead(source_object, res, user_data){
print("hi");
let length;
let out = out_reader.read_upto_finish(asyncResult, length);
print("out" + out);
print("length" + length);
}
var out = out_reader.read_upto_async("",0, 0, null, _SocketRead, "");
while(true){
i = 0;
}
回调根本没有被调用
首先感谢你提出这个问题,我也有同样的基本问题,即你的初始行“我正在尝试 运行 来自 gjs 的命令并异步读取输出”和你的问题包含我找到解决方案所需的详细信息!
在您的示例代码中,主要问题是这些行:
while(true){
i = 0;
}
您正在正确地尝试防止程序在获得输出之前终止,但此解决方案不起作用。
Javascript 是单线程的,这意味着虽然计算可以 运行 在串行交错的意义上并发,但不能有两个 Javascript 计算 运行 宁平行线。没有办法明确地产生线程,问题中的繁忙循环一直在旋转,回调永远不会获得 CPU 时间。
你想要的是进入一个事件循环。如果您正在开发 Gnome Shell 扩展,那么您已经 运行ning 了,但是如果您只是 运行ning 使用 Gjs 的脚本,则需要明确地启动一个。我将使用 Clutter,但其他一些事件循环也可以。以下代码段构成了完整的工作解决方案。
首先,让我们从导入所需的库开始:
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Clutter = imports.gi.Clutter;
然后添加问题中的产卵和文件描述符:
const [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null, ['/bin/ls'], null, 0, null);
const out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
调用异步读取函数并给它一个回调(在下面定义,由于 Javascript 提升可以在这里使用):
out_reader.read_upto_async("", 0, 0, null, _SocketRead, "");
并启动事件循环:
Clutter.init(null);
Clutter.main();
你的回调中有几个错误,所以这里有一个固定版本,一旦命令停止产生输出也会终止事件循环:
function _SocketRead(source_object, res){
const [out, length] = out_reader.read_upto_finish(res);
if (length > 0) {
print("out: " + out);
print("length: " + length);
out_reader.read_upto_async("", 0, 0, null, _SocketRead, "");
} else {
Clutter.main_quit();
}
}
如需进一步阅读,可在 https://gjs-docs.gnome.org/.
找到 Gjs 本机绑定文档
我正在尝试 运行 来自 gjs 的命令并异步读取输出。
这是我的同步代码
let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null,
['/bin/ls'], null, 0, null);
let out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
var out = out_reader.read_until("", null);
print(out);
这很好用,但如果我尝试异步执行它,它就不起作用
let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null,
['/bin/ls'], null, 0, null);
let out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
function _SocketRead(source_object, res, user_data){
print("hi");
let length;
let out = out_reader.read_upto_finish(asyncResult, length);
print("out" + out);
print("length" + length);
}
var out = out_reader.read_upto_async("",0, 0, null, _SocketRead, "");
while(true){
i = 0;
}
回调根本没有被调用
首先感谢你提出这个问题,我也有同样的基本问题,即你的初始行“我正在尝试 运行 来自 gjs 的命令并异步读取输出”和你的问题包含我找到解决方案所需的详细信息!
在您的示例代码中,主要问题是这些行:
while(true){
i = 0;
}
您正在正确地尝试防止程序在获得输出之前终止,但此解决方案不起作用。
Javascript 是单线程的,这意味着虽然计算可以 运行 在串行交错的意义上并发,但不能有两个 Javascript 计算 运行 宁平行线。没有办法明确地产生线程,问题中的繁忙循环一直在旋转,回调永远不会获得 CPU 时间。
你想要的是进入一个事件循环。如果您正在开发 Gnome Shell 扩展,那么您已经 运行ning 了,但是如果您只是 运行ning 使用 Gjs 的脚本,则需要明确地启动一个。我将使用 Clutter,但其他一些事件循环也可以。以下代码段构成了完整的工作解决方案。
首先,让我们从导入所需的库开始:
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Clutter = imports.gi.Clutter;
然后添加问题中的产卵和文件描述符:
const [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null, ['/bin/ls'], null, 0, null);
const out_reader = new Gio.DataInputStream({
base_stream: new Gio.UnixInputStream({fd: out_fd})
});
调用异步读取函数并给它一个回调(在下面定义,由于 Javascript 提升可以在这里使用):
out_reader.read_upto_async("", 0, 0, null, _SocketRead, "");
并启动事件循环:
Clutter.init(null);
Clutter.main();
你的回调中有几个错误,所以这里有一个固定版本,一旦命令停止产生输出也会终止事件循环:
function _SocketRead(source_object, res){
const [out, length] = out_reader.read_upto_finish(res);
if (length > 0) {
print("out: " + out);
print("length: " + length);
out_reader.read_upto_async("", 0, 0, null, _SocketRead, "");
} else {
Clutter.main_quit();
}
}
如需进一步阅读,可在 https://gjs-docs.gnome.org/.
找到 Gjs 本机绑定文档