• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Get output from LrTasks.execute(cmd)

Explorer ,
Jan 13, 2017 Jan 13, 2017

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 !

TOPICS
SDK

Views

1.1K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jan 13, 2017 Jan 13, 2017

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jan 13, 2017 Jan 13, 2017

Copy link to clipboard

Copied

ok, bad news... Thanks !

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 11, 2017 May 11, 2017

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 12, 2017 May 12, 2017

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 12, 2017 May 12, 2017

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
May 14, 2017 May 14, 2017

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)?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 17, 2017 May 17, 2017

Copy link to clipboard

Copied

LATEST

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines