8

I have two pieces of code. One is Applescript and the other a Bash shell script. The shell script needs to run concurrently with the applescript, return some values and then exit. The problem is the shell script's read -p prompt does not pause for user input when called from within applescript using do shell script "/path/to/script.sh".

I thought maybe

display dialog "Query?" default answer ""
set T to text returned of result

could replace the read -p prompt but I can't figure out how to make either way work. How cam use either of these methods to properly ask and wait for user entry?

I realize I could cut the applescript in two sections placing one at the beginning of the shell script and one after the last shell command.

#!/bin/bash

osascript ~/Start_Script.scpt

echo 'enter some Text'
read -p "" T

## for things in stuff do more 
## stuff while doing other things
## done 

osascript ~/End_Script.scpt

This is what I've been doing and it does work. But it requires using the terminal which is fine for me. But if I wanted to show someone like my Mom.. well she's just not going to open the Terminal app. So it would be nice to find a way to emulate the read -p command within Applescript itself and be able to pass a variable along to the embedded shell script.

3 Answers 3

12

AppleScript embedded in a shell script is often messy, hard to read, and hard to quote properly.

I get around that by using this sort of construct.

#!/usr/bin/env bash

read -r -d '' applescriptCode <<'EOF'
   set dialogText to text returned of (display dialog "Query?" default answer "")
   return dialogText
EOF

dialogText=$(osascript -e "$applescriptCode");

echo $dialogText;

-ccs

1
  • 2
    I actually think this is a better answer as it's more along the lines of what I was trying to do at the time. And this is what I ended up using anyways. Also introduced me to using heredocs which I now use all the time. So to all future readers, I encourage you to try this answer first. I believe it is a more robust and cleaner code. Commented Sep 21, 2017 at 12:53
5

I think what you need is:

set T to text returned of (display dialog "Query?" buttons {"Cancel", "OK"} default button "OK" default answer "")

If you want to do this from a bash script, you need to do:

osascript -e 'set T to text returned of (display dialog "Query?" buttons {"Cancel", "OK"} default button "OK" default answer "")'

I can explain it in more detail if you need me to, but I think it's pretty self-explanatory.

EDIT: If you want the result as a shell variable, do:

SHELL_VAR=`osascript -e 'set T to text returned of (display dialog "Query?" buttons {"Cancel", "OK"} default button "OK" default answer "")'`

Everything you type between the backticks (` `) is evaluated (executed) by the shell before the main command. See this answer for more information.

I agree that this is a little "hacky", and I'm sure there are better ways to do this, but this works.

4
  • Yes you can @user3439894. Just try copy pasting that thing as is into the Terminal. Commented May 27, 2016 at 12:56
  • It returns: 27:113: execution error: No user interaction allowed. (-1713) Commented May 27, 2016 at 13:03
  • Works fine on my machine: OSX 10.11.5. See screenshot 1 and screenshot 2 Commented May 27, 2016 at 13:17
  • @user556068 My bad. Edited the answer. Commented May 27, 2016 at 13:46
0

Here's a slightly more succinct example of this in action:

PROMPT_RETURNED="$(osascript -e 'text returned of (display dialog "How many, eh?" default answer "")')"
echo "$PROMPT_RETURNED"
1
  • just running osascript -e 'text returned of (display dialog "How many, eh?" default answer "")' would of course output the same thing to the terminal, but in my example I assign the returned value to a variable because presumably that value will be used later on in a shell function. Commented Nov 20, 2021 at 1:56

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.