I am writing a Firefox extension using the Addon SDK that needs to launch a bash script and then read its output from a file it creates in the current directory as follows:
echo "bash script output" >file.txt
I am launching the bash script as follows in my main.js:
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;
}
My question is how do I find out programatically, from within main.js, where file.txt will be stored when the script echoes to it? So what's the current working directory of the launched process? And is there anyway to retrieve it or change it?
The documentation on nsIProcess online doesn't mention anything about this.
I have determined (by searching the FS) where file.txt ends up when running the extension using cfx run, and when running it in Firefox after installing it as an XPI. But I would like to determine this info at startup and maybe even control where it ends up being stored.
This is a limitation of nsIProcess
- it will always execute applications using the application-wide current directory. You can get this directory using nsIDirectoryServiceProvider
interface:
var currDir = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIDirectoryServiceProvider)
.getFile("CurWorkD", {}).path;
The issue in your case is still that this directory will usually not be writable. While you could change this directory via js-ctypes, this is definitely not advisable - you might break other code that relies on the current directory not changing. The alternative is to let bash change the current directory before executing the script:
var args = ["-c", "cd /tmp && . " + scriptFile.replace(/\W/g, "\\$&")];
Note that the replace()
part is important to escape all unusual characters - otherwise parts of the file name might get interpreted as an additional command.