4

I've created an .app (a macOS bundle) where the main executable is a Bash script, following the instructions I found in StackOverflow and other places. It works perfectly except for the fact that when I double click on a file associated with the .app, the script is run but it doesn't get the clicked file name as an argument.

Looks like the problem is that the script doesn't handle the "OpenFile" event, but I don't know if there's a way where the user double-clicks a file and the file name is passed to the .app bundle executable as a command line parameter and not through some event.

#! /usr/local/bin/bash
source ~/.bashrc
python3 final_script.py $1
# Above, "$1" is empty. I've tried some variations,
# including not running the second script, to no avail. 

I know I can use py2app to achieve something similar, or Platypus, or Automator, etc. but using a Bash script is better for my workflow and also I'm curious about how macos passes parameters to apps when a file is double-clicked.

Thanks a lot in advance!

5
  • 1
    Yes, exactly, I'm used to call anything you can run "binary", maybe my UNIX background, sorry. I'll edit my question accordingly, and thanks for pointing that out. Commented Jun 11, 2019 at 13:14
  • $1 valid to use only when you supply arguments to a script, for instance ./test.sh my argument. Here, $1 is "my" and $2 is "argument". The name of the script is always $0. I don't know the answer to your solution, but I think some argument isn't being passed. Commented Jun 12, 2019 at 10:50
  • That's the problem, Bayou, no arguments end in the positional parameters. Commented Jun 12, 2019 at 17:02
  • Is it possible to include a second script? Hide it and execute that file with the parameters needed. Commented Jun 12, 2019 at 21:16
  • I don't know how will that solve the problem, Bayou. Could you please elaborate in a full answer? Or let's move this conversation to the chat... Commented Jun 13, 2019 at 4:20

1 Answer 1

3

Finally I found the way. Simpler than I thought, and it was not easy to find but...

The Bash launcher won't get anything in the command line because that's NOT the way macOS handles arguments in app bundles, it uses Apple Events. I didn't know this, and it's my fault, my lack of expertise in macOS.

Turns out tkinter actually supports Apple Events, at least the odoc one, which is the one the app bundle gets when the user double clicks a document to be opened by an app.

So, what I did was modifying final_script.py, adding the following code:

import sys
import tkinter

def handle_opendocument(widget, *args):
    message = ''
    for arg in args:
        message += str(arg) + '\n'
    widget.configure(text=message.rstrip())
...
# More code here...
...

root = tkinter.Tk()

root.title('Testing AppleEvent handling in Python/Tk')
root.createcommand('tk::mac::OpenDocument', lambda *args: handle_opendocument(label, *args))

label = tkinter.Label(root)
label.configure(text='Starting up...')

label.pack()

root.mainloop()

Of course, the real handle_opendocument function in my app does more things, but I wanted to show the bare minimum necessary to make this work. I hope is helpful!

Sign up to request clarification or add additional context in comments.

4 Comments

Did you replace your bash script with final_script.py or did you left the python script launching on the the bash script ?
Bemipefe, I don't remember right now, but I can try to find the relevant files and I'll provide you with an answer, if you give me a couple days. It's been nearly two years since I did this XD
Thanks. I just tried and it works even if the application main executable is a bash script. So chaining bash -> python doesn't prevent tkinter from receiving the open event. This is really useful for me.
Well, looks like you saved me quite a bit of time trying to find the code! I'm very happy it worked for you, and thanks for your comment!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.