subprocess.call() for shell program which write a file - python

I need to execute a shell script using python. Output of shell program is a text file. No inputs to the script. Help me to resolve this.
def invokescript( shfile ):
s=subprocess.Popen(["./Script1.sh"],stderr=subprocess.PIPE,stdin=subprocess.PIPE);
return;
invokescript("Script1.sh");
On using above code., I receive the following error.
Traceback (most recent call last):
File "./test4.py", line 12, in <module>
invokescript("Script1.sh");
File "./test4.py", line 8, in invokescript
s=subprocess.Popen(["./Script1.sh"],stderr=subprocess.PIPE,stdin=subprocess.PIPE);
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 8] Exec format error
Thanks in advance...

Try this:
import shlex
def invokescript(shfile):
return subprocess.Popen(
shlex.split(shfile),
stderr=subprocess.PIPE,
stdin=subprocess.PIPE
)
invokescript("Script1.sh");
And add #!/usr/bin/env bash to your bash file of course.

I used os.system() to call shell script. This do what i expected. Make sure that you have imported os module in your python code.
invokescript( "Script1.sh" ) // Calling Function
function invokescript( shfile ): // Function Defenition
os.system("/root/Saranya/Script1.sh")
return;
following is also executable:
invokescript( "Script1.sh" ) // Calling Function
function invokescript( shfile ): // Function Defenition
os.system(shfile)
return;
Thanks for your immediate response guys.

Related

Subprocess function python: Use in automation

I am trying to run this command in the terminal using Python:
./Pascal --set=settings/1_settings.txt --runpathway=on
--genescoring=sum --pval=1_snp_values.txt.gz
I need to run this script 180 times using a different pval everytime. Hence, automating it via Python saves me a lot of time.
Currently I have a Python subprocess like this:
subprocess.call("./Pascal --set=settings/1_settings.txt
--runpathway=on --genescoring=sum --pval=1_snp_values.txt.gz")
Although, I am getting this error:
Traceback (most recent call last):
File "test_automation.py", line 4, in <module>
subprocess.call("./Pascal --set=settings/1_settings.txt --runpathway=on --genescoring=sum --pval=1_snp_values.txt.gz")
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
The problem is when I execute the exact same command in terminal (outside of the Python code) it works fine. Am I using the syntax incorrectly?
Using os.system...
You could try using this to run your terminal command like so:
import os
os.system("./Pascal --set=settings/1_settings.txt --runpathway=on --genescoring=sum --pval=1_snp_values.txt.gz")
And if this works, it is simple to execute in a for-loop to get it to run 180 times:
import os
for _ in range(180):
os.system("./Pascal --set=settings/1_settings.txt --runpathway=on --genescoring=sum --pval=1_snp_values.txt.gz")
Additionally, if Pascal is in the same directory that you are running your script then the path of ./ is not necessary as by default, it will search the current working directory. So you can change it to just Pascal --set-settings...
Using subprocess.call...
Personally, I think using os.system is a cleaner solution, however you can use subprocess.call to do the same thing in one of two ways, either:
call Pascal and the other arguments separately from a list like:
import subprocess as s
s.call(['./Pascal', '--set=settings/1_settings.txt', '--runpathway=on', '--genescoring=sum', '--pval=1_snp_values.txt.gz'])
or just set shell to true and pass in the full line as a string like:
import subprocess as s
s.call('./Pascal --set=settings/1_settings.txt --runpathway=on --genescoring=sum --pval=1_snp_values.txt.gz', shell=True)
Hope this works for you!

Execute externall compiled program in Python

I would like to execute an external compiled program in Python. In shell,
./bin/myProgram ./dir1/arg1 ./dir/arg2 arg3 arg3 arg4
And my Python script looks like:
import subprocess
subprocess.call(["./Users/Solar/Desktop/parent/child1/child2/bin/myProgram",
"/Users/Solar/Desktop/parent/child1/child2/dir1/arg1",
"/Users/Solar/Desktop/parent/child1/child2/dir1/arg2",
"arg3", "arg4", "arg5"])
But I get this error:
Traceback (most recent call last):
File "/Users/Solar/Desktop/test.py", line 5, in <module>
"32", "0.06", "15"])
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 522, in call
return Popen(*popenargs, **kwargs).wait()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1335, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Process finished with exit code 1
Could you help me? Thank you in advance!!
It's solved, I just had to execute
subprocess.call(["/Users/Solar/Desktop/parent/child1/child2/bin/myProgram",
"/Users/Solar/Desktop/parent/child1/child2/dir1/arg1",
...
Instead of
subprocess.call(["./Users/Solar/Desktop/parent/child1/child2/bin/myProgram",
"/Users/Solar/Desktop/parent/child1/child2/dir1/arg1",
...
Thank you people!!
when subprocess.Popen issues
OSError: [Errno 2] No such file or directory
that's only because the executable cannot be found (if one of the file-arguments was not found it's the sub-process which reports the error, and no exception is thrown)
In your case ./Users/... is not likely to be valid considering that /Users/ is valid (root against current dir) so that's your problem.
"./Users/Solar/Desktop/parent/child1/child2/bin/myProgram" should be "/Users/Solar/Desktop/parent/child1/child2/bin/myProgram"
Note: better coding could have avoided the error:
import subprocess
root = "/Users/Solar/Desktop/parent/child1/child2"
subprocess.call([os.path.join(root,"bin/myProgram"),
os.path.join(root,"dir1/arg1"),
os.path.join(root,"dir1/arg2"),
"arg3", "arg4", "arg5"])

Subprocess in Python: File Name too long

I try to call a shellscript via the subprocess module in Python 2.6.
import subprocess
shellFile = open("linksNetCdf.txt", "r")
for row in shellFile:
subprocess.call([str(row)])
My filenames have a length ranging between 400 and 430 characters.
When calling the script I get the error:
File "/usr/lib64/python2.6/subprocess.py", line 444, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.6/subprocess.py", line 595, in __init__
errread, errwrite)
File "/usr/lib64/python2.6/subprocess.py", line 1106, in _execute_child
raise child_exception
OSError: [Errno 36] File name too long
An example of the lines within linksNetCdf.txt is
./ShellScript 'Title' 'Sometehing else' 'InfoInfo' 'MoreInformation' inputfiile outputfile.txt 3 2
Any ideas how to still run the script?
subprocess.call can take the command to run in two ways - either a single string like you'd type into a shell, or a list of the executable name followed by the arguments.
You want the first, but were using the second
import subprocess
shellFile = open("linksNetCdf.txt", "r")
for row in shellFile:
subprocess.call(row, shell=True)
By converting your row into a list containing a single string, you're saying something like "Run the command named echo these were supposed to be arguments with no arguments"
You need to tell subprocess to execute the line as full command including arguments, not just one program.
This is done by passing shell=True to call
import subprocess
cmd = "ls " + "/tmp/ " * 30
subprocess.call(cmd, shell=True)

Answering the terminal questions from a GUI window

I want to run terminal commands within a python file. It is working fine and I can also get the terminal messages on a gui window using subprocess.Popen.
import subprocess
import wx
import os
def main():
p = subprocess.Popen(['ls'], stdout = subprocess.PIPE)
text = p.stdout.readlines()
text = "".join(text)
wx.MessageBox("file names:\n%s" % text, "info")
if __name__ == '__main__':
app = wx.PySimpleApp()
main()
But when I run a command for which terminal should ask answers of some questions, I am getting error?
Traceback (most recent call last):
File "to_make_new_project_folder.py", line 19, in <module> main()
File "to_make_new_project_folder.py", line 10, in main p = subprocess.Popen(['gr_modtool add -t general square_ff'], stdout = subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 711, in init errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child raise child_exception
OSError: [Errno 2] No such file or directory
Does someone have idea how to answer the question from terminal using a gui window?
You should try passing in stdin=PIPE as well to popen
Based on your stack trace, the error you're receiving is OSError: No such file or directory, coming up from subprocess. It looks to me like Popen can't find the file that you're trying to execute, and is therefore failing.

NamedTemporaryFile cannot be acessed from command line

I have the following (simplified) code:
with NamedTemporaryFile() as f:
f.write(zip_data)
f.flush()
subprocess.call("/usr/bin/7z x %s" % f.name)
It dies with the following error:
Traceback (most recent call last):
File "decrypt_resource.py", line 70, in <module>
unpack(sys.argv[2])
File "decrypt_resource.py", line 28, in unpack
print(subprocess.check_output(cmd))
File "/usr/lib/python2.7/subprocess.py", line 568, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
However, if I use NamedTemporaryFile(delete=False) and then print & execute the command, it works. What's wrong here?
My System is an ArchLinux with a 3.9.5-1-ARCH kernel.
You are using subprocess.call() incorrectly.
Pass in a list of arguments:
subprocess.call(["/usr/bin/7z", "x", f.name])
The argument is not handled by a shell and is not parsed out like a shell would do. This is a good thing as it prevents a security problem with untrusted command line arguments.
Your other options include using shlex.split() to do the whitespace splitting for you, or, as a last resort, telling subprocess to use a shell for your command with the shell=True flag. See the big warning on the subprocess documentation about enabling the shell.

Categories

Resources