AppleScript Runner exit status passed back to shell script - macos

I need to be able to run AppleScript in a shell script. I am using "AppleScript Runner" in order to be in interactive mode, so that dialogs etc. are supported. I've got it working, but I need to get the exit status of the AppleScript Runner app back to the shell, so I can see if there were any errors in the script.
Here is my shell script:
output=$(/usr/bin/osascript << EOT
tell application "AppleScript Runner"
do script "somescript.scpt"
end
EOT)
status=$?
Here my variable $status only ends up with the exit status of the osascript command (which will be 0 whether or not somescript.scpt actually ran successfully), and not the exit status of the app AppleScript Runner.
Does any one know how I might accomplish this?
Thanks!

The -e flag prints errors to stderr and is the default. So you just need to read stderr.
This answer might help you if you aren't familiar with that:
bash variable capture stderr and stdout separately or get exit value
EDIT: Added sample code.
error=`osascript -e 'tell app "Finder" to adtivate' 2>&1`
echo $error
The above on my system captures the error messages.

Related

How to use result from a script shell with applescript?

I'm trying to run a simple code from applescript.
It use blueutil, a command-line utility that can query Bluetooth’s status (on or off) / turn it on / turn it off.
I try this code from rob cottingham:
tell application “Terminal”
do shell script “/usr/local/bin/blueutil status”
set _Result tothe result
if _Result is “Status: on” then
do shell script “/usr/local/bin/blueutil off”
endif
if _Result is “Status: off” then
do shell script “/usr/local/bin/blueutil on”
endif
endtell
Without success.
If i clean all and only keep the lines about turning off or on, it works though.
Cleanest code I seems to get is:
tell application "Terminal"
do shell script "/usr/local/bin/blueutil status"
set theResult to the result
if "result" is "Status: on" then
do shell script "/usr/local/bin/blueutil off"
end if
end tell
But still doesn't work.
Maybe it's about using the result of the query as a variable?
I'm really not a professional it as you probably guessed, so any help will be appreciated !
Thanks,
Christophe.
First of all you don't need Terminal.app at all.
Second of all there is no argument status, to get the power state write:
set powerStatus to do shell script "/usr/local/bin/blueutil -p" as boolean
The result is true or false.
To toggle the power state write:
do shell script "/usr/local/bin/blueutil -p toggle"
To set the power state to on:
do shell script "/usr/local/bin/blueutil -p on"
To set the power state to off:
do shell script "/usr/local/bin/blueutil -p off"
Yes, it's just one line respectively.
And you can get the help message showing the man page.
set helpText to do shell script "/usr/local/bin/blueutil -h"

Redirect an executable's stdout/stderr but not invocation-time errors from the shell

I have a simple bash script that launches an executable in the background and redirects stdout + stderr to a log file:
#!/usr/bin/bash
myexec >& logfile &
It works. However, output from myexec isn't the only thing that gets redirected: any messages that bash emits while attempting to invoke myexec are also going to logfile. To wit, if bash doesn't find myexec, I don't get to see the myexec: No such file or directory error because it went straight to logfile instead of to the terminal. This behavior annoys me because I end up not knowing whether the script succeeded in starting up myexec.
It occurs to me that the script could just test for the existence of myexec before trying to invoke it, but I'm wondering whether there isn't a way to do the redirection itself in such a way that only myexec's output, and not the shell's, gets redirected.
It's not possible to separate the outputs in the way the OP describes. As Charles Duffy explains in his comment, the system call that opens (or fails to open) the executable myexec takes place after Bash has forked a new process, at which point all of the I/O redirection has already been set up. There is, however, a workaround that suffices for the purpose stated in the OP, namely, "knowing whether the script succeeded in starting up myexec":
myexec > logfile 2>&1 && echo "ok" >&2 || echo "nope." >&2

Exiting a shell script with an error

