Copy link to clipboard
Copied
I would like to know if there is a way to get the output of a LrTasks.execute(cmd) call, without piping it to an external text file and reading it back ?
Many thanks !
Copy link to clipboard
Copied
Including output redirection to a temp file in the command line is the only documented way of capturing the output. There is the undocumented LrRemoteCommunication which appears to start a task with pipes for reading and writing, but I haven't seen any reports of anyone figuring out how that works.
Here is the utility function I used for running commands:
--[[----------------------------------------------------------------------------
public int exitCode, string output, string errOutput
safeExecute (string commandLine [, boolean getOutput])
Executes the command line "commandLine"in the platform shell via
LrTasks.execute, working around a bug in execute() on Windows where quoted
program names aren't accepted.
If "getOutput" is true, "output" will contain standard out and standard
error and "errOutput" will be "". If "getOutput" is "separate", then
"output" will contain standard out and "errOutput" will contain standard
error. If "getOutput" is false, then both "output" and "errOutput" will be
"".
Returns in "exitCode" the exit code of the command line. If any errors
occur in safeExecute itself, "exitCode" will be -1, and "output" and
"errOutput" will be:
getOuptut == "separate": "", <error message>
otherwise: <error message>, ""
------------------------------------------------------------------------------]]
function Util.safeExecute (commandLine, getOutput)
return LrFunctionContext.callWithContext ("", function (context)
local outFile, errFile
context:addCleanupHandler (function ()
if outFile then LrFileUtils.delete (outFile) end
if errFile then LrFileUtils.delete (errFile) end
end)
if getOutput then
local uuid = LrUUID.generateUUID ()
outFile = child (getStandardFilePath ("temp"), uuid .. ".out")
commandLine = commandLine .. ' > "' .. outFile .. '"'
if getOutput == "separate" then
errFile = child (getStandardFilePath ("temp"), uuid .. ".err")
commandLine = commandLine .. ' 2>"' .. errFile .. '"'
else
commandLine = commandLine .. ' 2>&1'
end
end
if WIN_ENV then commandLine = '"' .. commandLine .. '"' end
local exitStatus = LrTasks.execute (commandLine)
local output, errOutput, success = "", ""
local function outputErr (file, output)
local err = string.format ("Couldn't read output:\n%s\n%s",
file, output)
if getOutput == "separate" then
return -1, "", err
else
return -1, err, ""
end
end
if outFile then
success, output = pcall (LrFileUtils.readFile, outFile)
if not success then return outputErr (outFile, output) end
end
if errFile then
success, errOutput = pcall (LrFileUtils.readFile, errFile)
if not success then return outputErr (errFile, errOutput) end
end
return exitStatus, output, errOutput
end) end
Copy link to clipboard
Copied
ok, bad news... Thanks !
Copy link to clipboard
Copied
Ji John,
The problem with that is for example LrUUID seems to be unavailable for some version of Windows and Lr.
Do you have any idea until wich version of Lr your solution is working?
I'm using io.popen instead currently, but it does not work on Lightroom 4 which is a bit sad, as I don't perform amazing function with it.
For example, I just try to perform a uname to know if the OS is Mac or not and perform an unzip as well.
Do you have any clue?
Copy link to clipboard
Copied
The problem with that is for example LrUUID seems to be unavailable for some version of Windows and Lr.
LrUUID is available in LR 6 and LR 5 (OS X and Windows 10). It is also available in LR 4 (OS X). I haven't tested other combinations. Which combination of LR and Windows have you observed that doesn't have LrUUID?
It's easy enough to make an adequate replacement for LrUUID.generateUUID(). Append the string versions of these three values:
- require "Info".LrToolkitIdentifier
- LrDate.currentTime ()
- a global incrementing counter
This will give an ID that's unique across all plugins executing in that instance of LR.
Copy link to clipboard
Copied
I just try to perform a uname to know if the OS is Mac or not and perform an unzip as well.
If all you want to know is whether the current instance of LR is running on Mac or Windows, use the global variables MAC_ENV or WIN_ENV, e.g.
if MAC_ENV then ... else ... end
Copy link to clipboard
Copied
Thanks John,
Yes I changed it with these global variables. I didn't know them before (I should read all the documentation.. 😉 )
LR4 and Windows seems to not working, but not sure.. But yes, you're right it's very easy to perform a "fake" UUID.
My most concerned problem was that the io.popen was not working on LR 4 even if the action I was trying to perform should be possible in this environment.
I'll try to use your method. Did you see any performance issue or combination that result to a bug? Or it is working in all version (after LR 3)?
Copy link to clipboard
Copied
I haven't observed any performance issues with Util.safeExecute() in LR 4. I no longer test my existing plugins with LR 4, so I might not have noticed particular problems, but I haven't received any customer reports either.
In general, my newer plugins require LR 5.7 or LR 6.0, typically because they use SDK features not available in LR 4. Since LR 5 was released 5 years ago, there's not a big incentive for me to support LR 4.