Running Shell script from within Python issue - python

So, I am trying to run a Shell script from Python and I double checked that the location of the script.sh is all correct (because when I run it from sublime, the script.sh opens). What I have to call script.sh is:
subprocess.call("script.sh", shell=True)
When I run that, the function returns 0. However, the script is supposed to create a file in my folder and write into it, which it is not doing. It does work when I run the script from cygwin command prompt.
What could be wrong?

Please ensure you have added:
!/bin/bash
as the first line and also make sure that the file script.sh has executable permission.
chmod u+x script.sh
then try specifying the complete path:
subprocess.call("/complete/path/script.sh", shell=True)

At the top of your shell script somewhere, put the line:
pwd >/tmp/mytempfile
and then run the Python script and go look into that file.
This will let you find out the working directory of your scripts which, in the majority of cases where a file doesn't appear to be created, is different to what you think it should be.
You may also want to check the shell script to ensure it's not changing the working directory before creating the file but that would be unlikely given you've stated it works okay from the command line.
If you add the line to create the temporary file and it doesn't actually get created, then your script is not executing.
In that case, you could try a few things. The first is to fully specify the script on the off chance that Python isn't in the correct directory. In other words, something like:
subprocess.call("/actual/path/to/script.sh", shell=True)
Or you could try to run the actual bash executable with the script as an argument:
subprocess.call("bash -c script.sh", shell=True)

Related

Run terminal script in python?

I am using python and I am trying to run a shell script that is located in another folder I am trying
subprocess.call(['source','../Apps/appName/run'])
Where 'run' is a shell script I wrote and made an executable. But it keeps giving errors such as
No such file or directory or **No such file or directory: "source"
I have also tried the following
subprocess.call(['source','../Apps/appName/run'])
subprocess.call(['source ../Apps/appName/run'])
subprocess.call(['.','../Apps/appName/run'])
I am trying to run the script and leave it alone (as in I do not want any return value or to see what the output of the shell script is.
Thank you in advance
source is a shell builtin that reads a file and interprets the commands in the current shell instance. It's similar to C #include or Python import. You should not be using it to run shell scripts.
The correct way to run a script is to add a shebang like #!/bin/bash to the first line, and chmod +x yourscriptfile. The OS will then consider it a real executable, which can be executed robustly from any context. In Python, you would do:
subprocess.call(['../Apps/appName/run'])
If for whichever reason this is not an option, you can instead explicitly invoke bash on the file, since this is similar to what would happen if you're in bash and type source:
subprocess.call(['bash', '../Apps/appName/run'])

Why is the following .sh script saying .py command not found when the script is in PATH?

I am trying to run the Example Workflow in https://rki_bioinformatics.gitlab.io/ditasic/, in which example.sh is the major bash script that will take the example data and output some data matrices.
In the example.sh script which will run the example workflow, we have the following line 9:
ditasic_matrix.py -l 100 -o output/similarity_matrix35.npy data/reference_paths
However, when example.sh is run in the terminal of macOS, the following message arises:
DiTaSic /ditasic_example/example.sh: line 9: ditasic_matrix.py: command not found
But ditasic_matrix.py already exists in the path I have set for the terminal. I have put ditasic_matrix.py in a directory whose path I have added to the PATH of the terminal by
export PATH="$PATH":
So what has happened that leads to the command not found?
Change ditasic_matrix.py line in your script to be ./ditasic_matrix.py because of current path not being included in executable search.
If it still doesn't execute, maybe the file does not have executable bit set.
Open a terminal/console in that folder and issue
chmod +x ditasic_matrix.py
The ditasic_matrix.py file seems to have the following interpreter setting on it: #!/usr/bin/env python. Since you seem to not be able to run it, it seems that this is not your actual path to running Python. Please make sure that:
1) You have Python installed
2) You can execute Python programs by running python in the command line.

Execute bash script from Python on Windows

