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
Answer from 3D1T0R on Stack OverflowThe 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 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 :)
python - Command line execution in different folder - Stack Overflow
Run python script in subfolder
Running Executable in a different directory in python - Stack Overflow
function - Running a python file within a different directory - Stack Overflow
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.
The subprocess module is a very good solution.
import subprocess
p = subprocess.Popen([command, argument1,...], cwd=working_directory)
p.wait()
It has also arguments for modifying environment variables, redirecting input/output to the calling program, etc.
Try to os.chdir(path) before invoking the command.
From here:
os.chdir(path) Change the current working directory to path.
Availability: Unix, Windows
EDIT
This will change the current working dir, you can get the current working by:
os.getcwd()
If you want to save it and restore it later, if you need to do some work in the original working dir.
EDIT 2
In any case you should probably move to subprocess (doc) as suggested here. If you use subprocess's Popen you have the choice of providing cwd parameter to specify the working directory for the subprocess: read this.
subprocess.Popen(args, bufsize=0, executable=None, stdin=None,
stdout=None, stderr=None, preexec_fn=None, close_fds=False,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0)
...
If cwd is not None, the child’s current directory will be changed to cwd before it is executed. Note that this directory is not considered when searching the executable, so you can’t specify the program’s path relative to cwd.
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')
You need to find out where your script is and assemble an absolute path:
import os
import subprocess
dirname = os.path.dirname(os.path.abspath(__file__))
cmd = os.path.join(dirname, 'mybatch_file')
subprocess.call(cmd)
In Steps
You can find out the name of script with:
__file__
Now make it an absolute path:
os.path.abspath
and get the directory it is in:
os.path.dirname
Finally, join this path with your batch file name:
os.path.join
before you feed it to:
subprocess.call
you can achieve it use subprocess module
from subprocess import call
comando = 'path_to_the_script'
call(comando, shell=True)
So, I have to open two programs daily. Both can be operated from command line. The inputs are always the same.
Both executables are in different directories. So, I have to change directories and then open the programs and pass arguments to them. How do I do this? I tried using OS module but couldn't make it work.
I will upload code if needed. TIA!
Your problem is the same as: Relative imports for the billionth time
TL;DR: you can't do relative imports from the file you execute since main module is not a part of a package.
As main:
python B/fileB.py
Output:
Traceback (most recent call last):
File "p2/m2.py", line 1, in <module>
from p1.m1 import funA
ImportError: No module named p1.m1
As a module (not main):
python -m B.fileB
Output:
hello from A
One way to solve this is to add module A into the path of fileB.py by adding
import sys
sys.path.insert(0, 'absolute/path/to/A/')
to the top of fileB.py.