sverrejoh
sverrejoh

Reputation: 16840

Calling Shell Script with JavaScript for Automation

Using AppleScript I can call a shell script with:

do shell script "echo 'Foo & Bar'"

But I can't find a way to do this with JavaScript in the Yosemite Script Editor.

Upvotes: 6

Views: 2973

Answers (2)

mklement0
mklement0

Reputation: 437080

To complement ShooTerKo's helpful answer:

When calling the shell, properly quoting arguments embedded in the command is important:

To that end, AppleScript provides quoted form of for safely using variable values as arguments in a shell command, without fear of having the values altered by the shell or breaking the command altogether.

Curiously, as of OSX 10.11, there appears to be no JXA equivalent of quoted form of, but, it's easy to implement one's own (credit goes to this comment on another answer and calum_b's later correction):

// This is the JS equivalent of AppleScript's `quoted form of`
function quotedForm(s) { return "'" + s.replace(/'/g, "'\\''") + "'" }

From what I can tell, this does exactly what AppleScript's quoted form of does.

It encloses the argument in single-quotes, which protects it from shell expansions; since single-quoted shell strings don't support escaping embedded single-quotes, an input string with single-quotes is broken into multiple, single-quoted substrings, with the embedded single-quotes spliced in via \', which the shell then reassembles into a single literal.

Example:

var app = Application.currentApplication(); app.includeStandardAdditions = true

function quotedForm(s) { return "'" + s.replace(/'/g, "'\\''") + "'" }

// Construct value with spaces, a single quote, and other shell metacharacters
// (those that must be quoted to be taken literally).
var arg = "I'm a value that needs quoting - |&;()<>"

// This should echo arg unmodified, thanks to quotedForm();
// It is the equivalent of AppleScript `do shell script "echo " & quoted form of arg`:
console.log(app.doShellScript("echo " + quotedForm(arg)))

Alternatively, if your JXA script happens to load a custom AppleScript library anyway, BallpointBen suggests doing the following (lightly edited):

If you have an AppleScript library you reference in JS using var lib = Library("lib"), you may wish to add

on quotedFormOf(s)
  return quoted form of s
end quotedFormOf 

to this library.
This will make the AppleScript implementation of quoted form of available everywhere, as lib.quotedFormOf(s)

Upvotes: 2

ShooTerKo
ShooTerKo

Reputation: 2282

do shell script is part of the Standard Scripting Additions, so something like this should work:

app = Application.currentApplication()
app.includeStandardAdditions = true
app.doShellScript("echo 'Foo & Bar'")

Upvotes: 6

Related Questions