236

I've tried googling the answer but with no luck.

I need to use my works supercomputer server, but for my python script to run, it must be executed via a shell script.

For example I want job.sh to execute python_script.py

How can this be accomplished?

Harpal
  • 12,057
  • 18
  • 61
  • 74
  • 2
    Have you tried just putting `python python_script.py` in your shell script? – thkala Dec 07 '10 at 13:33
  • Um, `python python_script.py`. Or just `./python_script.py` if the script got a shebang. –  Dec 07 '10 at 13:34
  • 2
    @delnan: ./python_script.py also requires that the script is executable – thkala Dec 07 '10 at 13:36
  • what exactly have you tried and what is the problem? Either you did not do that good of a google search, or there is a lot that you are not telling us... – thkala Dec 07 '10 at 13:41
  • 4
    This is a rather old question but the best/most complete answer is the one by João Víctor. Be sure to read down to it. – Still.Tony Aug 13 '14 at 15:10

12 Answers12

283

Just make sure the python executable is in your PATH environment variable then add in your script

python path/to/the/python_script.py

Details:

  • In the file job.sh, put this
#!/bin/sh
python python_script.py
  • Execute this command to make the script runnable for you : chmod u+x job.sh
  • Run it : ./job.sh
ketanbhatt
  • 898
  • 7
  • 19
Jean-Bernard Jansen
  • 7,544
  • 2
  • 20
  • 17
  • 5
    It depends on your system. Python 3 may be the default python runtime, or may not be. You can check by running `python --version`, and you can enforce the version with `python3 hello.py`. – Jean-Bernard Jansen Dec 16 '16 at 10:58
  • What to do if it does not find the already installed imports, such as pandas? – mah65 Dec 17 '19 at 01:10
  • It means you launched the wrong python binary or the environment is not right. In that case, you should populate a virtualenv, then run `source PATH/TO/VENV/bin/activate` then call `python python_script.py` – Jean-Bernard Jansen Feb 06 '20 at 22:13
  • I'm trying to do this in automator, and I'm getting an error; `/path/to/Python: can't open file '/path/to/script': [Errno 1] Operation not permitted` is there a way to include my python code in-line within the bash script? – Keyslinger Apr 16 '20 at 18:20
161

Method 1 - Create a shell script:

Suppose you have a python file hello.py Create a file called job.sh that contains

#!/bin/bash
python hello.py

mark it executable using

$ chmod +x job.sh

then run it

$ ./job.sh

Method 2 (BETTER) - Make the python itself run from shell:

Modify your script hello.py and add this as the first line

#!/usr/bin/env python

mark it executable using

$ chmod +x hello.py

then run it

$ ./hello.py
Still.Tony
  • 1,437
  • 12
  • 35
João Víctor
  • 1,731
  • 1
  • 9
  • 4
  • 5
    Please edit your answer to make it more readable. You can use the 101010 button in the answer editor to mark the script contents as code. – thkala Dec 07 '10 at 14:16
  • 1
    I always forget `#!/usr/bin/env python`. Remember to make sure you're referencing the right python version + path for your system! – Still.Tony Aug 12 '14 at 15:05
  • Also make sure the python script works with the system python and doesn't need a virtual environment. – Steven Scott May 24 '23 at 17:24
18

You should be able to invoke it as python scriptname.py e.g.

# !/bin/bash

python /home/user/scriptname.py 

Also make sure the script has permissions to run.

You can make it executable by using chmod u+x scriptname.py.

NAND
  • 663
  • 8
  • 22
Shpongle
  • 983
  • 1
  • 9
  • 14
17

Save the following program as print.py:

#!/usr/bin/python3
print('Hello World')

Then in the terminal type:

chmod +x print.py
./print.py
Mickael Maison
  • 25,067
  • 7
  • 71
  • 68
Nishant Ingle
  • 793
  • 1
  • 8
  • 12
13

Imho, writing

python /path/to/script.py

Is quite wrong, especially in these days. Which python? python2.6? 2.7? 3.0? 3.1? Most of times you need to specify the python version in shebang tag of python file. I encourage to use

#!/usr/bin/env python2 #or python2.6 or python3 or even python3.1
for compatibility.

In such case, is much better to have the script executable and invoke it directly:

#!/bin/bash

/path/to/script.py

This way the version of python you need is only written in one file. Most of system these days are having python2 and python3 in the meantime, and it happens that the symlink python points to python3, while most people expect it pointing to python2.

Enrico Carlesso
  • 6,818
  • 4
  • 34
  • 42
8

