I have a python script that takes in a .txt file and outputs a .txt file. I want to create a bash file that I can click on from my desktop to execute the python script.
So far I have:
#!/bin/bash
cd /Desktop;
cd ./py-data;
python ./grab.py;
exit;
This just opens up the python script. Ideally I would like to click on the bash script and have the python script to run in the back ground and just produce the output without having to open the python script.
Solution:
change py.bat to py.command
at terminal:
$ cd ~/Desktop
$ chmod 755 py.command
open code on vim and place in (from: ./configure : /bin/sh^M : bad interpreter):
:set fileformat=unix
Changed code too:
#!bin/bash
cd ~/Desktop
python search.py
exit;
On MacOS, set the name of your script file to end in .command, and make the file executable. With that filename extension, you can double-click the file, and it will run Terminal application and any output (to stdout / stderr) will be displayed in the terminal window which pops up for execution.
=== /Users/john/Desktop/foo.command ===
#!/bin/bash
echo 'hello'
Then:
=== At command prompt===
$ cd ~/Desktop
$ chmod 755 foo.command
Double click on foo.command and you'll see window popup:
Last login: Thu Oct 5
/Users/john/Desktop/foo.command ; exit;
iMac:~/Desktop john$ /Users/john/Desktop/foo.command ; exit;
hello
logout
[Process completed]
In the popup window, you'll see lots of lines, plus your output ("hello").
In your particular example, I think you have two problems:
First, you mention /Desktop, which probably isn't what you want, as the user's Desktop is ~/Desktop. This would cause your script to fail.
Second, the output you would see in the popup window is the output your script writes directly to standard out. If you script is writing to another file, it may be working great, but you'll not see that information displayed in the popup (it will be in whatever file you wrote it to.) So it depends what your grab.py file actually does.
Finally, you say "run in the background". Technically, that's not what's happening, as it will run in a separate foreground process. I assume that's what you mean.
You could try chmod 777 on your bash script and then removing the extension. If you are on macOS then it should work. Not so sure about Linux, but it's worth a try.
chmod +x *filename*
Execute the above command in the terminal then make the bash file as follows
cd Desktop/*folder*/
python3 *filename.py*
Related
Try to create a Windows .bat file to achieve the below function:
cd C:\repo\demo
venv\Scripts\activate
python test.py
In Visual Studio Code terminal window, I can run the above lines without issue.
Created a .bat file as below:
cd C:\repo\demo
"C:\Users\jw\AppData\Local\Programs\Python\Python310\python.exe" "venv\Scripts\activate"
"C:\Users\jw\AppData\Local\Programs\Python\Python310\python.exe" "python test.py"
pause
When double click the above .bat file to run it, end with error:
if [ "${BASH_SOURCE-}" = "$0" ]; then
SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?
Also tried the below .bat code, not working either:
cd C:\repo\demo
venv\Scripts\activate
python test.py
pause
How to correct the .bat file to make it work?
======================================
Based on #Compo's comment, tried the below version and it successfully executed python test.py:
cd C:\repo\demo
call "venv\Scripts\activate.bat"
python test.py
pause
but seems it didn't finish call "venv\Scripts\activate.bat", the command line window shows as below:
When manually run the code, it will prefix the path with (venv) as below which shows the proper result:
============================================
UPDATE:
The below .bat version works now, an answer from this question
cd C:\repo\demo && call "venv\Scripts\activate.bat" && python test.py && pause
You should either remove "C:\...\python.exe" from the second line:
cd C:\repo\demo
"C:\Users\jw\AppData\Local\Programs\Python\Python310\python.exe" "venv\Scripts\activate"
python heatmap.py <-- like this
pause
or remove python
cd C:\repo\demo
"C:\Users\jw\AppData\Local\Programs\Python\Python310\python.exe" "venv\Scripts\activate"
"C:\Users\jw\AppData\Local\Programs\Python\Python310\python.exe" "heatmap.py"
pause
Try this:
cd c:\python
python scripts/test.py <-- here, you can replace "test" with the name of the Python program(script) you want to execute you
I need to click in a button to call a python function (i did this), but now :
I need a python script to open a new cmd, and in the opened cmd i want to do 2 commands :
Cd and run a python file
This code is the best thing i could do but it's not running the script !
import os
username = os.getlogin()
os.system('start cmd /k ; cd C:\\Users\\' + username + '\\Desktop\\Automatisation & python serverSender.py')
To resume :
Start cmd /k (Open new cmd and remain)
cd C:\Users\' + username + '\Desktop\Automatisation (To change directory)
python serverSender.py (To run the python script inside Automatisation directory)
But the last command : python serverSender.py is not executing ! As you can see in the screen, the function opens a new cmd when i click on the button , it's goes to the directory in the cd command, but it's not starting the serverSender.py file !
Cmd Opened
Any idea on how to run the third command ? (i don't want to run it in another cmd, i want to run it in the opened cmd with the first command )
Thanks !
The & is interpreted by the outer shell and not the one inside start. You need to escape it, by changing & to ^&:
os.system('start cmd /k ; cd C:\\Users\\' + username + '\\Desktop\\Automatisation ^& python serverSender.py')
Having tried to check into this, I don't think it is a python issue.
I tried doing this, from a command line, for comparison:
start cmd /k cd .. & cd ..
It did not work. Only the first "cd .." got executed.
So it seems "&" is not a successful way to chain commands with "cmd /k". I checked && and that did not work either.
After further looking into it, there is one suggested workaround I found at the below link, which involves using a single line to temporarily write a script and execute that script. (though I did not try it)
https://superuser.com/questions/62850/execute-multiple-commands-with-1-line-in-windows-commandline
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 need a .command file that can launch a python script in the same directory as it.
I have so far gotten this:
#!bin/bash
python /Users/username/Desktop/IF.py
But every time the Terminal returns the same error.
Last login: Sun Oct 11 01:48:38 on ttys000
MacBook-Pro:~ username$ /var/folders/m7/yf7p3vdj2mx0l9r7qb68rttc0000gn/T/Cleanup\ At\ Startup/run 466235498.368.command.command ; exit;
/var/folders/m7/yf7p3vdj2mx0l9r7qb68rttc0000gn/T/Cleanup At Startup/run-466235498.368.command.command: line 3: bin/bash: No such file or directory
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
Please note the error is on line 3 of the 2 lines of code I have...
Maybe because the shebang (or hashbang). About what is shebang (wiki).
#!bin/bash
^
python /Users/username/Desktop/IF.py
This means the system will use bin/bash to run this program, but bin/bash means path/bin/bash.
For example, if you're in /home then the system will use /home/bin/bash to run this program.
I think you need this:
#!/bin/bash
python /Users/username/Desktop/IF.py
Note that I replaced #!bin/bash to #!/bin/bash.
Why not just launch the python script itself from the get-go? You can add a shebang at the top like so:
#! /user/bin/env python
... the rest of your python script here
Then just give the script executable permissions:
chmod +x nameofscript.py
Then just launch it like so:
./nameofscript.py
In case you don't want the script to rely on the environment, just use the following shebang instead:
#! /usr/bin/python
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?
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
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
Save the following program as print.py:
#!/usr/bin/python3
print('Hello World')
Then in the terminal type:
chmod +x print.py
./print.py
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.
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.
This works for me:
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
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.
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
I use this and it works fine
#/bin/bash
/usr/bin/python python python_script.py
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
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:
Execute a python program from within a shell script
Assign output of os.system to a variable and prevent it from being displayed on the screen
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 --