Shell Script & progressIndicator - AppleScript - xcode

What I have is an applescript app in xcode that runs a shell script. What I was hoping to do is have the progressIndicator move a certain amount when the command is "echo hello world" as an example but since all of my commands are sudo I have to put them in a shell script together and I can't just have the progressIndicator move in between commands (there are lots of them.) Is there a way to have the bar move when a certain command is started? Also, is there a way to output the log of the applescript to a textView in xcode?

You can always run the command line tool "ps" to see which processes are currently running. As such you can formulate a repeat loop and using ps can figure out which of your commands are currently running... and thus increment your progress indicator as needed.
Here's a ps command I've used to get a nice listing. You can combine this with grep to filter for your processes...
/bin/ps -Axcro user,pid,%cpu,command

Related

Blocking a bash script running with &

I may have inadvertently launched a bash script containing an infinite cycle whose exit condition may be met next century, if ever. The fact is that I launched the script, as I would do with a nohup program, with
bash [scriptname].sh &
so that (as I get it, which is most probably wrong) I can close the terminal and still keep the script running, as was my intention in developing it. The script should run calculation programmes in my absence and let me gather the results after some time.
Now I want to stop it, but nothing seems to do the trick: I killed the programmes the script had launched, I removed the input file the script was getting orders from and - last and most perfect of accomplishments - I accidentally closed the terminal trying to "exit" the script, which was still giving me error messages.
How can I check whether the script is running (as it does not appear in "top")? Is the '&' relevant? Should I just ask permission to reboot the pc, if that will work and kill everything?
Thank you.
[I put a "Hi everyone" at the beginning but the editor won't let me show it. Oh, well. It's that kind of day.]
Ok, I'll put it right here to prove my stupidity, as I wandered the internet shortly (after a long wandering before writing this post) and found that the line:
kill -9 $(pgrep -f [SCRIPTNAME].sh)
does the trick from any terminal window.
I write this answer to help anyone in the same situation, but feel free to remove the thread if unnecessary (and excuse me for disturbing).
Good you found it, here is another way if you do not use bash -c and run it in current shell not a separate shell.
# put a job in background
sleep 100 &
# save the last PID of background job
MY_PID=$!
# later
kill $MY_PID

Wait for PID to exit using AppleScript

