The Python Oracle

python: Change the scripts working directory to the script's own directory

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Track title: CC H Dvoks String Quartet No 12 Ame

--

Chapters
00:00 Question
01:11 Accepted answer (Score 280)
01:58 Answer 2 (Score 59)
02:22 Answer 3 (Score 27)
03:32 Answer 4 (Score 23)
04:08 Thank you

--

Full question
https://stackoverflow.com/questions/1432...

Answer 1 links:
http://docs.python.org/library/sys.html#...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #workingdirectory

#avk47



ACCEPTED ANSWER

Score 301


This will change your current working directory to so that opening relative paths will work:

import os
os.chdir("/home/udi/foo")

However, you asked how to change into whatever directory your Python script is located, even if you don't know what directory that will be when you're writing your script. To do this, you can use the os.path functions:

import os

abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

This takes the filename of your script, converts it to an absolute path, then extracts the directory of that path, then changes into that directory.




ANSWER 2

Score 66


You can get a shorter version by using sys.path[0].

os.chdir(sys.path[0])

From http://docs.python.org/library/sys.html#sys.path

As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter




ANSWER 3

Score 29


Don't do this.

Your scripts and your data should not be mashed into one big directory. Put your code in some known location (site-packages or /var/opt/udi or something) separate from your data. Use good version control on your code to be sure that you have current and previous versions separated from each other so you can fall back to previous versions and test future versions.

Bottom line: Do not mingle code and data.

Data is precious. Code comes and goes.

Provide the working directory as a command-line argument value. You can provide a default as an environment variable. Don't deduce it (or guess at it)

Make it a required argument value and do this.

import sys
import os
working= os.environ.get("WORKING_DIRECTORY","/some/default")
if len(sys.argv) > 1: working = sys.argv[1]
os.chdir( working )

Do not "assume" a directory based on the location of your software. It will not work out well in the long run.




ANSWER 4

Score 26


Change your crontab command to

* * * * * (cd /home/udi/foo/ || exit 1; ./bar.py)

The (...) starts a sub-shell that your crond executes as a single command. The || exit 1 causes your cronjob to fail in case that the directory is unavailable.

Though the other solutions may be more elegant in the long run for your specific scripts, my example could still be useful in cases where you can't modify the program or command that you want to execute.