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!
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.
How to execute .py file outside of it's residing directory?
Running a Python Script Inside Another Directory - Stack Overflow
linux - Running a (python) script in another directory - Stack Overflow
Running a python script from any directory?
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 :)
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+?
sh /path/to/script will spawn a new shell and run she script independent of your current shell. The source (.) command will call all the commands in the script in the current shell. If the script happens to call exit for example, then you'll lose the current shell. Because of this it is usually safer to call scripts in a separate shell with sh or to execute them as binaries using either the full (starting with /) or relative path (./). If called as binaries, they will be executed with the specified interpreter (#!/bin/bash, for example).
As for knowing whether or not a script will find the files it needs, there is no good answer, other than looking at the script to see what it does. As an option, you could always go to the script's folder in a sub-process without leaving your current folder:
(cd /wherever/ ; sh script.sh)
You can definitely do that (with the adjustments the others mentioned like sudo sh /pathto/script.sh or ./script.sh). However, I do one of a few things to run them system wide to not worry about dirs and save me useless extra typing.
1) Symlink to /usr/bin
ln -s /home/username/Scripts/name.sh /usr/bin/name
(be sure there is no overlapping name there, because you would obviously override it.) This also lets me keep them in my development folders so I can adjust as necessary.
2) Add the Scripts dir to your path (using .bash_profile - or whatever.profile you have on your shell)
PATH=/path/to/scripts/:$PATH
3) Create Alias's in the .bash_profile in ~/.bash_profile add something like:
alias l="ls -l"
As you can tell, the syntax is just alias, digits you want to act as a command, the command. So typing "l" anywhere in the terminal would result in ls -l If you want sudo, just alias sl="sudo ls -l" to note to yourself l vs sl (as a useless example).
Either way, you can just type sudo nameofscript and be on your way. No need to mess with ./ or . or sh, etc. Just mark them as executable first :D
I have a small python script on a Mac that I'd like to run from Terminal without first cd'ing into the directory.
I can set an alias to do pipenv run python script.py. But is there a better way to do this?
You can call your script using only the whole path, without the dot .:
/path/to/script
sudo also works fine:
sudo /path/to/script
Will they usually find all the stuff they need to run properly?
Do you mean like, "will my script find the files which are in the same folder?" That depends of your code. For example, if you have the script /tmp/test.sh:
#!/bin/bash
ls
If you invoke it from your home folder, it will run ls in your home:
test@ubuntu:~:/tmp/test.sh
Desktop Dropbox Imagens NetBeansProjects Público
Documentos Modelos R Vídeos
In this situation, dirname is your ally:
#!/bin/bash
current=$(dirname $0)
ls $current
Running it from your home folder, it gives:
test@ubuntu:~:/tmp/test.sh
acroread_1000_1000 hiRF7yLSOD pulse-2L9K88eMlGn7
unity_support_test.0 clementine-art-jt5332.jpg
which is the content of my /tmp/ folder.
Common *nix practice for user scripts is to put them in your bin directory. That way, the script will be searched for by default when you type the name from the command line.
Your bin (binary) directory should be in your home folder so the full path would be /home/yourusername/bin. (Obviously change yourusername to your login name.)
The bin directory should have the following permissions if you run ls -lh from the terminal: drwxr-xr-x
By default when you make a directory with the terminal you have the following permissions set: drwxrwxr-x
The only thing you need to change is the group permission, but for I will walk you through each step from the terminal (assuming you don't already have a bin):
Open a terminal ([Ctrl] + [Alt] + t)
Create the binary directory:
mkdir binNow either use the GUI or CLI to copy your scripts to
/bin.Now we have to change some permissions so that everything is set up correctly:
chmod -R 755 bin
This sets the owner (you) to read, write and execute, groups and others to read and execute the scripts. The -R means recursive or set the permissions for all the files in the directory as well.
For more help on file permissions see this document.
Now, you can just type myscript to execute your scripts - you do not have to be in the directory. You don't need the . / or anything!
For sudo it's a little different as you will have to define the full path to the script file.
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
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")