Currently, doShellScript
can’t be used in DT menu bar JXA scripts (it is fine in smart rule scripts, though). The handcrafted function below can be used as a replacement for menu bar scripts:
function runShellCommand(...arguments) {
const err = $();
const task = $.NSTask.alloc.init;
task.executableURL = $.NSURL.fileURLWithPath('/bin/sh');
const argumentString = arguments.join(" ");
task.arguments=['--login', '-c', argumentString];
const output = $.NSPipe.pipe;
task.standardOutput = output;
task.launchAndReturnError(err);
const readHandle = output.fileHandleForReading;
const rawResult = readHandle.readDataToEndOfFile;
const result = $.NSString.alloc.initWithDataEncoding(rawResult, $.NSUTF8StringEncoding);
return result.js;
}
The code is inspired by JXA with Require · GitHub
Call the function like so
const result = runShellCommand('cmd', 'arg1', 'arg2', 'arg3')
or
const result = runShellCommand('cmd arg1 arg2 arg3')
The arguments are passed as they are to the shell, so that runShellCommand('echo $PATH')
returns the current PATH
value. If you need to escape arguments, do so before calling runShellCommand
.
runShellCommand
is about 10% slower than doShellScript
. That is due to the --login
parameter passed to the shell. So, if you do not need the shell’s login environment, leave it out to speed things up.