Seashells is a service that will pipe the output of this python script to a web URL, which it generates randomly. I need to capture that URL later in the Macro. If I run this command in the Terminal and append 2> test.txt then it writes the URL to that file perfectly.
Are the paths to python and seashells included in your KM ENV_PATH variable? You could test with a shell script action, eg:
If that doesn't display the correct path then either edit ENV_PATH appropriately or include the full path in your shell script. Especially important if you are using python virtual environments -- you may have included those in your Terminal PATH or have explicitly sourced then earlier in the session, but the KM action has its own environment and knows nothing about them until they are explicitly included.
And check that you are passing the KM variables in to the shell script -- click the down-arrow next to the text area and make sure either "All Variables" or both fileToMoveFinal and fileName are checked.
Make sure that "Failure aborts macro" is unchecked as well.
For troubleshooting, try using "Display results in a window" rather than saving to a variable -- and make sure Notifications are allowed!
Seashells is thankfully found with "which seashells" but I've hardcoded it just in case.
The Python part works perfectly. The file begins uploading in the background, but no matter what combination of 2>&1 I use, nothing goes to the variable.
It's not a big deal to use a file, I'm just more curious about what I don't understand. If someone has resources to point me to, I'd love to read them.
I did some more reading and I think I understand that when I use 2> to go to a file, then it's just grabbing the stderr right away, but 2>&1 is trying to merge the stderr into the stdout and therefore waiting for stdout to finish which it takes a long time to do, therefore nothing is getting written to the variable.
So I think my question is, is there some bash wizardry that can ONLY grab stderr as soon as it's available and send it to KM?
By using the Execute Shell Script action, you are limited to the features of that action, which may be a limiting factor in this case. I'm not sure.
However if you want to think outside the box, you could run the command inside a Terminal window, and then, by polling the window using "Select All" and "Copy", you can check for any error results even before the command finishes. This approach should work fine.
I don't know if this is "as soon as it's available" or if it still waits for seashells to complete, but you can redirect stderr to stdout but suppress the utility's actual stdout with
But remember that you're looking at layers here. Regardless of when the error message is written out and whether or not KM saves that value to the variable then or after seashells has finished, your macro doesn't move on to the next action until the "Execute Shell Script" action has itself completed -- and that's after seashells is done.
If you can't wait for that then you'll need to set the action to "Asynchronously", and that means you can't save the results to a variable! So you'll have write to a file, and your macro will have to "Pause Until..." that file has been written to.
In the main method of seashell.py first action after checking parameters is getting uri from server, write it to stderr and flush, what means the it is immediate visible on stdout of seashell, but as @Nige_S wrote, the result will be visible in variable after finishing all processes in pipeline.
How big is the result of first process in pipe? Maybe the part of output was overwritten? Seashell has option -q, which transfer output to the web, but not to stdout of seashell. Check what will you see if you set this option.
The purpose of all this is to initiate a file upload to Dropbox on a headless server, using a command line Dropbox client. The Python script reads the progress from the program and writes some additional data, like this:
So it can take as long as an hour. Seashells pipes that to a random HTML url so I can monitor the progress remotely.
The python writes to sdtout like this: sys.stdout.write(full_line_to_print)
I got it working. I run Macro 2 from Macro 1 right before Macro 1 runs the shell script, saves the stderr to the file, then Macro 2 waits for the file to appear and sends me the URL. Macro 1 keeps going and I can cancel the transfer by aborting the Macro if need be.
I came into this process with the mental model that I wouldn't need a temp file, but now I mostly understand why. My weird use case and KM's noninteractive shell opens up a whole can of worms.