basically I have written a shell script for a homework assignment that works fine however I am having issues with exiting. Essentially the script reads numbers from the user until it reads a negative number and then does some output. I have the script set to exit and output an error code when it receives anything but a number and that's where the issue is.
The code is as follows:
if test $number -eq $number >dev/null 2>&1
then
"do stuff"
else
echo "There was an error"
exit
The problem is that we have to turn in our programs as text files using script and whenever I try to script my program and test the error cases it exits out of script as well. Is there a better way to do this?
The script is being run with the following command in the terminal
script "insert name of program here"
Thanks
If the program you're testing is invoked as a subprocess, then any exit command will only exit the command itself. The fact that you're seeing contrary behavior means you must be invoking it differently.
When invoking your script from the parent testing program, use:
# this runs "yourscript" as its own, external process.
./yourscript
...to invoke it as a subprocess, not
# this is POSIX-compliant syntax to run the commands in "yourscript" in the current shell.
. yourscript
...or...
# this is bash-extended syntax to run the commands in "yourscript" in the current shell.
source yourscript
...as either of the latter will run all the commands -- including exit -- inside your current shell, modifying its state or, in the case of exit, exec or similar, telling it to cease execution.

After exiting custom startup shell script, exit into default startup shell?

You have to excuse me if I use the wrong language here of if I'm asking an obvious but that is, after all, why I'm here.
I'm just getting to grips with shell scripting and have written a small script that is "Run as a custom command instead of my shell" to make things a little easier for the things I might want to do. Here's what I've got.
#
# Custom console startup script.
#
path_to_scripts=~/Scripts
echo "Hello $USERNAME, what would you like to do?"
echo "Options:"
echo "-l Continue in local machine"
echo "-s Connect to server"
read response
case $response in
"l") echo "Contunie within local machine.";;
"s") $path_to_scripts/connect_to_server;;
*) echo "Invalid command. Exiting.";;
esac
So my terminal starts up with this script and if I select 's' it runs the 'connect_to_server' script fine and connects then I'm in!
However when I enter an invalid command, or key in 'l' to exit and continue as normal the console says 'The child process exited normally with status 0.'
I know that it has just quit and the script has exited but what I want to do is just run the default shell so that I am then in my local machine at ~, as if id just started up console with default settings. What do I need to run in order to do this?
Run exec "$SHELL" to replace the current process with your normal shell.

How can I get rid of this osascript output?

The following question relates to an answer that was posted on this question:
I like the notion of creating my own function that opens a new terminal, so the script that Craig Walker linked to in that above-referenced question suited my needs. The script, written by Mark Liyanage, is found here.
That script is this:
#!/bin/sh
#
# Open a new Mac OS X terminal window with the command given
# as argument.
#
# - If there are no arguments, the new terminal window will
# be opened in the current directory, i.e. as if the command
# would be "cd `pwd`".
# - If the first argument is a directory, the new terminal will
# "cd" into that directory before executing the remaining
# arguments as command.
# - If there are arguments and the first one is not a directory,
# the new window will be opened in the current directory and
# then the arguments will be executed as command.
# - The optional, leading "-x" flag will cause the new terminal
# to be closed immediately after the executed command finishes.
#
# Written by Marc Liyanage <http://www.entropy.ch>
#
# Version 1.0
#
if [ "x-x" = x"$1" ]; then
EXIT="; exit"; shift;
fi
if [[ -d "$1" ]]; then
WD=`cd "$1"; pwd`; shift;
else
WD="'`pwd`'";
fi
COMMAND="cd $WD; $#"
#echo "$COMMAND $EXIT"
osascript 2>/dev/null <<EOF
tell application "Terminal"
activate
do script with command "$COMMAND $EXIT"
end tell
EOF
I made one change to the script on the linked site; I commented out the line that outputs "$COMMAND $EXIT" to eliminate some verbosity. However, when I run the script I still get this output
tab 1 of window id 2835
just before it opens the new window and executes the command that I pass in. Any ideas why this would be happening? (I tried moving the redirect of stderr to /dev/null before the call to oascript, but that made no difference.)
tab 1 of window 2835 is the AppleScript representation of the object returned by the do script command: it is the tab instance created to execute the command. osascript returns the results of the script execution to standard output. Since there is no explicit return in the AppleScript script, the returned value of the whole script is the result of the last-executed statement, normally the do script command. The two easiest fixes are to either redirect stdout of the osascript (and preferably not redirect stderr in case of errors):
osascript >/dev/null <<EOF
or insert an explicit return (with no value) into the AppleScript.
tell application "Terminal"
activate
do script with command "$COMMAND $EXIT"
end tell
return

Resources