1

I am using a MacOS osascript command in a shell script and I try to run the following command:

APPNAME=$@

if pgrep -x "$APPNAME" > /dev/null # checking if app is open
then
  echo "Closing..."
  osascript -e 'quit app $APPNAME'

else
  echo "*** The app is not open"
fi

Ideally, the command would be osascript -e 'quit app "Calendar"' as an example of a working solution. However, I can't seem to insert a variable in-between ' ' quotation marks.

What would be a workaround?

agc
  • 7,973
  • 2
  • 29
  • 50
  • See [Process Management](https://mywiki.wooledge.org/ProcessManagement) for how to do this sort of thing properly. – l0b0 May 28 '20 at 20:38
  • @DaniilGannota: Why are you using single quotes when you don't want interpolation to occur? Aside from the obvious solution `osascript -e "quit app $APPNAME"`, an easy-to-read alternative, which might come handy if you want to do one day a mixture of interpolated and non-interpolated strings, is `osascript -e 'quit app '"$APPNAME"` . – user1934428 May 29 '20 at 07:59
  • 1
    @user1934428 I tried both these but they throw me an error! I get errors -2740, -2741 and -2743. That's why I am asking here :) Apparently, this method worked for me: `osascript -e 'on run argv' -e 'quit app (item 1 of argv)' -e 'end run' "$appname"` – Daniel Gannota May 29 '20 at 10:12
  • Closers: **not a duplicate** -- see [*chepner's* comment](https://stackoverflow.com/questions/62073282/how-to-insert-a-variable-in-between-in-a-shell-command/62075148?noredirect=1#comment109786499_62073343) and [OP's follow up](https://stackoverflow.com/questions/62073282/how-to-insert-a-variable-in-between-in-a-shell-command/62075148?noredirect=1#comment109786780_62073343). This is a miscategorized Apple specific question, **not** a *nix question.. – agc May 29 '20 at 10:42
  • @DaniilGannota: If you want to pass double quotes literally to osascript (which would be an odd requirement, but not inconceivable), you have of course to include them in the command: `osascript -e 'quit app "'"$APPNAME"'"'`. I just show the general principle of how to handle quoting. You need to apply this in the way it fits for your concrete usage case. – user1934428 May 29 '20 at 10:49
  • @DaniilGannota, Re *"I get errors -2740, -2741 and -2743."*: Please include the complete text of any error messages in the question. Do not just say *"it doesn't work"* -- be specific. – agc May 29 '20 at 10:57

4 Answers4

4

Trying to build a script dynamically using string interpolation is always fragile. You should pass the app name as an argument to the AppleScript, so that you don't have to worry about escaping any characters through two levels of interpreters.

APPNAME=$1  # The name should be passed as a single argument.

if pgrep -x "$APPNAME" > /dev/null # checking if app is open
then
  echo "Closing..."
  osascript -e 'on run argv' -e 'quit app (item 1 of argv)' -e 'end run' "$APPNAME"

else
  echo "*** The app is not open"
fi

No matter what the value of APPNAME is, you are executing the exact same script; the only difference is the argument that script receives.

chepner
  • 497,756
  • 71
  • 530
  • 681
1

The point (one of the points, anyway) of single quotes is to prevent variable interpolation. It sounds like what you really want is a way to get double quotes into a string. There are lots of ways to do that. A common one is:

osascript -e "quit app \"$appname\""
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • 1
    Cross your fingers that `appname` doesn't contain a double quote :) The safe version is something like `osascript -e 'on run argv' -e 'quit app (item 1 of argv)' -e 'end run' "$appname"` (there may be a slightly shorter way to specify a multiline script; I don't know if there's an AppleScript equivalent for `;` like `bash` uses.) – chepner May 28 '20 at 20:05
  • 2
    [Apparently not](https://stackoverflow.com/questions/4108808/applescript-oneliner), though since the question is tagged `bash` and `zsh`, something like `osascript -e $'on run argv\nquit app (item 1 of argv)\nend run' textedit` is an option. (Moral of the story: don't use parameterized "one-liners" in AppleScript.) – chepner May 28 '20 at 20:09
  • I get the following error when I try to run it `syntax error: A identifier can’t go after this number. (-2740)`. Do you know why? – Daniel Gannota May 28 '20 at 20:16
  • 1
    @chepner as I am very inexperienced with shell commands, I am not entirely sure what you did there, but it worked! Thanks a lot – Daniel Gannota May 28 '20 at 20:18
0

This implementation worked for me:

osascript -e 'quit app "'"$APPNAME"'"'

Trying this using:

osascript -e 'quit app "\"$APPNAME\""'

did not work resulting in error showing: "\"$APPNAME\""... as the value it is seeing.

See https://discussions.apple.com/thread/251633896 for more

Ryan Work
  • 1
  • 1
-1

Try:

osascript -e 'quit app '"$APPNAME"

Or, if osascript requires additional double quotes, try:

osascript -e 'quit app "'"$APPNAME"'"'
agc
  • 7,973
  • 2
  • 29
  • 50
  • For some reason the latter example is easier to keep straight in my head than the backslash `\"` equivalent -- while writing it anyway. Reading it later on it looks equally obscure. – agc May 28 '20 at 22:00
  • This is still fragile: your second one assumes that `$APPNAME` itself doesn't contain double quotes. – chepner May 29 '20 at 12:11
  • @chepner, Re *"fragile"*: Thanks, I'm not up on *MacOS* quoting, so I'll probably delete this answer soon. – agc May 29 '20 at 12:13
  • This isn't unique to macOS; you have the same problem on any platform. The bigger problem here is that you are nesting one script inside another script, which just multiplies the quoting concerns. – chepner May 29 '20 at 12:15
  • @chepner, In that case it's unclear what *"your second one assumes ... double quotes"* is warning against. This works `f='"dquote"' ; echo "$f"`, so if used carefully what is fragile there? (Agreed however, that minimizing quoting is preferable.) – agc May 29 '20 at 12:21
  • Say `APPNAME='Weird"AppName'`. Then `osascript` will see the argument `quit app Weird"AppName`, which contains an unclosed double-quote. You would have to make sure that `AppName` contained a fragment of AppleScript that *represents* the application's name when incorporated into the surrounding context, rather than simply the application's name. – chepner May 29 '20 at 12:44