Quick and dirty:
In your start up script instead of just executing the python script, use cd first.
#!/bin/sh
cd /home/username/projectname &&
python ./scriptname.py
Answer from bahamat on Stack ExchangeQuick and dirty:
In your start up script instead of just executing the python script, use cd first.
#!/bin/sh
cd /home/username/projectname &&
python ./scriptname.py
There are a couple of ways around this directly in your Python script.
If your script is always going to be in "/home/username/projectname/subfolder", you can simply add that to your search path inside Python:
import sys sys.path.append("/home/username/projectname/subfolder")I suspect, however, that you might have this in multiple "projectname" directories, so a more generic solution is something like this:
import sys import os sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), "subfolder"))This finds the directory where the Python script is (in
sys.argv[0]), extracts the directory part, appends "subfolder" onto it, and puts it into the search path.Note that some operating systems may only give the executable name in
sys.argv[0]. I don't have a good solution for this case, perhaps someone else does. You may also need to inject aos.path.abspath()call in there ifsys.argv[0]has a relative path, but play around with it a bit and you should be able to get it working.Similar to the above answer, you can have the Python script change directories all by itself with no need for a wrapper script:
import os os.chdir("/home/username/projectname")
At the beginning of your script
import os
os.chdir("/dir/to/goto/before/running/the/script")
# rest of the logic goes here
assuming your script is run like this
./my_script dir/to/work/on
then you can do
import os
import sys
os.chdir(sys.argv[1])
# rest of the logic goes here
Things you use from anywhere should be reachable from anywhere.
That's where the system's PATH environment variable comes in.
You should either move your script to a directory in the PATH, or extend the PATH with the location of your script.
Note:
make sure the script works location-independently: use sys.path extensively, try to use sys.path.join(base, sub) where possible etc...
How to execute .py file outside of it's residing directory?
bash - How to execute a python script in a different directory? - Stack Overflow
Run python script in subfolder
python: Change the scripts working directory to the script's own directory - Stack Overflow
Videos
This question has been absolutely beat to death. I know this because I spent quite some time googling it and not two answers are the same. I think this is partly because there are many use cases and the language / tech specific term barriers for us noobs. It's seriously infuriating!
So, I'll try to explain my use case. I simply want to be able to run my .py scripts from PowerShell (on win10) in other directories than where the script resides. This is because I want to do things with the files of those other dirs, while getting information from PowerShell console.
I know one solution is to compile into executables and make a batch script, but I wonder if there's a way to avoid having to go through that every time I make a little change to the script. Also it seems parameters does not work this way and console output is not visible (or it opens and closes).
I'm open to any suggestions!
Thanks for reading my question / rant :)
The easiest answer is probably to change your working directory, then call the second .py file from where it is:
python a.py && cd testA && python ../b.py
Of course you might find it even easier to write a script that does it all for you, like so:
Save this as runTests.sh in the same directory as a.py is:
#!/bin/sh
python a.py
cd testA
python ../b.py
Make it executable:
chmod +x ./runTests.sh
Then you can simply enter your directory and run it:
./runTests.sh
I managed to get b.py executing and producing the testB folder where I need it to, while remaining in the MAIN folder. For anyone who might wonder, at the beginning of my b.py script I would simply use mydir = os.getcwd() which normally is wherever b.py is.
To keep b.py in MAIN while making it work on files in other directories, I wrote this:
mydir = os.getcwd() # would be the MAIN folder
mydir_tmp = mydir + "//testA" # add the testA folder name
mydir_new = os.chdir(mydir_tmp) # change the current working directory
mydir = os.getcwd() # set the main directory again, now it calls testA
Running the bash script now works!
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.
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
This is not a pythonic way but we can use the bash to mimic the same behavior.
you can try as suggested by @FlyingTeller
(cd company_repo && python3 helper.py)
or you can also use pushd & popd
pushd company_repo && python3 helper.py && popd
You can try using env --chdir:
env --chdir=$dir python3.5 $dir/scripts/helper1.py someargument
import os
from os.path import abspath, dirname
os.chdir(dirname(abspath(__file__)))
You can use dirname(abspath(__file__))) to get the parent directory of the python script and os.chdir into it to make the script run in the directory where it is located.
The easiest answer is probably to change your working directory, then call the .py file from where it is:
cd path/to/python/file && python ../.py
Of course you might find it even easier to write a script that does it all for you, like so:
Save this as runPython.sh in the directory where you're running the python script from, is:
#!/bin/sh
cd path/to/python/file
python ../script.py
Make it executable (for yourself):
chmod +x ./runPython.sh
Then you can simply enter your directory and run it:
./runPython.sh
If you want to only make changes to the python script:
mydir = os.getcwd() # would be the folder where you're running the file
mydir_tmp = "path/to/python/file" # get the path
mydir_new = os.chdir(mydir_tmp) # change the current working directory
mydir = os.getcwd()
The reason you got an error was because sys.argv[0] is the name of the file itself, instead you can pass the directory as a string and use sys.argv[1] instead.
The subprocess module supports setting current working directory for the subprocess, fx:
subprocess.call("./Upgrade", cwd="/home/bin")
If you don't care about the current working directory of your subprocess you could of course supply the fully qualified name of the executable:
subprocess.call("/home/bin/Upgrade")
You might also want to use the subprocess.check_call function (if you want to raise an exception if the subprocess does not return a zero return code).
The problem with your solution is that you start a subprocess in which you try to execute "cd /home/bin" and then start ANOTHER subprocess in which you try to execute "./Upgrade" - the current working directory of the later is not affected by the change of directory in the former.
Note that supplying shell to the call method has a few drawbacks (and advantages too). The drawback (or advantage) is that you'll get various shell expansions (wildcard and such). One disadvantage may be that the shell may interpret the command differently depending on your platform.
You can change directory using os. The python script will remain in the folder it was created but will run processes based on the new directory.
import os
os.chdir()
os.chdir('filepath')
No you don't need to use:
cd home/directoryA/directoryB/directoryC/DirectoryD
./somefile
You can simply run the command by prefixing it with its path:
/home/directoryA/directoryB/directoryC/DirectoryD/somefile
Because you are already in the /home/directoryA you can use the current directory shortcut . and run the command like this:
./directoryB/directoryC/DirectoryD/somefile
I noticed OP has expanded scope via comments under other answers. Here is some additional information:
- To find out where
somefileis located use:locate somefile. - If
somefilewas added today you need to first update the locate database by runningsudo updatedb. - When there are multiple versions of
somefilelocated in the PATH you can find out which one is executed first usewhich somefile. - If you want to run
somefilewithout specifying a directory name in front put it in the path. To check the path useecho $PATH. Common path locations to putsomefileare/usr/local/bin(if it uses sudo powers) and/home/your_user_name/bin(you might have to create the directory first). - You can also add
/home/directoryA/directoryB/directoryC/DirectoryD/to your path but that would be highly unusual. However you could then simply typesomefileno matter what directory you are in and it will run. - Of course
somefilemust be executable which you set with the command:chmod a+x /home/directoryA/directoryB/directoryC/DirectoryD/somefile
Sure! If somefile is marked as executable, you can run it with
~/directoryA/directoryB/directoryC/DirectoryD/somefile
Want to know if somefile is executable? Go to its directory and run
find . -maxdepth 1 -perm -111 -type f
to see all the executables in that directory.
You can use os.path.dirname() and __file__ to get absolute paths like this:
#!/usr/bin/python
import os # We need this module
# Get path of the current dir, then use it to create paths:
CURRENT_DIR = os.path.dirname(__file__)
file_path = os.path.join(CURRENT_DIR, 'test.txt')
# Then work using the absolute paths:
f = open(file_path,'w')
f.write('testing the script')
This way the script will work on files placed only in the same directory as the script, regardless of the place from which you execute it.
If your cwd is /Desktop/test, and then you try to execute ./test/script.py, you're trying to run a script at /Desktop/test/test/script.py. More likely, you just wanted to do ./script.py.
As an aside, your question would have been more useful if you had provided the error message you got from the command line, rather than just saying "didn't work"
If the script is running and nothing is echoed to the console, most likely it's working. Note that opening a file in 'w' mode truncates the file. Maybe you want to use a+?