Mike
Mike

Reputation: 49463

Launching a python script via a symbolic link

I have an executable python script that exists in a "scripts" directory, and there's a symbolic link to that script (used to launch the file) in a root directory. Something like:

.
├── scripts
│   ├── const.py
│   ├── fops.py
│   ├── i_build.py
│   └── i_Props.ini
└── build_i -> scripts/i_build.py

I would like to be able to launch/run my scripts via:

python build_i

From the root directory. The i_build.py script will attempt to open i_Props.ini and do some magic based on what's in there.

The issue is that when the i_build.py script is launched via the symlink in the root directory, the i_build.py script will look in the root directory for the other files (not the /scripts directory where i_build.py is stored).

The i_build.py file has the props file location as:

PROP_FILE = "i_Props.ini"

and attempts to open that, and then fails. I do not want to hardcode a path for obvious reasons.

A quick test adding os.getcwd() in the main file confirms my suspicions that it thinks the CWD is the root directory, and a check of __file__ says it is the symbolic link ("build_i").

Is there anything I can do to have python use the destination of the symbolic like for the __file__ name and CWD?

Upvotes: 14

Views: 12739

Answers (3)

Dia
Dia

Reputation: 41

The simplest way to be able to launch a Python script from a symlink and have the script use the link destination's path is:

os.chdir("<path to link destination>")

For example, I like to put my script and its associated files in /usr/local/lib/myapp

Then for convenience I create a symlink to /usr/local/lib/myapp/myapp.py in /usr/local/bin/:

cd /usr/local/bin
ln -s ../lib/myapp/myapp.py myapp

In myapp.py I would have this:

os.chdir("/usr/local/lib/myapp")
# put any import statements for myapp files here

Upvotes: 0

Ronald Portier
Ronald Portier

Reputation: 231

You can use __file__, but you have to take some precautions to get the real path:

import os
base_dir = os.path.dirname(os.path.realpath(__file__))

Then load your other files / resources relative to base_dir:

some_subdir = 'my_subdir'
some_file = 'my.ini'

ini_path = os.path.join(base_dir, some_subdir, some_file)

Upvotes: 21

Steve Barnes
Steve Barnes

Reputation: 28405

Just a few possibilities spring to mind:

  1. In the root directory have a shell file that calls your python script by explicit path.
  2. Add the directory that it lives in to your path.
  3. Specifically add the directory to sys.path

Upvotes: 3

Related Questions