Calling Shell Script with JavaScript for Automation
Asked Answered
C

2

6

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.

Craddock answered 20/1, 2015 at 11:55 Comment(3)
Maybe this helps you out: #27587194Punkie
I'd recommend looking into Cocoa's NSTask as it's much more robust and capable than do shell script.Euhemerize
Similar question: #48201673Inquest
P
6

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'")
Punkie answered 20/1, 2015 at 14:47 Comment(0)
M
2

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)

Mclin answered 17/10, 2015 at 15:12 Comment(1)
Thanks, @BallpointBen - I've added your suggestion to the bottom of the answer, with some minor additions.Mclin

© 2022 - 2024 — McMap. All rights reserved.