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.
    – I0_ol
    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.
    – gunner
    May 27, 2016 at 12:56
  • It returns: 27:113: execution error: No user interaction allowed. (-1713) May 27, 2016 at 13:03
  • Works fine on my machine: OSX 10.11.5. See screenshot 1 and screenshot 2
    – gunner
    May 27, 2016 at 13:17
  • @user556068 My bad. Edited the answer.
    – gunner
    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.
    – Chris
    Nov 20, 2021 at 1:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .