Page 1 of 1

Advice on implementing a long shell script

Posted: Fri Nov 02, 2012 6:18 pm
by nextyoyoma
I am writing an app to partition a hard drive into multiple parts. I will use a shell command to do this, but the command can take some time to complete. Also, I would like the user to be able to see the output from the command in case there is a problem. What is the best approach to this?

I was planning on running the shell command in the background and redirecting all output to a file, then creating a new sub-stack that would poll the file and display it to the user until the command is complete. The substack would have one card with one field. The card's script is below.

Code: Select all

on openstack
   put empty into field "field"
   repeat until the endRepeat with messages
      put url "binfile:/Users/cpatton/Desktop/baz.log" into field "field"
      put shell("ps -axo comm | awk '/[a]sr/{print}'") into isitrunning
      if isitrunning contains "asr" then
      else 
        send "endRepeat" to this card
      end if
      wait 0 milliseconds with messages
   end repeat
end openstack

on endRepeat
   put "ASR complete." after field "field"
end endRepeat
This approach may be completely wrong, but if it is not, the problem I am having is that I can't figure out how to break out of the repeat. I thought sending that message would signal the repeat to stop, but apparently not.

Any advice on how to proceed would be appreciated.

Re: Advice on implementing a long shell script

Posted: Fri Nov 02, 2012 7:15 pm
by sturgis
There are a couple options here. First thing to note is that shell is blocking. So if you are running a really long shell script, nothing else can or will occur until it is done. (if i'm mistaken, someone correct me)

Now, if you're running the shell script from a terminal and just want to check your log file from LC that should be easy enough to implement. If you want a more interactive/non-blocking approach to run your script from within livecode, you might look at "open process" alternatively could probably break up your long shell script and run each part of it one at a time using shell (meaning forget a script file, do each individual line from within lc using shell() then update your log after each step completes)

open process is probably the easiest.

As for exiting repeats you can use 'exit repeat'

repeat until condition
if some other condition we want to break on then
exit repeat
end if

end repeat

During development I usually put a line like

if the shiftkey is down then exit repeat
so that I just have to hold shift until the next loop and it will exit.

If you go with open process instead of shell you'll need to set up a read loop

Something like..

Code: Select all

command readloop
if conditionthatmeanskeeplooping then
   read from myprocess until empty
   -- could put a check to see if the process is done here, if so change the condition
   
   put it after field "log"
   send readLoop to me in 1 tick
  
end if
end readloop

If you'd rather just redirect output to a file like you mentioned and then poll the file you can open process "/path/to/executable" for neither -- neither meaning no input or output just launch it.
At which point you'll still need some type of loop to check the file contents for change. Repeat or a send in time loop should be fine.

Re: Advice on implementing a long shell script

Posted: Fri Nov 02, 2012 7:55 pm
by nextyoyoma
sturgis wrote:Now, if you're running the shell script from a terminal and just want to check your log file from LC that should be easy enough to implement. If you want a more interactive/non-blocking approach to run your script from within livecode, you might look at "open process" alternatively could probably break up your long shell script and run each part of it one at a time using shell (meaning forget a script file, do each individual line from within lc using shell() then update your log after each step completes)
The dictionary says you can't use open process for unix executables. Does it actually work?

Also, my shell command is only one line, but it takes some time to complete. Running it in the background, however, allows the script to run in the background. This means I can't get any output from it directly into LC, but that isn't too much of a problem.

Re: Advice on implementing a long shell script

Posted: Fri Nov 02, 2012 8:37 pm
by sturgis
Nope, doesn't work, was thinking you were on linux for some reason. *doh*

Well if its a script file you can probably use launch. Make sure the script is executable and that you have rights to it then

launch "/path/to/script"

For a quick test I just put

#!/bin/bash
find . >~/test.log

into a script file, launched it and yep works fine without the shell() lockout. Easy at that point to read the test.log file as you planned anyway.

If you're going to do a loop you can do a send or repeat, with a flag or check for process completion with ps. If the process is gone set the flag so that repeat exits. Same thing with send in time.