I'm new to AppleScript but I have to recreate a batch file which I have written for Windows in OSX and AppleScript seems the best way to do this. Basically, the script will created by another program dynamically and then executed. The AppleScript simply needs to wait for a process, which I want to identify by its process ID, and display a message if the process is still running after a specific amount of time.
Is this possible, and if so, how?
Thanks in advance
I eventually found a solution to my given problem after searching online a bit more. Here is the AppleScript code I use to check if a process with a given id pid is running
tell application "System Events"
set runningApplications to (unix id of every process)
if (runningApplications contains (pid as integer)) is false then
-- process is not running
else
-- process still running
end if
end tell
This is just a snippet obviously. Personally I have the above the statement in a repeat loop, but this offers a solution to checking a process id (which is the unix id).
Hope this helps others
Here are some things to (hopefully) get you on your way:
shell scripts in terminal, and 'do shell script' command: don't know how well you know Unix, but you definitely want to go there, and
learn basics of bash. with some limitations, you can run shell
scripts via AS through the 'do shell script' command.
writing the script dynamically: osascript and osacompile will probably come in handy. see the man pages. osascript can execute
scripts or script text, and osacompile can (!) compile text into
script form (non-text form), among other things.
script waiting for/watching process: more shell script stuff, or using the Finder (what used to be called the Scriptable Finder!),
that is, the Finder's scripting capabilities (dictionary), like
tell application "Finder" to get name of processes. The shell version (which can be called via the 'do shell script' AS command)
might be "ps ax | grep Safari | grep -v grep | awk '{print $1}'" (taken from
stackoverflow post. I like it because it returns empty string if no
match). Depending on how your main script will run, learn how the
idle handler works in a script application, and how that differs from
using an xcode-built app (if that's the route you go), or just a
script.
displaying a message: 'display dialog' is the super simple method, complete with timeout ("gives up" after n seconds). (Sorry if this is
so basic I just insulted your intelligence :-) )
other: Check out (unless you're already wedded to a script editing environment) Smile. It's my primary script editor.

Combining two scripts in applescript

I'm a complete newbie to applescript and my new external backup HDD made it necessary for me to work with it. As it is quite noisy I wanted to write a script that mounts the disk (if it is unmounted), runs the backup and then ejects the backup disk again (Code A). So far so good. In order to eject the disk after backup has finished I found a piece of code to check if a process is still running (Code B). It returns 1 if the backup process (backupd) is still alive and 0 if it is finished.
I am struggling now with combining those two pieces. I would like code B to keep checking after the backup has started if backupd is still running and if it is done go to the next step and eject the disk.
I just can't get code B running in code A and also the needed loop confuses me a bit. Any help is really greatly appreciated!! I can't imagine it's that tricky just too much for my imagination Thanks for helping me restoring peace and quietness
Code A:
set myVolumeLabel to "Time Machine"
tell application "Finder"
set diskDev to do shell script "diskutil list | grep \"" & myVolumeLabel & "\" | grep -o > 'disk[0-9]*' "
if not (disk myVolumeLabel exists) then
do shell script "diskutil mountDisk " & diskDev
do shell script "/System/Library/CoreServices/backupd.bundle/Contents/Resources/backupd-> helper >/dev/null 2>&1 &"
(* Checking if the backupd process is still running should go here I suppose.*)
else
do shell script "diskutil eject /Volumes/'Time Machine' " & diskDev
end if
end tell
Code B
on check_process(marker)
set the_processes to (do shell script "ps -A")
return (the_processes contains marker)
end check_process
if check_process("/backupd") then
set x to "1"
else
set x to "0"
end if
---display dialog x buttons {"OK"} default button 1
Mac OS X (10.6.8)
It seems to me that what you want to do is rather low-level kind of "system stuff" and that more of the code should be done in the shell.
I'm learning both AppleScript and Unix shell-scripting (the bash shell to be precise, which is the default shell in OS X).
Most of your AppleScript here is really mostly shell scripts inside of AppleScript.
It seems like in this case, the right tool for the right job is a shell script.
You may not want to learn a whole 'nother programming language right now, so I'll give you a couple of thoughts.
If you end a shell-command with an ampersand "&" inside of the quotation marks, then AppleScript will NOT wait for the shell script to complete but rather it will return immediately, putting the process on a separate thread and will return a process id.
If you don't terminate a shell-command with an ampersand, then AppleScript will wait for the command to finish before proceeding.
You can try the following experiment. Type in the following command into Terminal.app:
sleep 10
It will take 10 seconds before you get control back in Terminal.
If you type the following command,
sleep 10&
You will get control back immediately and will get a process id back to refer to the process which you have started.
Well, again, it seems to me that the whole script is best written as a bash script, possibly using a little bit of Automator or AppleScript to kick things off.
Mac shell (bash) tutorial:
http://tidbits.com/article/7003
-- Kaydell
Let me be your guide

View output or progress of shell script when run in AppleScript

I'm working on a simple AppleScript that runs the following...
do shell script "diskutil partitionDisk /dev/disk1 1 APM JHFS+ Test 1G"
It's part of a bigger script. The above works fine but is there a way of viewing the progress? Anything will do really, preferably the actual command within a terminal window would be good.
Thanks
I often have the need for seeing the progress of do shell script commands and other various stages of an AppleScript script while it is running. What I do for do shell script is log the output to a log file and then use a program called MKConsole to display it on the Desktop. For example:
do shell script "diskutil verifyPermissions // &> /output.log"
In the above command diskutil will start up and start running and log standard output to the log file I created called output.log located at /. It won't show you the 0%...10%...20% progress indicator that you see in the Terminal but it does show you all the other output.
Then I configure MKConsole's preferences to read this log file and then in real time it will display all new log messages from that file on my Desktop.
If you need progress of non-shell script commands and need to log AppleScript activity then you can use the logger command. For example:
do shell script "logger -f /output.log The current count is: " & some_variable
If you have an AppleScript which runs for a long time and uses repeat loops and you'd like to know what stage of completion the script is in while running then
the above logger command is a great method for getting some feedback on the progress. I usually throw in a logger command right at the bottom of the script above the end repeat so that it is the last thing it does in that iteration of the loop.
The logger command method works well with MKConsole as well so that you can see the output in real time on your Desktop.
Invoke a terminal and have the terminal run diskutil:
"xterm -e 'diskutil partitionDisk /dev/disk1 1 APM JHFS+ Test 1G'"
is the commandline to pass to the shell, and have xterm(1) display the diskutil output. Other terminals(than xterm) can be used, and the window size font, and colors can be controlled: see the manual page for the terminal.
Maybe another way to show progress would be to run the entire script(not just the diskutil part) in a window.

bash script doesnt run correctly as background process

I have bash script which works well but when I send it back with nohup script &
and close my terminal session then it's not working correctly. It only works well within my terminal session open.
What could be possible reasons which affects my script run not correctly without my terminal session? Could it be one of the terminal variables or something?
solaris 10
call:
script &
disown $!
& launches your script in the background and disown $! detaches last executed command from the current shell. $! is the PID of the last background executed command.
Without the source we can only make guesses. However, your usecase might be a good fit for using GNU Screen: http://www.gnu.org/software/screen/ You can detach shell sessions from your current login and pick them up later on.
In my humble opinion one of the most useful programs on earth ;)

Resources