I currently have a folder structure that will contain a few python scripts which need to be fired from a certain folder but I would like to write a global script that runs each python script via a seperate script in each folder.
-Obtainer
--Persona
---Arthur
----start.sh
--Initialise.sh
-Persona
--Arthur
---lib
----pybot
-----pybot.py
When I run initialise I am aiming to make initialise run "start.sh" Arthur is the bot and there will be more folders with different names and initialise with find and fire each start.sh.
In initialise.sh I have:
#!/bin/bash
. ./Persona/Arthur/start.sh
In start.sh I have:
#!/bin/bash
python ../../../Persona/Arthur/lib/pybot/pybot.py
I get this error:
python: can't open file '../../../Persona/Arthur/lib/pybot/pybot.py': [Errno 2] No such file or directory
However if I run the start.sh itself from its directory it runs fine. This is because I assume it's running it from the proper shell and consequently directory. Is there a way to make the main script run the start.sh in it's own shell like it is being run by itself? The reason why is because the pybot.py saves a bunch of files to where the start script is and because there will be more than one bot I need them to save in each seperate folder.
In the first place, do not source when you mean calling it,
#!/bin/bash
. ./Persona/Arthur/start.sh
Don't do this.
Your script has a number of issue. It won't work because of your current working directory is uncertain. You'd better have your script derive the path to relieve yourself from the hustle of abs paths or relative paths.
The general code could be
script_dir=`dirname "${BASH_SOURCE[0]}"`
then you can use this to derive the path of your target file,
#!/bin/bash
script_dir=`dirname "${BASH_SOURCE[0]}"`
"$script_dir/Persona/Arthur/start.sh"
Your python invocation becomes:
#!/bin/bash
script_dir=`dirname "${BASH_SOURCE[0]}"`
python "$script_dir/../../../Persona/Arthur/lib/pybot/pybot.py"
This should work out properly.
Regarding BASH_SOURCE, check out https://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html
If you want the directory of start.sh to be cwd, you should call cd:
#!/bin/bash
script_dir=`dirname "${BASH_SOURCE[0]}"`
cd "$script_dir"
python "$script_dir/../../../Persona/Arthur/lib/pybot/pybot.py"
Related
I have a question about running a bash script in a python file. First, let me explain the situation. I have multiple python files: for each city in Mali, I am able to create a weather forecast in python (therefore is have created multiple python files: e.g. gao.py, bamba.py, etc.) One of the steps in each python file, is to run a bash script that creates audiofiles in .wav format, and places them in a folder /converted. Now, my question the following:
How do I change the bash script in such a way, that when gao.py is running, a folder /converted/gao will be created, and when for example bamba.py is running, a folder converted/bamba is created?
This is the current bash script:
#!/bin/bash
if [ ! -d converted/gao ]
then
mkdir converted/gao;
fi;
However, when I run the script above, each city will places his files in converted/gao, which is not what I want. I hope somebody knows how to fix this issue.
Use __ file__ for accessing the filename of script in python. And then pass it as argument to bash script. After that access the argument in bash script using $1.
as following samples:
Python Script hello.py
import os
script_filename = __file__
# function to execute the shell script
os.system("./bashfile.sh {}".format(script_filename))
Sample Bash Script bashfile.sh
#!/bin/bash
script_name=$1
# now use the script_name as you like in your script.
echo $script_name
I have a folder called TEST with inside :
script.py
script.sh
The bash file is :
#!/bin/bash
# Run the python script
python script.py
If I run the bash file like this :
./TEST/script.sh
I have the following error :
python: can't open file 'script.py': [Errno 2] No such file or directory
How could I do, to tell my script.sh to look in the directory (which may change) and to allow me to run it for inside the TEST directory ?
Tricky, my python file run a sqlite database and I have the same problem when calling the script from outside the folder, it didn't look inside the folder to find the database!
Alternative
You are able to run the script directly by adding this line to the top of your python file:
#!/usr/bin/env python
and then making the file executable:
$ chmod +x script.py
With this, you can run the script directly with ./TEST/script.py
What you asked for specifically
This works to get the path of the script, and then pass that to python.
#!/bin/sh
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
python "$SCRIPTPATH/script.py"
Also potentially useful:
You mentioned having this problem with accessing a sqlite DB in the same folder, if you are running this from a script to solve this problem, it will not work. I imagine this question may be of use to you for that problem: How do I get the path of a the Python script I am running in?
You could use $0 which is the name of the currently executing program, as invoked, combined with dirname which provides the directory component of a file path, to determine the path (absolute or relative) that the shell script was invoked under. Then, you can apply it to the python invocation.
This example worked for me:
$ t/t.sh
Hello, world!
$ cat t/t.sh
#!/bin/bash
python "$(dirname $0)/t.py"
Take it a step farther and change your current working directory which will also be inherited by python, thus helping it to find its database:
$ t/t.sh; cat t/t.sh ; cat t/t.py ; cat t/message.txt
hello, world!
#!/bin/bash
cd "$(dirname $0)"
python t.py
with(open('message.txt')) as msgf:
print(msgf.read())
hello, world!
From the shell script, you can always find your current directory: Getting the source directory of a Bash script from within. While the accepted answer to this question provide a very comprehensive and robust solution, your relatively simple case only really needs something like
#!/bin/bash
dir="$(dirname "${BASH_SOURCE[0]}")"
# Run the python script
python "$(dir)"/script.py
Another way to do it would be to change the directory from which you run the script:
#!/bin/bash
dir="$(dirname "${BASH_SOURCE[0]}")"
# Run the python script
(cd "$dir"; python script.py)
The parentheses ((...)) around cd and python create a subprocess, so that the directory does not change for the rest of your bash script. This may not be necessary if you don't do anything else in the bash portion, but is still useful to have if you ever decide to say source your script instead of running it as a subprocess.
If you do not change the directory in bash, you can do it in Python using a combination of sys.argv\[0\], os.path.dirname and os.chdir:
import sys
import os
...
os.chdir(os.path.dirname(sys.argv[0]))
I'm trying to run a Python script from a shell script within a shell script, but I'm running into some problems.
Imagine my root shell script looks like this:
echo "test0"
sh ./test/test1/test2.sh
and my test2.sh:
echo "test2"
python testme.py
The python file is in the same directory as test2.sh but test2.sh's working directory seems to be the root's so it cannot find the python script. So, if I give the python script's absolute location to test2.sh, the python file runs, but when the python file creates new files, it's created in the root.
If there is a solution so that I don't have to edit the python script to create new files in the directory of the python script, please let me know.
Here is your root script:
echo "test0"
cd test/test1
sh ./test2.sh
Your script test2 is launched with the environment of your root script. So you just have to cd in your root script.
im kinda new to the python world and im having some issues running a bash file that will be automatically from my python script (using linux) .
i set my python script to create both a text file .geo and a Bash file .sh in a directory somewhere in my Desktop like this :
basedirectory="/home/pst2/Desktop/";
*//Writing the .geo file*
file = open(basedirectory+nomdossier+"/"+nomfichier+".geo", 'w');
file.write
..blabla
..blabla
file.close();
//Writing the .sh file
file = open(basedirectory+nomdossier+"/"+nomfichier+".sh", 'w');
file.write
..blabla
..blabla
file.close();
Now at this point my script works perfectly with all the variables set up and working fine and both those files that i created find themselves in this directory (for exemple after running the python script and entering the variables)
/home/pst2/Desktop/test/
(and in here you will find the new test.geo and test.sh that were created via the python script)
basically the test.sh when executed "manually" with Bash test.sh ( whenever i am in its directory on ubuntu) will create another file called test.msh in the same directory
and i cant seem to find the right coding , using the subprocess modules to execute the newly created test.sh file automatically from the script .
is there a way to do so , like with indicating the absolute path to the .sh file
(in our case basedirectory+nomdossier+"/"+nomfichier+".sh ) ?
take a look at the os module.
I believe
os.system("command_line_with_args")
could be what your looking for
Not sure what you are writing into the .sh file.
But to start with:
Have you started your .sh-file with the hashbang? #!/bin/sh
Have you modded your file as executable? chmod +x
After you have done this, you should be able to use subprocess module and do something like the example from the manual for subprocess:
subprocess.call([path_to_script+'/script.sh'])
I might have to update this answer if & when new information comes to my attention
Roughly equivalent to "manually" executing bash test.sh with the current directory being the one where test.sh has been written by your posted code is:
from subprocess import call
call(['bash', 'test.sh'], cwd=basedirectory+nomdossier)
I have a python script let's name it script1.py. I can run it in the terminal this way:
python /path/script1.py
...
but I want to run like a command-line program:
arbitraryname
...
how can i do it ?
You use a shebang line at the start of your script:
#!/usr/bin/env python
make the file executable:
chmod +x arbitraryname
and put it in a directory on your PATH (can be a symlink):
cd ~/bin/
ln -s ~/some/path/to/myscript/arbitraryname
There are three parts:
Add a 'shebang' at the top of your script which tells how to execute your script
Give the script 'run' permissions.
Make the script in your PATH so you can run it from anywhere.
Adding a shebang
You need to add a shebang at the top of your script so the shell knows which interpreter to use when parsing your script. It is generally:
#!path/to/interpretter
To find the path to your python interpretter on your machine you can run the command:
which python
This will search your PATH to find the location of your python executable. It should come back with a absolute path which you can then use to form your shebang. Make sure your shebang is at the top of your python script:
#!/usr/bin/python
Run Permissions
You have to mark your script with run permissions so that your shell knows you want to actually execute it when you try to use it as a command. To do this you can run this command:
chmod +x myscript.py
Add the script to your path
The PATH environment variable is an ordered list of directories that your shell will search when looking for a command you are trying to run. So if you want your python script to be a command you can run from anywhere then it needs to be in your PATH. You can see the contents of your path running the command:
echo $PATH
This will print out a long line of text, where each directory is seperated by a semicolon. Whenever you are wondering where the actual location of an executable that you are running from your PATH, you can find it by running the command:
which <commandname>
Now you have two options: Add your script to a directory already in your PATH, or add a new directory to your PATH. I usually create a directory in my user home directory and then add it the PATH. To add things to your path you can run the command:
export PATH=/my/directory/with/pythonscript:$PATH
Now you should be able to run your python script as a command anywhere. BUT! if you close the shell window and open a new one, the new one won't remember the change you just made to your PATH. So if you want this change to be saved then you need to add that command at the bottom of your .bashrc or .bash_profile
Add the following line to the beginning script1.py
#!/usr/bin/env python
and then make the script executable:
$ chmod +x script1.py
If the script resides in a directory that appears in your PATH variable, you can simply type
$ script1.py
Otherwise, you'll need to provide the full path (either absolute or relative). This includes the current working directory, which should not be in your PATH.
$ ./script1.py
You need to use a hashbang. Add it to the first line of your python script.
#! <full path of python interpreter>
Then change the file permissions, and add the executing permission.
chmod +x <filename>
And finally execute it using
./<filename>
If its in the current directory,