如何获取/设置nsIProcess runAsync()的工作目录

时间:2012-08-14 16:30:17

标签: firefox-addon firefox-addon-sdk

我正在使用Addon SDK编写Firefox扩展,该扩展需要启动bash脚本,然后从当前目录中创建的文件中读取其输出,如下所示:

echo "bash script output" >file.txt

我在main.js中按如下方式启动bash脚本:

function runBashScript(scriptFile) {
    var localFile = Cc["@mozilla.org/file/local;1"]
        .createInstance(Ci.nsILocalFile)
    localFile.initWithPath('/bin/bash');

    var process = Cc["@mozilla.org/process/util;1"]
        .createInstance(Ci.nsIProcess);
    process.init(localFile);

    var args = [ scriptFile ];
    var rc = process.runAsync(args, args.length, 
        function(subject, topic, data) {
            console.log('subject=' + subject + ', topic=' + topic + ', data=' + data);
            console.log('bash script finished executing, returned ' + process.exitValue);
    });

    return rc;
}

我的问题是如何以编程方式从main.js中找到文件,当脚本回显时会存储file.txt?那么启动过程的当前工作目录是什么?无论如何要检索它或改变它?

nsIProcess在线的文档并未提及此事。

我已经确定(通过搜索FS)使用cfx run运行扩展时file.txt结束的位置,以及在将其作为XPI安装后在Firefox中运行时。但我想在启动时确定这些信息,甚至可以控制最终存储的位置。

3 个答案:

答案 0 :(得分:2)

这是nsIProcess的限制 - 它将始终使用应用程序范围的当前目录执行应用程序。您可以使用nsIDirectoryServiceProvider interface获取此目录:

var currDir = Cc["@mozilla.org/file/directory_service;1"]
                .getService(Ci.nsIDirectoryServiceProvider)
                .getFile("CurWorkD", {}).path;

在您的情况下,问题仍然是该目录通常不可写。虽然您可以通过js-ctypes更改此目录,但这绝对不可取 - 您可能会破坏依赖于当前目录不会更改的其他代码。另一种方法是让bash在执行脚本之前更改当前目录:

var args = ["-c", "cd /tmp && . " + scriptFile.replace(/\W/g, "\\$&")];

请注意,replace()部分对于转义所有异常字符非常重要 - 否则文件名的某些部分可能会被解释为附加命令。

答案 1 :(得分:0)

open open提供文件的路径。如果未能提供完整路径,则默认为运行该命令的进程的当前工作目录。进程可以使用系统调用来更改其当前工作目录,因此它在启动时的位置可能在以后不同。如果您关心文件的位置,则应指定完整路径。

要将文件写入Unix / Linux上的临时目录,请执行以下操作:

echo "bash script output" >/tmp/file.txt

您不应该将文件写入例如用户的主目录,因为它可能会覆盖同名的其他文件。

答案 2 :(得分:0)

现在有subprocess,允许您这样做。