Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua
http://www.hammerspoon.org
MIT License
12.1k stars 582 forks source link

hs.task doesn't like arguments with quotes #1418

Closed latenitefilms closed 7 years ago

latenitefilms commented 7 years ago

I've been struggling to get hs.task to work properly, as it doesn't seem to like quotes or double quotes in the attribute table.

Basically, I'm trying to trigger something similar to:

/Applications/Compressor.app/Contents/MacOS/Compressor -monitor -jobid "5E0D3BF6-981C-4911-962E-DBC47F5554DD"

I'm using:

local log = require("hs.logger").new("test")
local test =  hs.task.new("/Applications/Compressor.app/Contents/MacOS/Compressor", function(exitCode, stdOut, stdErr)
    log.df("exitCode: %s", exitCode)
    log.df("stdOut: %s", stdOut)
    log.df("stdErr: %s", stdErr)
end, function(task, stdOut, stdErr)
    log.df("task: %s", task)
    log.df("stdOut: %s", stdOut)
    log.df("stdErr: %s", stdErr)
end, { "-monitor", "-jobid", [["5E0D3BF6-981C-4911-962E-DBC47F5554DD"]] } ):start()

I've also tried using single quotes, but same issue. I've also tried escaping the quotes in the string (i.e. [[\"5E0D3BF6-981C-4911-962E-DBC47F5554DD\"]]), but no dice.

Any suggestions @asmagill or @cmsj ?

Also, possibly unrelated, I occasionally get the following error:

LuaSkin: hs.task terminationHandler block encountered an exception: *** -[NSConcreteFileHandle readDataOfLength:]: Resource temporarily unavailable

latenitefilms commented 7 years ago

Also getting this occasionally:

2017-05-10 13:27:10: 13:27:10 ** Warning: LuaSkin: hs.task:launch() Unable to launch hs.task process: -[__NSCFNumber fileSystemRepresentation]: unrecognized selector sent to instance 0x337

asmagill commented 7 years ago
  1. your stream callback should return a boolean value (see help.hs.task.new), but having never used these I don't know if it's causing your problem.
  2. i can't replicate the problem... For a shell script of:
    #! /bin/bash
    echo $@

I get the following:

> hs.task.new("/path/test.sh", function(...)
    print("exit", hs.inspect(table.pack(...)))
end, function(ud, ...)
    print("stream", hs.inspect(table.pack(...)))
    return true
end, { "1", [["aBCDEF"]]}):start()

hs.task: /path/test.sh 1 "aBCDEF" (0x6080008af568)
stream  { '1 "aBCDEF"\n', "",
  n = 2
}
exit    { 0, "", "",
  n = 3
}

In the stream callback, you can see the arguments and the second one clearly includes the quotes.

latenitefilms commented 7 years ago

Legend, thanks for the fast reply @asmagill !

Unfortunately, I'm still having issues.

This is what I now have in the script:

local compressorTask =  task.new(compressorPath, function(...)
    print("exit", hs.inspect(table.pack(...)))
end, function(...)
    print("stream", hs.inspect(table.pack(...)))
    return true
end, { "-batchname", wrapInQuotes("CommandPost Watch Folder"), "-jobpath", wrapInQuotes(file), "-settingpath", wrapInQuotes(selectedFile.settingFile), "-locationpath", wrapInQuotes(selectedFile.destinationPath .. filename)  } ):start()
log.df("compressorTask: %s", compressorTask)

This is what I get in the Console:

2017-05-10 13:35:27: 13:35:27   fcpwatch:     compressorTask: hs.task: /Applications/Compressor.app/Contents/MacOS/Compressor -batchname "CommandPost Watch Folder" -jobpath "/Users/latenitechris/Desktop/Watch Folder/Watch Folder/Compressor/Blue.mov" -settingpath "/Users/latenitechris/Library/Application Support/Compressor/Settings/HD 1080p.cmprstng" -locationpath "/Users/latenitechris/Desktop/Watch Folder/Watch Folder/Compressor Renders/Blue" (0x6080008a7d08)
2017-05-10 13:35:28: -- Loading extension: inspect
2017-05-10 13:35:28: stream { <userdata 1> -- hs.task: /Applications/Compressor.app/Contents/MacOS/Compressor -batchname "CommandPost Watch Folder" -jobpath "/Users/latenitechris/Desktop/Watch Folder/Watch Folder/Compressor/Blue.mov" -settingpath "/Users/latenitechris/Library/Application Support/Compressor/Settings/HD 1080p.cmprstng" -locationpath "/Users/latenitechris/Desktop/Watch Folder/Watch Folder/Compressor Renders/Blue" (0x6080008a7d08), 'Parameter error: Invalid Job path: "/Users/latenitechris/Desktop/Watch Folder/Watch Folder/Compressor/Blue.mov"; Path does not exist\n', "",
  n = 3
}
2017-05-10 13:35:28: exit   { 255, "", "",
  n = 3
}

However if I copy and paste this from the Console:

/Applications/Compressor.app/Contents/MacOS/Compressor -batchname "CommandPost Watch Folder" -jobpath "/Users/latenitechris/Desktop/Watch Folder/Watch Folder/Compressor/Blue.mov" -settingpath "/Users/latenitechris/Library/Application Support/Compressor/Settings/HD 1080p.cmprstng" -locationpath "/Users/latenitechris/Desktop/Watch Folder/Watch Folder/Compressor Renders/Blue"

...and run it in Terminal, it works fine.

knu commented 7 years ago

I don't think you need to pass quotes in the first place. Quotes are meant to help the shell (/bin/sh) split a command line string into arguments, and NSTask just takes arguments as an array of strings, so you don't need quotation.

asmagill commented 7 years ago

He may have a point... usually quotes are included to prevent spaces from breaking up arguments but the actual script never gets them.

From my example above, if I do ./test.sh 1 "abc" from the Terminal, I see 1 abc. To get the quotes, I have to do ./test.sh 1 "\"abc\"".

asmagill commented 7 years ago

As to the exceptions, I don't know... hs.task was written by @cmsj, and while I've glanced at it a few times to review or to figure out how he solved something, I've never really studied it in depth.

latenitefilms commented 7 years ago

LEGEND! Got it in one @knu!

Yes, I was using quotes prevent spaces from breaking up arguments - but it seems with hs.task arguments you don't need to worry about it!

Maybe something to add to the documentation?

Thanks heaps @knu & @asmagill !