3

I would like to execute a shell command within a Groovy script where part of the script is variable of a filename which may contain spaces.

According to groovy execute with parameters containing spaces I may use an array for this:

def filename = '/tmp/folder with spaces'

// does not work
'ls "' + filename + '"'.execute()

// works
['ls', filename].execute()

But I can't figure out how to reformat the following command using an array where "filename" is a groovy variable containing a filename with or without spaces:

mdfind "$(/usr/libexec/PlistBuddy -c 'Print RawQuery' filename)"

This does not work:

// not working
["mdfind", "\$(/usr/libexec/PlistBuddy -c 'Print RawQuery' " + filename + ")"].execute()
["mdfind", "\$(/usr/libexec/PlistBuddy -c 'Print RawQuery' ", filename, ")"].execute()
rbuc
  • 31
  • 1
  • 3

2 Answers2

0

unless knowing what the raw output of /usr/libexec/PlistBuddy might be, it is difficult to tell how the brackets have to be placed in order to provide syntactical sense.

println([
    "mdfind",
    "/usr/libexec/PlistBuddy",
    "-c 'Print RawQuery'",
    "${filename}"
].execute().text)

See the Groovy documentation on Process Management - breaking the statement down into two statements might provide some clue, why it doesn't work as expected - while one still can formulate it into a single-line statement, once both parts do return the desired results. one can also .waitFor() process termination, before outputting the captured text; also the | operator is available there, just not within the [] bracketed command/parameter arrays... because I have the impression, that it most likely might be intended to look about like this:

def p = "mdfind".execute() | [
    "/usr/libexec/PlistBuddy",
    "-c 'Print RawQuery'",
    "${filename}"
].execute()
p.waitFor()
println p.text

I'd consider the most simple formulation: ["mdfind", "-name ${filename}"].execute()

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
0

I always run complicated shell commands using split().

Example:

def sout = new StringBuilder(), serr = new StringBuilder()
def shellCommand="" //your shell command here
Process proc = shellCommand.split().execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(100000L)
kensou
  • 11
  • 2