Execute a subprocess that takes an input file and write the output to a file - python-3.x

I am using a third-party C++ program to generate intermediate results for the python program that I am working on. The terminal command that I use looks like follows, and it works fine.
./ukb/src/ukb_wsd --ppr_w2w -K ukb/scripts/wn30g.bin -D ukb/scripts/wn30_dict.txt ../data/glass_ukb_input2.txt > ../data/glass_ukb_output2w2.txt
If I break it down into smaller pieces:
./ukb/src/ukb_wsd - executable program
--ppr_w2w - one of the options/switches
-K ukb/scripts/wn30g.bin - parameter K indicates that the next item is a file (network file)
-D ukb/scripts/wn30_dict.txt - parameter D indicate that the next item is a file (dictionary file)
../data/glass_ukb_input2.txt - input file
> - shell command to write the output to a file
../data/glass_ukb_output2w2.txt - output file
The above works fine for one instance. I am trying to do this for around 70000 items (input files). So found a way by using the subprocess module in Python. The body of the python function that I created looks like this.
with open('../data/glass_ukb_input2.txt', 'r') as input, open('../data/glass_ukb_output2w2w_subproc.txt', 'w') as output:
subprocess.run(['./ukb/src/ukb_wsd', '--ppr_w2w', '-K', 'ukb/scripts/wn30g.bin', '-D', 'ukb/scripts/wn30_dict.txt'],
stdin=input,
stdout=output)
This error is no longer there
When I execute the function, it gives an error as follows:
...
STDOUT = subprocess.STDOUT
AttributeError: module 'subprocess' has no attribute 'STDOUT'
Can anyone shed some light about solving this problem.
EDIT
The error was due to a file named subprocess.py in the source dir which masked Python's subprocess file. Once it was removed no error.
But the program could not identify the input file given in stdin. I am thinking it has to do with having 3 input files. Is there a way to provide more than one input file?
EDIT 2
This problem is now solved with the current approach:
subprocess.run('./ukb/src/ukb_wsd --ppr_w2w -K ukb/scripts/wn30g.bin -D ukb/scripts/wn30_dict.txt ../data/glass_ukb_input2.txt > ../data/glass_ukb_output2w2w_subproc.txt',shell=True)

Related

String method tutorial in abinit - no output file produced

I'm trying to follow this tutorial in abinit: https://docs.abinit.org/tutorial/paral_images/
When trying to run abinit for any of the tstring files, no output file is produced. For instance, I copy the files tstring_01.in and tstring.files into the subdirectory work_paral_string, edit the tstring.files with the appropriate file names, and run the command mpirun -n 20 abinit < tstring.files > log 2> err. No error message is shown but also no output is produced. (The expected output file would be tstring_01.out.)
Any suggestions?

finding a file using general location in a python script

I making a script in python3. this script takes an input file. depends on who is running the script every time the location of this input file is different but always would be in the same directory as the script is. so I want to give the location of the input file to the script but basically the script should find it. my input file always would have the same name (infile.txt). to do so, I am using this way in python3:
path = os.path.join(os.getcwd())
input = path/infile.txt
but it does not return anything. do you know how to fix it?
os.getcwd() return the working directory which can be different to the directory where the script is. The working directory corresponds from where python is executed.
In order to know where is the scipt you should use
`
import os
input = os.path.join(os.path.dirname(os.path.realpath(__file__)), infile.txt)
# and you should use os.path.join
`
If i understand your question properly;
You have python script (sample.py) and a input file (sample_input_file.txt) in a directory say; D:\stackoverflow\sample.y and D:\stackoverflow\sample_input_file.txt respectively.
import os
stackoverflow_dir = os.getcwd()
sample_txt_file_path = os.path.join(stackoverflow_dir, 'sample_input_file.txt')
print(sample_txt_file_path)
os.path.join() takes *args as second argument which must have been your file path to join.

os.system(cmd) call fails with redirection operator

My Python 3.7.1 script generates a fasta file called
pRNA.sites.fasta
Within the same script, I call following system command:
cmd = "weblogo -A DNA < pRNA.sites.fasta > OUT.eps"
os.system(cmd)
print(cmd) #for debugging
I am getting the following error message and debugging message on the command line.
Error: Please provide a multiple sequence alignment
weblogo -A DNA < pRNA.sites.fasta > OUT.eps
"OUT.eps" file is generated but it's emtpy. On the other hand, if I run the following 'weblogo' command from the command line, It works just find. I get proper OUT.eps file.
$ weblogo -A DNA<pRNA.sites.fasta>OUT.eps
I am guessing my syntax for os.system call is wrong. Can you tell me what is wrong with it? Thanks.
Never mind. It turned out to be that I was not closing my file, "pRNA.sites.fasta" before I make system call that uses this file.

how to protect C file from entering into infinite-loop in ubunto

Im currently writing a python3 script that checks out a C source file by running the C code with various of input files. the compilation is done by GCC if it matters.
in some case, the C code enters into an infinite loop (I figured it out because I ran out of memory).
is there a way that I can "protect" my code like a watchdog or something that
tells me a after X minutes that I ran into an infinite loop?
I cant assume anything about the input so i cant have answers like change it or something...
#runfile is an exe file, code file is .c file, inputlist/outputlist are directories
import subprocess as sbp
import os
sbp.call('gcc -o {0} {1}'.format(runfile,codefile), shell = True)
for i in range(numoFiles):
#run the file with input i and save it to output i in outdir
os.system("./{0} <{1} >{2}".format(ID,inputList[i],outputList[i]))
Look up the "Halting Problem". It is not possible to determine whether an arbitrary program will eventually finish or if it will be stuck in a loop forever.
I figured out a way to avoid enter infinite loop by this method:
import subprocess
for i in range(numofiles):
cmd="gcc -o {0} {1}".format(runfile,codefile)
subprocess.call(cmd, shell = True)
try:
cmd="./{0} <{1} >'/dev/null'".format(Cfile,inputfile) #check if runtime>100 sec
subprocess.run(cmd,shell=True,timeout=100)
except subprocess.TimeoutExpired:
print("infinite loop")
continue
cmd="./{0} <{1} >{2}".format(Cfile,inputfile,outputfile)
subprocess.run(cmd,shell=True) #print output to txt file

Why is stdout printing out an empty string in this case?

I am reading about subprocess and playing around with some code.
I'm using Windows 7 with Python3.6
import subprocess
process = subprocess.Popen(['notepad', 'C:\\Users\Amit\Downloads\InsiderTrades.txt'],stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#I'm opening a text file which has a list of stock tickers
stdout1, stderr1 = process.communicate()
print(stdout1.decode('ASCII'))
The output I'm getting is nothing or
b'' as the value for stdout1.
I"m not quite sure what communicate is outputting in this case.
I was under the impression that it would output the text from my text file or it would output anything I type into the text file.
I tried typing into the newly opened text file as well, but I'm still getting the same output , b''
So what am I getting an empty string, despite typing something into the newly opened textfile.
Subprocess is basically as if you run that command in the terminal.
So what you are doing is running
notepad some_file.txt
which just opens a file in notepad, but it doesn't send anything to standard output.
If you run a command that writes something to standard output, then you will have a non-empty stdout1. Try ls for example if you are on a *nix system or dir if on Windows.

Resources