This works for me:

  1. Create a new shell file job. So let's say: touch job.sh and add command to run python script (you can even add command line arguments to that python, I usually predefine my command line arguments).

    chmod +x job.sh

  2. Inside job.sh add the following py files, let's say:

    python_file.py argument1 argument2 argument3 >> testpy-output.txt && echo "Done with python_file.py"

    python_file1.py argument1 argument2 argument3 >> testpy-output.txt && echo "Done with python_file1.py"

Output of job.sh should look like this:

Done with python_file.py

Done with python_file1.py

I use this usually when I have to run multiple python files with different arguments, pre defined.

Note: Just a quick heads up on what's going on here:

python_file.py argument1 argument2 argument3 >> testpy-output.txt && echo "completed with python_file.py" . 

  • Here shell script will run the file python_file.py and add multiple command-line arguments at run time to the python file.
  • This does not necessarily means, you have to pass command line arguments as well.
  • You can just use it like: python python_file.py, plain and simple. Next up, the >> will print and store the output of this .py file in the testpy-output.txt file.
  • && is a logical operator that will run only after the above is executed successfully and as an optional echo "completed with python_file.py" will be echoed on to your cli/terminal at run time.
geekidharsh
  • 3,549
  • 1
  • 20
  • 24
4

This works best for me: Add this at the top of the script:

#!c:/Python27/python.exe

(C:\Python27\python.exe is the path to the python.exe on my machine) Then run the script via:

chmod +x script-name.py && script-name.py
peterb
  • 891
  • 8
  • 7
  • Just to clarify, this is Windows-specific. And the prompt that I use is the Git bash. I find it super useful. Especially in the Windows environment – peterb Jul 22 '15 at 04:03
4

I use this and it works fine

#/bin/bash
/usr/bin/python python python_script.py
Max Hay
  • 41
  • 1
2

Since the other posts say everything (and I stumbled upon this post while looking for the following).
Here is a way how to execute a python script from another python script:

Python 2:

execfile("somefile.py", global_vars, local_vars)

Python 3:

with open("somefile.py") as f:
    code = compile(f.read(), "somefile.py", 'exec')
    exec(code, global_vars, local_vars)

and you can supply args by providing some other sys.argv

dCSeven
  • 815
  • 8
  • 18
1

If you have a bash script and you need to run inside of it a python3 script (with external modules), I recommend that you point in your bash script to your python path like this.

#!/usr/bin/env bash

-- bash code --

/usr/bin/python3 your_python.py

-- bash code --
Adelino
  • 2,530
  • 4
  • 20
  • 32
0

Here I have demonstrated an example to run python script within a shell script. For different purposes you may need to read the output from a shell command, execute both python script and shell command within the same file.

To execute a shell command from python use os.system() method. To read output from a shell command use os.popen().

Following is an example which will grep all processes having the text sample_program.py inside of it. Then after collecting the process IDs (using python) it will kill them all.

#!/usr/bin/python3
import os

# listing all matched processes and taking the output into a variable s
s = os.popen("ps aux | grep 'sample_program.py'").read()
s = '\n'.join([l for l in s.split('\n') if "grep" not in l]) # avoiding killing the grep itself
print("To be killed:")
print(s)

# now manipulating this string s and finding the process IDs and killing them
os.system("kill -9 " + ' '.join([x.split()[1] for x in s.split('\n') if x]))

References:

hafiz031
  • 2,236
  • 3
  • 26
  • 48
0

I am not a python developer but I do use it for some tasks. Below is what I use for transforming a timesheet from one format to another. I run it once a month so I want to something that will help me install the right packages if I start over.

#!/bin/bash

if ! which virtualenv
then
   echo virtualenv not installed on this machine
   exit 1
fi

#rm -rf ./venv # uncomment out to start over.

if [[ ! -f ./venv/bin/activate ]]
then
   virtualenv venv
   . ./venv/bin/activate
   pip install openpyxl
   pip install pandas
   pip install numpy
else
   . ./venv/bin/activate
fi

year="2023"
month="04"
lastday="30"
thesrc="Clockify_Time_Report_Detailed_${year}-${month}-01-${year}-${month}-${lastday}.xlsx"
thedst="TimeSheet_${year}-${month}.xlsx"

if [[ ! -f ${thesrc} ]]
then
   echo "${thesrc} does not exist"
   exit 1
fi

if [[ -f ${thedst} ]]
then
   echo "timesheet script already run for ${thedst}"
   exit 1
fi

python ./TransformTimesheet.py "${thesrc}" "${thedst}"
Be Kind To New Users
  • 9,672
  • 13
  • 78
  • 125