I am trying to write a python script that will execute a bash script I have on my Windows machine. Up until now I have been using the Cygwin terminal so executing the bash script RunModels.scr has been as easy as ./RunModels.scr. Now I want to be able to utilize subprocess of Python, but because Windows doesn't have the built in functionality to handle bash I'm not sure what to do.
I am trying to emulate ./RunModels.scr < validationInput > validationOutput
I originally wrote this:
os.chdir(atm)
vin = open("validationInput", 'r')
vout = open("validationOutput", 'w')
subprocess.call(['./RunModels.scr'], stdin=vin, stdout=vout, shell=True)
vin.close()
vout.close()
os.chdir(home)
But after spending a while trying to figure out why my access was denied, I realized my issue wasn't the file permissions but the fact that I was trying to execute a bash file on Windows in general. Can someone please explain how to execute a bash script with directed input/output on windows using a python script?
Edit (Follow up Question):
Thanks for the responses, I needed the full path to my bash.exe as the first param. Now however, command line calls from within RunModels.scr come back in the python output as command not found. For example, ls, cp, make. Any suggestions for this?
Follow up #2:
I updated my call to this:
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'], stdin=vin, stdout=vout, cwd='C:\\path\\dir_where_RunModels\\')
The error I now get is /usr/bin/bash: RunModels.scr: No such file or directory.
Using cwd does not seem to have any effect on this error, either way the subprocess is looking in /usr/bin/bash for RunModels.scr.
SELF-ANSWERED
I needed to specify the path to RunModels.scr in the call as well as using cwd.
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'C:\\path\\dir_where_RunModels\\RunModels.scr'], stdin=vin, stdout=vout, cwd='C:\\path\\dir_where_RunModels\\')
But another problem...
Regardless of specifying cwd, the commands executed by RunModels.scr are throwing errors as if RunModels.scr is in the wrong directory. The script executes, but cp and cd throw the error no such file or directory. If I navigate to where RunModels.scr is through the command line and execute it the old fashioned way I don't get these errors.
Python 3.4 and below
Just put bash.exe in first place in your list of subprocess.call arguments. You can remove shell=True, that's not necessary in this case.
subprocess.call(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'],
stdin=vin, stdout=vout,
cwd='C:\\path\\dir_where_RunModels\\')
Depending on how bash is installed (is it in the PATH or not), you might have to use the full path to the bash executable.
Python 3.5 and above
subprocess.call() has been effectively replaced by subprocess.run().
subprocess.run(['C:\\cygwin64\\bin\\bash.exe', '-l', 'RunModels.scr'],
stdin=vin, stdout=vout,
cwd='C:\\path\\dir_where_RunModels\\')
Edit:
With regard to the second question, you might need to add the -l option to the shell invocation to make sure it reads all the restart command files like /etc/profile. I presume these files contain settings for the $PATH in bash.
Edit 2:
Add something like pwd to the beginning of RunModels.scr so you can verify that you are really in the right directory. Check that there is no cd command in the rc-files!
Edit 3:
The error /usr/bin/bash: RunModels.scr: No such file or directory can also be generated if bash cannot find one of the commands that are called in the script. Try adding the -v option to bash to see if that gives more info.
A better solution than the accepted answer is to use the executable keyword argument to specify the path to your shell. Behind the curtain, Python does something like
exec([executable, '-c`, subprocess_arg_string])
So, concretely, in this case,
subprocess.call(
'./RunModels.scr',
stdin=vin, stdout=vout,
shell=True,
executable="C:/cygwin64/bin/bash.exe")
(Windows thankfully lets you use forward slashes instead of backslashes, so you can avoid the requirement to double the backslashes or use a raw string.)

Execute script in Python2 on Unix Command Line

Yes, I know I can do
python2 cal.py
What I am asking for is a way to execute it on the command line such as:
calpy
and then the command afterwards. I put in in a path and when I write cal.py in the command line:
/usr/bin/cal.py: line 5: print: command not found
I don't want to issue cal.py to run my script, I want it to be issued with calpy
I'm running Arch Linux if that helps, thanks. Sorry for my English.
In order for bash to know to run your script via the Python interpreter, you need to put an appropriate shebang at the start. For example:
#!/usr/bin/python
tells bash to run /usr/bin/python with your script as the first argument. I personally prefer
#!/usr/bin/env python
which is compatible with virtualenv. You also need to ensure that the permissions on your script allow it to be executed:
~$ chmod +x path/to/cal.py
Finally, in order to call cal rather than path/to/cal.py, you need to remove the .py extension and make sure that the directory containing cal is in your command search path. I prefer to add ~/bin to the search path by modifying the $PATH environment variable in ~/.bashrc:
export PATH=$HOME/bin:$PATH
then put my own executables in ~/bin. You could also copy (or symlink) cal to one of the system-wide binary directories (/bin or /usr/bin), but I consider it bad practice to mess with system-wide directories unnecessarily.
Ok, you need a couple of things for achive what you want.
First you have to tell your script "How" is going to execute/interpret it. You can do this writting
#/usr/bin/env python
at the very beggining of the file.
The problem you have is the system is trying to execute the script using bash. And in bash there is no print command.
Second you need give execution privileges to your script. And of course if you want to call your script through the command "calcpy", the script has to be called like that.
Put this (exactly this) as the first line of your script:
#!/usr/bin/env python

Permission denied for Python script using Bash?

I am new to Ubuntu... I am trying to run my first simple python program "Hello World" ...
After running following commands in terminal
1. chmod +x filename.py
2. ./filename.py
terminal is showing following error "bash: ./filename.py: Permission denied"
what can I do for solve about problem?
Do you have the appropriate incantation at the top of your python file? e.g.,
#!/usr/bin/python (or alternatively #!/usr/bin/env python)
Just to clarify, chmod +x only makes a file executable, it doesn't run it.
And I'm assuming your script looks like nothing more complex than this:
#!/usr/bin/env python
print 'hello world'
Some possibilities:
What does it say if you type umask? chmod +x will only make a file executable for you if your umask doesn't block the user executable bit. A typical umask such as 0022 will not block the user execute bit, but a umask like 0122 can. (See the Description section of chmod(1) for more info.)
To execute a script such as a Python script, you also need read permission. Try chmod u+rx filename.py and execute the script again.
It's also remotely possible that whatever interpreter you've specified in the file with the "hashbang" line at the beginning of your file (e.g. #!/usr/bin/env python) isn't executable, although that in my experience yields a different error message.
I deal with the same problem on my new system.
It is the third time I tried to solve this, and your post is the first one appearing on google results. My post is late, but think that it will help another users with the same problem.
In my case, it was about partition table setup.
Check in your /etc/mtab file how python script is being stored. Check if there is a clause: noexec
noexec is a flag that forbid executing under the partition. By default, it is set with exec. But, sometimes, this kind of things happen.
Now, it is working fine here.

Categories